当前位置: 首页 > 知识库问答 >
问题:

Spring boot Spring Security应用程序的单向SSL和双向SSLendpoint

西门庆
2023-03-14

我有一个web应用程序,它有5个REST API。所有API都是启用SSL的HTTPS。这是服务器中的连接器标记。xml:

 <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
                maxThreads="150" scheme="https" secure="true"
                keystoreFile="conf/jks/ketStore.jks" keystorePass="keystore" keystoreType="jks"
                truststoreFile="conf/jks/trustStore.jks" truststorePass="truststore" truststoreType="jks"
                clientAuth="true" sslProtocol="TLSv1.2"/>

现在,我只需要制作一个应用程序接口,通过具有单向SSL的HTTPS公开。其他4个应用程序接口应该只能通过具有双向SSL证书的HTTPS访问。

解决Spring Boot和Spring 4安全问题的最佳方法是什么?

使现代化

我在这方面取得了一些进展。我已经设置了clientAuth=“want”,并且能够访问所需的API,而无需在客户端出示证书。但我不确定如何对其他API强制使用双向,并编写一个自定义过滤器来检查SSL握手。有没有办法在Spring安全中做到这一点。

我有以下MultiHttpSecurityConfig类:

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MultiHttpSecurityConfig {

  private static final Logger LOG = LoggerFactory
      .getLogger(MultiHttpSecurityConfig.class);


  @Configuration
  @Order(1)
  public static class SecureApiConfigurationAdapter extends
      WebSecurityConfigurerAdapter {

    @Autowired
    private HttpAuthEntryPoint httpAuthEntryPoint;

    @Autowired
    private X509UserDetSer x509UserUserDetSer;

    protected void configure(
        final HttpSecurity http)
        throws Exception {
      LOG.debug("/SSL2waysecureAPI/");
      http.csrf().disable()
          .antMatcher("/SSL2waysecureAPI/**")

          .x509()
          .subjectPrincipalRegex("CN=(.*?),")
          // .subjectPrincipalRegex(".*")
          .authenticationUserDetailsService(x509UserUserDetSer)
          .and().exceptionHandling()
          .authenticationEntryPoint(httpAuthEntryPoint)
          .and().sessionManagement()
          .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }
  }

Tomcat中的新连接器标记如下所示:

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
                maxThreads="150" scheme="https" secure="true"
                keystoreFile="conf/jks/ketStore.jks" keystorePass="keystore" keystoreType="jks"
                truststoreFile="conf/jks/trustStore.jks" truststorePass="truststore" truststoreType="jks"
                clientAuth="want" sslProtocol="TLSv1.2"/>

共有1个答案

蔚和安
2023-03-14

所以如果有人需要它——我这样做了

首先-server.xml配置文件

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
            maxThreads="150" scheme="https" secure="true"
            keystoreFile="conf/jks/ketStore.jks" keystorePass="keystore" keystoreType="jks"
            truststoreFile="conf/jks/trustStore.jks" truststorePass="truststore" truststoreType="jks"
            clientAuth="want" sslProtocol="TLSv1.2"/>

然后是网络。xml:

<filter>
    <filter-name>ServletFilter</filter-name>
    <filter-class>securechat.filter.ServletFilter</filter-class>
    <async-supported>true</async-supported>
</filter>

<filter-mapping>
    <filter-name>ServletFilter</filter-name>
    <url-pattern>/*</url-pattern>
 </filter-mapping>

之后,对任何endpoint的任何请求都将挂接到这个过滤器。在它里面,您可以手动检查像这样的任何request.something

@Component
public class ServletFilter implements Filter {

 public static final String X_CLACKS_OVERHEAD = "X-Clacks-Overhead";

    @Override
    public void doFilter(ServletRequest req, ServletResponse res,
                     FilterChain chain) throws IOException, ServletException {

    X509Certificate[] certificates = (X509Certificate[]) req
            .getAttribute("javax.servlet.request.X509Certificate");

    String servletPath = null;
    int port = -1;
    if (req instanceof HttpServletRequest) {
        servletPath = ((HttpServletRequest)req).getServletPath();
        port =  ((HttpServletRequest)req).getServerPort();

        System.out.println("getServletPath = " +  ((HttpServletRequest)req).getServletPath() );
        System.out.println(" ((HttpServletRequest)req).getServerPort() = " +   ((HttpServletRequest)req).getServerPort());

    //Just in memory of....
    HttpServletResponse response = (HttpServletResponse) res;
    response.setHeader(X_CLACKS_OVERHEAD, "GNU Terry Pratchett");


    //Here you can do checking for port and destination.
    if(port == 8080 && !servletPath.equals("/notSecureDest/something")
         //log error - we try to enter secured enpoint bu non-secured port and url
         return; // we decline request
    }else if(port == ??? && ???? ) {
        //if all checkings age good - we do
        chain.doFilter(req, res);
    }

} 

希望有帮助。

 类似资料:
  • 是否可以使用AWS应用程序负载平衡器和双向ssl(客户端证书)? 我当前的设置支持使用通过tcp到Web服务器endpoint的经典ELB转发。我现在需要使用URL路由流量,并希望在可能的情况下使用AWS应用程序负载均衡器进行路由。 如果没有,有没有关于如何在AWS中使用url路由流量的建议?

  • 对于双向SSL是如何工作的,我有些困惑。客户端如何创建要发送到服务器的证书?是否从服务器生成并分发到客户端? 另外,与单向SSL相比,双向SSL的优势是什么?

  • 如果我正确理解SSL/TLS在仅服务器身份验证中的含义,那么在握手之后,服务器会向客户端发送它的公钥和一个由CA签名的数字签名证书。如果客户端拥有这个CA的公钥,它就可以解密证书并与服务器建立信任。如果它不信任CA,则通信停止。在双向SSL中,客户端需要向服务器进行身份验证,在客户端接收到公钥和数字签名的证书之后,客户端将向服务器发送它的公钥和数字签名的证书。服务器将检查它是否有客户机证书的公钥,

  • 我试图使用nginx作为双向SSL/相互SSL的web逻辑的反向代理。 客户端<=双向SSL=>NGINX<=双向SSL=>WebLogic服务器 客户端到NGINX双向SSL工作良好,但在上游连接到web逻辑上出现以下错误。 nginx调试日志: 以下是我对上游的nginx配置: 我尝试了各种选项,包括注释下面的配置。 如果我尝试使用openssl c_client命令行,我能够连接并获得HTT

  • 我正在创建一些restful Web服务,并使用Spring-Boot创建一个嵌入式tomcat容器。 其中一个要求是实现双向SSL。我一直在研究HttpSecurity对象,可以使用以下方法使其仅在SSL通道上运行webservices:- 我似乎找不到一种方法来使Web服务仅可供提供有效客户端证书的应用程序访问。 我只有SSL的基本知识,所以即使是正确方向的一般指针也将不胜感激。 正在部署的服

  • 我试图设置2方式ssl身份验证。我的要求是经纪人应该只认证特定的客户。 我的组织有一个CA,它发行pkcs12格式的所有证书。我遵循的步骤如下。 获取代理的证书,并在代理密钥库中配置它 当我运行代理和客户端时,我希望代理验证客户端并建立ssl连接。但是下面的错误被抛出。 当我用只包含CA证书的信任存储文件替换 /etc/pki/java/cacerts代理信任存储时,它工作得很好。但是它将验证任何