我设法使用证书中的用户名对Ldap用户进行身份验证。我想要获得的是直接使用Ldap上的证书对用户进行身份验证。 我找不到如何将证书传递给Ldap。
这是当前配置(使用证书的用户名):
<security:x509 subject-principal-regex="CN=(.*?)," user-service-ref="userService"/>
<bean name="userService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
<constructor-arg ref="ldapUserSearch"/>
<constructor-arg ref="ldapAuthoritiesPopulator"/>
</bean>
<bean name="ldapUserSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg value=""/>
<constructor-arg value="sAMAccountName={0}"/>
<constructor-arg ref="contextSource" />
</bean>
<bean name="ldapAuthoritiesPopulator" class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
<constructor-arg ref="contextSource" />
<constructor-arg value="" />
<property name="groupSearchFilter" value="member={0}" />
<property name="searchSubtree" value="true" />
</bean>
答案 0 :(得分:1)
我自己正在研究这个问题。我还没有找到一个执行X509->帐户解析“权限”的身份验证堆栈。我得知Spring Security的UserDetailsService接口坚持使用字符串uid进行查找,但在很多情况下,不可能从X509证书主题中包含的信息中导出这样的UID(例如,有很多cn = John Smith在世界上,甚至在单个组织内,证书DN中也不需要电子邮件。证书的唯一性在于Issuer + Serial Number组合,而不是Subject。
查看API后,有几种方法可以解决这个问题。无论哪种方式都可能排除使用命名空间并自行设置过滤器链和bean:
1)实现您自己的AuthenticationUserDetailsService并将其绑定到PreAuthenticatedAuthenticationProvider。默认情况下,我相信,命名空间使用传入的user-service-ref设置UserDetailsByNameServiceWrapper。走这条路线意味着你必须做所有事情来设置UserDetails,包括授予权限解决方案。当然,你可以委托所有这些,但更多的工作。
2)如果您的LDAP存储由某个UID键入,并且这是我倾向于的路由,请实现您自己的X509PrincipalExtractor并将其绑定到X509AuthenticationFilter并返回您的LDAPUserDetailsService配置的字符串uid。在提取器中实现逻辑以在LDAP存储中搜索存储的证书。我不知道任何可以跨LDAP服务器工作的策略,最简单的方法是,如果你的LDAP支持RFC4523 certificateMatch或certificateExactMatch,你可以配置一个搜索过滤器,它将返回一个唯一的帐户,然后你可以从中返回属性你需要(例如sAMAccountName)。如果没有,如果您的证书包含可以过滤的值(例如,证书cn = LDAP cn),您可以使用该值来检索一组候选LDAP结果,请将其证书提取到X509Certificate,并对传递的.equals()执行.equals()在证书中找到匹配并返回其uid的帐户。
答案 1 :(得分:0)
设置LDAP服务器以使用SSL进行客户端身份验证。
答案 2 :(得分:0)
最后,我在我的非网络应用程序中实现了以下解决方案:
<bean id="x509ContextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<constructor-arg value="ldap://hostname:389/DC=base,DC=com" />
<property name="authenticationStrategy">
<bean class="org.springframework.ldap.core.support.ExternalTlsDirContextAuthenticationStrategy">
<property name="sslSocketFactory">
<bean class="yourOwnSocketFactory"/>
</property>
<property name="shutdownTlsGracefully" value="true" />
</bean>
</property>
</bean>
其中yourOwnSocketFactory获取用户的证书以建立TLS连接。
成功的TLS连接意味着用户已通过身份验证。配置良好的LDAP就是这种情况,应该检查用户是否包括证书撤销列表。
建立连接后,您必须使用自定义BindAuthenticator恢复用户的信息,该自定义BindAuthenticator可以提取(X509PrincipalExtractor)证书DN(或其他有用信息)以匹配LDAP用户。