Spring X509 在所有身份验证级别的安全性

Spring Security with X509 at all levels of authentication

我有一个遗留应用程序,我正在将其从用户密码转换为使用基于证书的身份验证。我正在使用 Tomcat 7,我的应用程序需要支持基于用户尝试访问的应用程序中的 URL 的 4 种安全类型

例如: 一些 servlet 将使用 HTTP 一些 servlet 将使用 HTTPS 而无需任何身份验证 一些 servlet 将使用 PKI 进行相互身份验证,但用户不会事先知道,因此任何在证书链中拥有有效证书的用户都将被授予访问权限。 应用程序的重置是管理,因此它将具有基于预定义用户证书 CN 的基于角色的访问。

我的 Tomcat server.xml

中有一个连接器 运行 HTTPS,地址为 443,clientAuth="want"

我有我的应用程序 web.xml,它有一个 springSecurityFilterChain,它列出了我想要要求 HTTPS

的任何 URLS

我的 springSecurityContext.xml 有一个 x509 部分,其中有 subject-principal-regex="CN=(.*?)," user-service-ref="userDetailsService" 从 属性 文件。从那里,我列出了 intercept-url 模式,其中我想要一个 requires-channel="https" 以及哪些模式需要哪些角色。

我还添加了 URLs,我希望它仅通过将 access="IS_AUTHENTICATED_ANONYMOUSLY" 设置为拦截来要求 HTTPS -url

这满足了我需要的 4 个要求中的 3 个,因为上面的 URL 中的任何一个都会使用 spring 安全性自动从 HTTP 重定向到 HTTPS,并针对角色强制执行用户凭据,或者根本不检查客户端证书。未放入 web.xml springSecurityFilterChain 的 url 模式将接受 HTTP 连接。

我想不通的是最终模式,即应用程序请求客户端证书,该证书将针对证书链中的 CA 进行验证,但不会针对我已知的用户数据库进行验证角色。他们将拥有有效的证书,我需要访问客户端证书才能发现这些证书,但实际上在我的系统中并不为人所知,因为他们只是应用程序的一般用户。我不太确定如何完成此操作。

以下是我的 3 个 XML 文件中的一些片段,以显示我在说什么。我只在 spring 安全性中包含 httpsandcertlink 以显示我要添加的是哪个,但无法开始工作。

server.xml

<Connector port="443" protocol="org.apache.coyote.http11.Http11Protocol"
maxThreads="150" SSLEnabled="true" scheme"https" secure="true"
clientAuth="want" sslProtocol"TLS"
keystoreFile="doesntmatter"
truststoreFile="doesntmatter" />

web.xml

<login-config>
<auth-method>CLIENT-CERT</auth-method>
<realm-name>MYAPP</realm-name>
</login-config>

<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>*.go</url-pattern>
<url-pattern>/httpsonlylink</url-pattern>
<url-pattern>/httpsandcertlink</url-pattern>
</filter-mapping>

springSecurityContext.xml

<security:http xmlns="http://www.springframework.org/schema/security" >
<security:x509 subject-principal-regex="CN=(.*?)," user-service-ref="userDetailsService" />
<security:intercept-url pattern="/management**" requires-channel="https" access="ROLE_MGMT" />
<security:intercept-url pattern="/httpsonlylink**" requires-channel="https" access="IS_AUTHENTICAED_ANONYMOUSLY" />
<security:intercept-url pattern="/httpsandcertlink**" requires-channel="https" --not sure what to change here-- />
</security:http>

<security:authentication-manager xmlns="http://www.springframework.org/schema/security" alias="authenticationManager">
<security:authentication-provider>
<security:user-service id="userDetailsService" properties="\WEB-INF\users.properties" />
</security:authentication-provider>
</security:authentication-manager>

一种方法是通过创建一个额外的 "valid certificate" 角色来搭载角色要求中缺少的要求,该角色会自动分配给所有用户。应该已经需要一个有效的证书链,所以所需要的只是设置一个拦截-url 模式,该模式将匹配任何需要有效证书的 URL 并需要 "valid certificate"角色,确保此规则匹配之后需要特定角色的规则。