使用 Spring Boot 实现 2 路 SSL

2024-02-04

我正在创建一些宁静的 Web 服务,并使用 Spring-Boot 创建嵌入式 tomcat 容器。

要求之一是实现 2 路 SSL。我一直在查看 HttpSecurity 对象,并且可以使用以下方法让它仅通过 SSL 通道运行 Web 服务:-

@Override
protected void configure(HttpSecurity http) throws Exception {

    System.out.println("CONFIGURED");

    http
        // ...
        .requiresChannel()
            .anyRequest().requiresSecure();
}

我似乎找不到一种使网络服务只能由提供有效客户端证书的应用程序访问的方法。

我只有 SSL 的基本知识,因此即使是正确方向的一般指示也将不胜感激。

正在部署的服务器将具有多种应用程序 - 这是唯一需要使用 2 路 SSL 锁定的服务器。我真正寻找的是一种锁定单个应用程序以仅接受客户端证书的方法。


我遇到了类似的问题,并认为我应该分享我带来的解决方案。

首先,您需要了解 SSL 证书身份验证将在您的 Web 服务器端处理(参见 dur 的解释,使用“clientAuth=want”设置)。 然后,必须配置您的 Web 应用程序才能处理提供的(和允许的)证书,将其映射到用户等。

我与您的细微差别是,我将 spring boot 应用程序打包到 WAR 存档中,然后将其部署在现有的 Tomcat 应用程序服务器上。

我的 Tomcat 的 server.xml 配置文件定义了一个 HTTPS 连接器,如下所示:

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
    maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
    keystoreFile="/opt/tomcat/conf/key-stores/ssl-keystore.jks"
    keystorePass=“some-complex-password“
    clientAuth="want" sslProtocol="TLS"
    truststoreFile="/opt/tomcat/conf/trust-stores/ssl-truststore.jks"
    truststorePass=“some-other-complex-password” />

避免任何混淆的小注释:keystoreFile 包含用于 SSL 的证书/私钥对(仅),而 truststoreFile 包含用于客户端 SSL 身份验证的允许的 CA 证书(请注意,您也可以将客户端证书直接添加到该信任存储中) 。

如果您在 Spring Boot 应用程序中使用嵌入式 tomcat 容器,则应该能够使用以下属性键/值在应用程序的属性文件中配置这些设置:

server.ssl.key-store=/opt/tomcat/conf/key-stores/ssl-keystore.jks
server.ssl.key-store-password=some-complex-password
server.ssl.trust-store=/opt/tomcat/conf/trust-stores/ssl-truststore.jks
server.ssl.trust-store-password=some-other-complex-password
server.ssl.client-auth=want

然后,在我的 Web 应用程序上,我声明特定的 SSL 配置,如下所示:

@Configuration
@EnableWebSecurity
//In order to use @PreAuthorise() annotations later on...
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SSLAuthConfiguration extends WebSecurityConfigurerAdapter {

    @Value("${allowed.user}")
    private String ALLOWED_USER;

    @Value("${server.ssl.client.regex}")
    private String CN_REGEX;

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure (final HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
                .authorizeRequests()
                .antMatchers("/url-path-to-protect").authenticated() //Specify the URL path(s) requiring authentication...
            .and()
                .x509() //... and that x509 authentication is enabled
                    .subjectPrincipalRegex(CN_REGEX)
                    .userDetailsService(userDetailsService);
    }

    @Autowired
    //Simplified case, where the application has only one user...
    public void configureGlobal (final AuthenticationManagerBuilder auth) throws Exception {
        //... whose username is defined in the application's properties.
        auth
            .inMemoryAuthentication()
                .withUser(ALLOWED_USER).password("").roles("SSL_USER");
    }

}

然后我需要声明 UserDetailsS​​ervice bean(例如在我的应用程序的主类中):

@Value("${allowed.user}")
private String ALLOWED_USER;

@Bean
public UserDetailsService userDetailsService () {

    return new UserDetailsService() {

        @Override
        public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException {
            if (username.equals(ALLOWED_USER)) {
                final User user = new User(username, "", AuthorityUtils.createAuthorityList("ROLE_SSL_USER"));
                return user;
            }
            return null;
        }
    };
}

就是这样!然后,我可以将 @PreAuthorize(“hasRole(‘ROLE_SSL_USER’)”) 注释添加到我想要保护的方法中。

总结一下,身份验证流程如下:

  1. 用户提供SSL证书;
  2. Tomcat 根据其信任库进行验证;
  3. 自定义 WebSecurityConfigurerAdapter 从证书的 CN 检索“用户名”;
  4. 应用程序对与检索到的用户名关联的用户进行身份验证;
  5. 在方法级别,如果使用 @PreAuthorize("hasRole('SSL_USER')") 进行注释,应用程序将检查用户是否具有所需的角色。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Spring Boot 实现 2 路 SSL 的相关文章

  • 构建 jar 后无法运行 exe

    我制作了一个简单的实用应用程序 其中我有一个要运行的exe文件 我通过使用它来运行 Runtime getRuntime exec this getClass getResource filename exe getPath 当我从 ide
  • 是否值得清理 Filter 中的 ThreadLocals 来解决线程池相关问题?

    简而言之 tomcat 使用线程池 因此线程被重用 一些图书馆使用ThreadLocal变量 但不要清理它们 使用 remove 所以实际上它们将 脏 线程返回到池中 Tomcat 具有在关闭时检测这些事情并清理线程局部变量的新功能 但这意
  • Android 中的 ImageView 拖动限制

    我在布局中有一个 ImageView 并在 ImageView 上设置 OnTouchListener 来拖动 ImageView 它工作得很好 我的问题是如何防止将 ImageView 移动到布局范围之外 这是我的代码 活动类别 publ
  • JAXB、Marshal 的问题 - 无法封送类型“java.lang.String”

    当我运行 marshal 操作时 出现以下错误 javax xml bind MarshalException with linked exception com sun istack internal SAXException2 unab
  • java IO将一个文件复制到另一个文件

    我有两个 Java io File 对象 file1 和 file2 我想将 file1 的内容复制到 file2 有没有一种标准方法可以做到这一点 而无需我创建一个读取 file1 并写入 file2 的方法 不 没有内置方法可以做到这一
  • Netflix Archaius 动态配置

    我正在将 Hystrix 集成到现有项目中 并且希望从 xml 文件中读取配置值 而不是使用配置管理器提供配置属性 当 xml 文件中的值更新时 我希望 Hystrix 配置在运行时更新 这是我遵循的指南 https github com
  • WebView ssl 错误

    对不起我的英语不好 我需要加载 url https 我有一些问题 当我尝试加载页面时 webView 给我错误 primary error 3 certificate Issued to CN my site com Issued by C
  • Java 中的逻辑回归

    我们需要用 Java 进行逻辑回归 我们在 Python 中使用了这段代码http blog smellthedata com 2009 06 python logistic regression with l2 html http blo
  • 将 JAR 文件打包为 WAR 文件

    我有一系列依赖的Java项目 我想将它们打包成一个 JAR 文件 以便在我的 WAR 文件中使用 这些项目依赖于大量的外部库和项目 如log4j apache commons等 我选择 Eclipse 中的所有项目并导出为 JAR 文件 然
  • 与 Java 中的同步块相比,新的 Lock 接口有什么优势?

    与 Java 中的同步块相比 新的 Lock 接口有什么优势 您需要实现一个高性能缓存 允许多个读取器但单个写入器保持完整性 您将如何实现它 锁的优点是 让他们公平是可能的 可以使线程在等待 Lock 对象时响应中断 可以尝试获取锁 但如果
  • 带有 CONTAINS 查询的PreparedStatement

    我有一个查询需要连续运行 28000 次 所以我认为使用准备好的语句可能是一个聪明的主意 这是我的查询 String requestWithFirstName SELECT SE ELEMENT ID SE LASTNAME SE FIRS
  • 定时器启动/停止参数

    自从加入这个社区以来 我在技能和进步方面取得了突飞猛进的进步 你们都是一个巨大的帮助 我无法提供一个计时器 该计时器已在启动和停止时实现了某些参数 我要么收到错误消息 局部变量计时器可能尚未初始化 要么没有收到错误消息 但什么也没有发生 也
  • 使用服务器 java api 从 jasperserver 存储库检索资源

    我正在尝试使用其 java API 从 Jasperserver 存储库检索资源 根据jasper 报表服务器终极指南 https community jaspersoft com documentation jasperreports s
  • java:验证 GUI 中的所有文本字段是否已完成

    我正在尝试创建一个允许某人设置帐户的 GUI 我想验证按下创建帐户按钮时所有文本字段是否完整 做这个的最好方式是什么 我正在附加我的代码 但我对文本字段是否完整的验证不起作用 参见下面的代码 public class GUIaccounts
  • jstack 是否停止在较新的 JDK8 版本上工作?

    我惊讶地发现 不知何故 最近 jstack 停止了在较新的 JDK 8 上的工作 我不确定这发生在哪个版本 但我确实得到 36649 Unable to open socket file target process not respond
  • Java 统一编码

    A Java char is 2 bytes http java sun com docs books tutorial java nutsandbolts datatypes html 最大大小为 65 536 但有95 221 http
  • 运行 JAR 时“JCE 无法验证提供者 BC”

    在我的 scala 项目中我使用 org bouncycastle bcprov jdk14 1 51 用于密码学 如果它在 Scala IDE 中测试我的项目 它工作得很好 但是一旦我制作了一个 JAR 并尝试通过以下方式运行它java
  • 有没有办法在 Spring Boot 应用程序配置中使用 Spring Cloud {cipher} ?

    我有一个使用 Spring Cloud Config 的 Spring Boot 应用程序 但我想在 Spring Boot 应用程序 bootstrap yml 文件中加密 Spring Cloud Config 密码 有没有办法做到这一
  • tomcat 7 + ssl 不工作 - ERR_SSL_VERSION_OR_CIPHER_MISMATCH

    Ubuntu 14 tomcat 7 java 7 our crt our key 和 gd bundle g2 g1 crt 由 godaddy 提供 该捆绑包中有 3 个证书 通过查看文件可以看出 请注意 我们的密钥和 crt 在 no
  • ByteBuddy 变基、合成类型和 OSGi

    我为 byte buddy 开发了以下拦截器 public class SecurityInterceptor RuntimeType public static Object intercept SuperCall Callable su

随机推荐

  • Azure API应用程序的IP地址以及如何限制IP

    我已经部署了用 Java Servlet 编写的 API 应用程序 我想知道的是 我的 API 应用程序的 IP 地址以及仅允许来自一两个 IP 地址的请求的方式 这意味着我想限制除这些 IP 之外的所有 IP 似乎一旦我在一个地区部署多个
  • Eclipse 上的自动代码完成

    我希望 Eclipse 在我编写一些变量 类名称或关键字时自动向我建议所有可能的选项 就像在 Flash Develop 或 Visual Studio 中一样 是否可以 如果没有 我可以使用哪个 Java IDE 获得这个 I m spe
  • SQL 和唯一的 n 列组合

    Oracle 有没有一种简单的方法来查询 n 个字段的唯一组合 我有非常简单的两场解决方案 CREATE TABLE combinations AS SELECT 1 AS n FROM DUAL UNION ALL SELECT 2 FR
  • 如何使用 ng-style 设置 li:before 的 css

    我想用可变范围 宽度 更改 li before 的宽度值 ul li span step stepName uppercase span li ul 我正在执行这段代码 但它不起作用 请帮助 不幸的是你不能拥有pseudoelements
  • 启用基于客户位置的付款方式

    我不知道是否可能 但是 我们需要为巴塞罗那添加一些不同的付款方式 因此 我们的想法是 如果客户居住在巴塞罗那地区 加泰罗尼亚 他将看到与西班牙其他地区不同的信用卡付款方式和银行转账账户 WooCommerce 可以做到这一点吗 Thanks
  • Codeigniter - 从 where_in 中删除单引号

    我有两个疑问 genres this gt db gt select Group Concat intGenreId strDJGenres gt from tblDJGenres gt where intDJId this gt sess
  • 使用 rustdoc 生成 markdown 文档?

    有没有办法在 doc 中生成单个 markdown 文件 评论 多个 Markdown 文件 doc main md doc foo md等 也很好 我是 Rust 新手 虽然生成的 HTML 文档很好 但我主要生活在命令行上 真的不想为了
  • .setValue() 不能始终适用于 Google Sheets 脚本

    我一直在努力处理我在 Google Sheet 中编写的一段脚本 该脚本的目的是监视给定单元格的输入值 来自键盘 并验证输入是否遵循数据输入标准 例如 所有输入值必须遵循标准XX XX X 举个例子 A5 03 1是可以接受的 而B555
  • Swift:反映 NSManagedObject 子类的属性

    当使用 Mirror 访问 NSManagedObject 子类的内部结构时 所有托管变量都将被忽略 public class Foo NSManagedObject NSManaged var bar String var f Foo c
  • Windows 7 上的端口转发

    如何在 Windows 7 上将端口 xxx 上的传入请求重定向到 localhost yyy 开发服务器 相对于 2008 仅允许从本地主机访问 这还不够好 我需要从不同的计算机测试我的应用程序 感谢大家的建议 尽管我自己找到了答案 我下
  • 将数据存储在 iPhone 本地

    我正在构建一个应用程序 我想在设备本地存储用户信息 而不使用任何服务器数据库 但一切都在设备端 我希望存储特定的用户位置并将其显示在表格视图中 因此即使用户稍后启动应用程序 我也可以提取历史记录并向历史记录表提供过去的位置 基本上是本地数据
  • 使用PHP将制表符转换为空格以进行HTML显示?

    我需要在网页中显示一个纯文本文件 其中包含两个空格制表符的数据列 我所做的是使用 PHP 读取文本文件并将其打印出来 pre 标签使用等宽字体 如下所示 pre pre pre
  • Visual Studio 中 Qt 特定结构的缩进损坏

    VS编辑器中的自动缩进显然不知道Qt 信号和槽的声明会自动格式化 如下所示 class MyClass public QObject Q OBJECT public MyClass signals lt Broken indentation
  • 有没有 PHP 函数可以将数字转换为带有千位分隔符的货币?

    有没有PHP函数可以转换integer十亿和千万 900800 gt 9 00 800 500800 gt 5 00 800 正如您所添加的Yii在你的问题标签中 你可以这样做Yii的方式如下 Yii app gt language en
  • 由于视图模型为空,将剔除应用于填充的表单而不擦除表单的数据?

    我有一个脚本 通过将空视图模型应用到我的表单来初始化淘汰赛 当用户在表单中输入数据时 视图模型会相应更新 这是预期的行为 JavaScript var viewModel myField ko observable init functio
  • 是否可以在 Visual Studio Code 中为 Java 项目选择 JDK 8?

    我正在尝试使用 Visual Studio Code 来编译和运行基于 Maven 的 Java 项目 VSCODE 本身需要 JDK 11 我安装了 JDK 11 并将其添加为 VSCODE Java 配置 Java 运行时 部分中的 j
  • 动态类型与对象类型

    我交替使用了动态类型和对象类型 这两种类型有什么区别吗 使用其中一种对性能有什么影响吗 其中哪一个更灵活 They re hugely不同的 如果你使用dynamic您选择动态类型 从而在很大程度上选择退出编译时检查 是的 它的性能比使用静
  • 在多模块 Maven 构建中重用 ant-snippets

    如何在多个项目中重复使用 Ant 代码片段 假设我的根目录中有以下内容pom xml
  • 检查 Python 列表中是否存在某些内容

    我有一个元组列表Python http en wikipedia org wiki Python 28programming language 29 并且我有一个条件 仅当元组不在列表中时我才想采用分支 如果它在列表中 那么我不想采用 if
  • 使用 Spring Boot 实现 2 路 SSL

    我正在创建一些宁静的 Web 服务 并使用 Spring Boot 创建嵌入式 tomcat 容器 要求之一是实现 2 路 SSL 我一直在查看 HttpSecurity 对象 并且可以使用以下方法让它仅通过 SSL 通道运行 Web 服务