简体   繁体   English

Spring boot + Spring Security单向SSL和双向SSL端点用于应用程序

[英]Spring boot+Spring Security one way SSL and two-way SSL endpoint for application

I have a web application which has 5 REST APIs. 我有一个Web应用程序,它有5个REST API。 All the APIs are HTTPS with SSL enabled. 所有API都是启用了SSL的HTTPS。 This is connector tag in server.xml: 这是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="true" sslProtocol="TLSv1.2"/>

Now I have to make only one of the APIs to be exposed over HTTPs with onw-way SSL. 现在,我必须只使用onw-way SSL通过HTTP公开其中一个API。 The other 4 APIs should be accessible only over HTTPS with 2-way SSL certificates. 其他4个API只能通过具有双向SSL证书的HTTPS访问。

What is the best way in approaching this problem with Spring boot and Spring 4 Security. 使用Spring启动和Spring 4安全性解决此问题的最佳方法是什么。

Update 更新

I have progressed a bit on this. 我在这方面取得了一些进展。 I have set clientAuth="want" and able to access the required API without presenting a certificate at client side. 我已设置clientAuth="want"并且无需在客户端提供证书即可访问所需的API。 But I am not sure on the way to enforce 2-way for other APIs and write a custom filter to check SSL handshake. 但我不确定在为其他API强制执行2-way并编写自定义过滤器来检查SSL握手的方法。 Is there a way to do this in Spring Security. 有没有办法在Spring Security中执行此操作。

I have the below MultiHttpSecurityConfig class: 我有以下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);
    }
  }

The new connector tag in Tomcat is like below: 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"/>

So if someone needs it - I did something like this in this way 所以,如果有人需要它 - 我就是这样做的

First of all - server.xml config file 首先 - 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"/>

Then web.xml : 然后是web.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>

After that, any request to any endpoint will be hooked to this filter. 之后,任何端点的任何请求都将挂钩到此过滤器。 Inside of it you can manually check any request.something like 在它内部你可以手动检查任何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);
    }

} 

Hope that helps. 希望有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM