gpt4 book ai didi

java - Spring Security 4.0.0 + ActiveDirectoryLdapAuthenticationProvider + BadCredentialsException PartialResultException

转载 作者:IT老高 更新时间:2023-10-28 13:57:47 32 4
gpt4 key购买 nike

我已经在 stackoverflow 上阅读了几乎所有关于 Spring/Security/Ldap 和 ActiveDirectory 的内容。即使我找到了有用的提示和提示,我也无法解决我的问题。

这是:我确实使用用户服务和自定义登录页面配置了 Spring Security,一切正常。然后,我尝试切换到最终的身份验证提供程序,它恰好是 ActiveDirectory。

这是我的 security-applicationContext.xml(我提醒您,此设置与作为身份验证提供程序的用户服务一起工作正常,因此,该文件实际上已导入等):

<?xml version="1.0" encoding="UTF-8"?>
<b:beans xmlns:b="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/security"
xmlns:oauth="http://www.springframework.org/schema/security/oauth"
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd http://www.springframework.org/schema/security/oauth http://www.springframework.org/schema/security/spring-security-oauth.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

<!-- Définitions globales de sécurité -->
<global-method-security pre-post-annotations="enabled" />

<!-- Configuration de l'accès et du formulaire -->
<!-- Permettre l'accès libre aux feuilles de style, polices et images -->
<http pattern='/resources/css/**' security="none" />
<http pattern='/resources/fonts/**' security="none" />
<http pattern='/resources/images/**' security="none" />

<http use-expressions="true" access-denied-page="/403" disable-url-rewriting="true">

<!-- Limitation à une seule session utilisateur concurrente -->
<session-management invalid-session-url="/identite?time=1">
<concurrency-control max-sessions="1" expired-url="/identite?time=1" />
</session-management>

<!-- Définitions pour le formulaire de la page JSP d'identification -->
<form-login login-page="/identite" login-processing-url="/identite.proc" default-target-url="/" always-use-default-target="true" authentication-failure-url="/identite?err=1" username-parameter="username" password-parameter="password" />

<logout logout-url="/logout" logout-success-url="/identite?out=1" delete-cookies="JSESSIONID" invalidate-session="true" />

<!-- Utiliser un canal chiffré pour les échanges -->
<intercept-url requires-channel="https" pattern="/identite*" access="permitAll()" />
<intercept-url requires-channel="https" pattern="/**" access="isAuthenticated()" />
</http>

<!-- Fournisseurs d'identité pour le formulaire (au final, LDAP) -->
<authentication-manager erase-credentials="true">
<ldap-authentication-provider ref="myADProvider" />
<!-- This is the user-service authentication provider that is working fine
<authentication-provider>
<user-service>
<user name="Toto" authorities="ROLE_USER, ROLE_ADMIN" password="totototo" />
</user-service>
</authentication-provider>
-->
</authentication-manager>

<b:bean id="myADProvider"
class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
<b:constructor-arg value="fsappsuni" />
<b:constructor-arg value="ldap://fsapps.company.uni:389/" />
<b:property name="convertSubErrorCodesToExceptions" value="true" />
<b:property name="useAuthenticationRequestCredentials" value="true" />
</b:bean>

在 bean myADProvider 中,即使我将第一个构造函数参数更改为 fsapps.company.uni 或 company.uni 或其他任何内容,它也不会将任何内容更改为以下错误。问题似乎是由于在绑定(bind)后使用错误的过滤器执行搜索以寻找类似 (&(userPrincipalName={0})(objectClass=user)) 而不是 (&(sAMAccountName={0})(objectClass =用户))。由于我无法弄清楚如何更改这一点,而您可以使用 LDAP 提供程序进行更改,因此我随后切换到 LDAP 提供程序,试图使其正常工作,但没有成功,也没有在同一个地方遇到问题。在阅读 ActiveDirectoryLdapAuthenticationProvider 存在问题后,我还将 Spring Framework 从 3.1.2 升级到 4.1.6.RELEASE 并将 Spring Security 从 3.1.2 升级到 4.0.0.RELEASE,希望同时解决此问题关于这个问题的最初讨论是在 3.x 版中进行的。

这是我尝试使用 Active Directory 进行身份验证的 LDAP 设置的配置:
<?xml version="1.0" encoding="UTF-8"?>
<b:beans xmlns:b="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/security"
xmlns:oauth="http://www.springframework.org/schema/security/oauth"
xsi:schemaLocation="http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.0.xsd
http://www.springframework.org/schema/security/oauth
http://www.springframework.org/schema/security/spring-security-oauth.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd">

<!-- Définitions globales de sécurité -->
<global-method-security pre-post-annotations="enabled" />

<!-- Configuration de l'accès et du formulaire -->
<!-- Permettre l'accès libre aux feuilles de style, polices et images -->
<http pattern='/resources/css/**' security="none" />
<http pattern='/resources/fonts/**' security="none" />
<http pattern='/resources/images/**' security="none" />

<http use-expressions="true" disable-url-rewriting="true">

<!-- Limitation à une seule session utilisateur concurrente -->
<session-management invalid-session-url="/identite?time=1">
<concurrency-control max-sessions="1" expired-url="/identite?time=1" />
</session-management>

<!-- Définitions pour le formulaire de la page JSP d'identification -->
<form-login login-page="/identite" login-processing-url="/identite.proc" default-target-url="/" always-use-default-target="true" authentication-failure-url="/identite?err=1" username-parameter="username" password-parameter="password" />
<csrf disabled="true" />

<logout logout-url="/logout" logout-success-url="/identite?out=1" delete-cookies="JSESSIONID" invalidate-session="true" />

<!-- Utiliser un canal chiffré pour les échanges -->
<intercept-url requires-channel="https" pattern="/identite*" access="permitAll()" />
<intercept-url requires-channel="https" pattern="/**" access="isAuthenticated()" />
</http>

<!-- Fournisseurs d'identité pour le formulaire (au final, LDAP) -->
<ldap-server url="ldap://fsapps.company.uni/dc=fsapps,dc=company,dc=uni" port="389" />
<authentication-manager erase-credentials="true">
<ldap-authentication-provider role-prefix="none"
user-search-filter="(&amp;(sAMAccountName={0})(objectClass=user))"
group-search-filter="(&amp;(member={0})(objectClass=group))"
user-search-base="dc=fsapps,dc=company,dc=uni">
</ldap-authentication-provider>
<!-- <authentication-provider ref="myADProvider" ></authentication-provider> -->
</authentication-manager>

<!--
<b:bean id="myADProvider" class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
<b:constructor-arg value="fsapps.company.uni" />
<b:constructor-arg value="ldap://fsapps.company.uni:389/" />
<b:property name="convertSubErrorCodesToExceptions" value="true" />
<!- -
<b:property name="useAuthenticationRequestCredentials" value="true" />
- ->
</b:bean>
<b:bean id="webSecurityExpressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"></b:bean>
-->

</b:beans>

这次把bean配置部分留给AD提供者引用。这也不行。

那么,如何将用户和组搜索路径传递给 AD 提供程序?或者,我如何配置 LDAP 提供程序以使用 AD 并完成身份验证?

这是我在 LDAP 设置的日志中收到的消息,上面解释了 AD 设置(错误的凭据主要是由于错误的搜索路径):
2015-04-15 16:19:13,252 DEBUG (o.s.s.a.ProviderManager.authenticate) [http-8443-1] Authentication attempt using org.springframework.security.ldap.authentication.LdapAuthenticationProvider MDC{}
2015-04-15 16:19:13,252 DEBUG (o.s.s.l.a.AbstractLdapAuthenticationProvider.authenticate) [http-8443-1] Processing authentication request for user: ba5glag MDC{}
2015-04-15 16:19:13,252 DEBUG (o.s.s.l.s.FilterBasedLdapUserSearch.searchForUser) [http-8443-1] Searching for user 'myuser', with user search [ searchFilter: '(&(sAMAccountName={0})(objectClass=user))', searchBase: 'dc=fsapps,dc=company,dc=uni', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ] MDC{}
2015-04-15 16:19:13,299 DEBUG (o.s.s.a.DefaultAuthenticationEventPublisher.publishAuthenticationFailure) [http-8443-1] No event was found for the exception org.springframework.security.authentication.InternalAuthenticationServiceException MDC{}
2015-04-15 16:19:13,299 ERROR (o.s.s.w.a.AbstractAuthenticationProcessingFilter.doFilter) [http-8443-1] An internal error occurred while trying to authenticate the user. MDC{}
org.springframework.security.authentication.InternalAuthenticationServiceException: Uncategorized exception occured during LDAP processing; nested exception is javax.naming.NamingException: [LDAP: error code 1 - 00000000: LdapErr: DSID-0C090627, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, vece(unprintable character here)]; remaining name 'dc=fsapps,dc=company,dc=uni'
at org.springframework.security.ldap.authentication.LdapAuthenticationProvider.doAuthentication(LdapAuthenticationProvider.java:207) ~[spring-security-ldap-4.0.0.RELEASE.jar:?]
at org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider.authenticate(AbstractLdapAuthenticationProvider.java:82) ~[spring-security-ldap-4.0.0.RELEASE.jar:?]

我希望我提供所有必需的信息,以便有人为解决此配置问题提供一些提示和指导。

更新 2015-04-16 ~10:20

我想出了如何使用 ActiveDirectoryLdapAuthenticationProvider 添加搜索过滤器。我还使用 Wireshark 观看了我的应用程序服务器和 AD 服务器之间的交换,以了解实际执行的操作。这是我的发现,我相信我离解决我的问题不远了。我更新的 security-applicationContext.xml,自从我现在专注于让 ActiveDirectoryLdapAuthenticationProvider 工作以来,我已经扔掉了 ldap-server 的东西。所以,现在这是一个更清晰的配置:
<?xml version="1.0" encoding="UTF-8"?>
<b:beans xmlns:b="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/security"
xmlns:oauth="http://www.springframework.org/schema/security/oauth"
xsi:schemaLocation="http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.0.xsd
http://www.springframework.org/schema/security/oauth
http://www.springframework.org/schema/security/spring-security-oauth.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd">

<!-- Définitions globales de sécurité -->
<global-method-security pre-post-annotations="enabled" />

<!-- Configuration de l'accès et du formulaire -->
<!-- Permettre l'accès libre aux feuilles de style, polices et images -->
<http pattern='/resources/css/**' security="none" />
<http pattern='/resources/fonts/**' security="none" />
<http pattern='/resources/images/**' security="none" />
<http pattern='/resources/js/**' security="none" />

<http use-expressions="true" disable-url-rewriting="true">

<!-- Limitation à une seule session utilisateur concurrente -->
<session-management invalid-session-url="/identite?expiree=1">
<concurrency-control max-sessions="1" expired-url="/identite?expiree=1" />
</session-management>

<!-- Définitions pour le formulaire de la page JSP d'identification -->
<form-login login-page="/identite" login-processing-url="/identite.proc" default-target-url="/" always-use-default-target="true" authentication-failure-url="/identite?err=1" username-parameter="username" password-parameter="password" />
<csrf disabled="true" />

<logout logout-url="/logout" logout-success-url="/identite?termine=1" delete-cookies="JSESSIONID" invalidate-session="true" />

<!-- Utiliser un canal chiffré pour les échanges -->
<intercept-url requires-channel="https" pattern="/identite*" access="permitAll()" />
<intercept-url requires-channel="https" pattern="/**" access="isAuthenticated()" />
<access-denied-handler error-page="/erreur403" />
</http>

<!-- Fournisseurs d'identité pour le formulaire (au final, LDAP) -->
<authentication-manager erase-credentials="true">
<authentication-provider ref="myADProvider" />
</authentication-manager>

<b:bean id="myADProvider" class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
<b:constructor-arg value="fsapps.company.uni" />
<b:constructor-arg value="ldap://fsapps.company.uni:389/" />
<b:property name="searchFilter" value="(&amp;(sAMAccountName={0})(objectClass=user))" />
<b:property name="convertSubErrorCodesToExceptions" value="true" />
<b:property name="useAuthenticationRequestCredentials" value="true" />
</b:bean>
<b:bean id="webSecurityExpressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler" />

</b:beans>

关于配置的评论很少。在 myADProvider bean 定义中,构造函数的第一个参数 fsapps.company.uni 用于以 username@fsapps.company.uni 的形式创建主体,并使用以下形式的 baseObject 为搜索请求构建 baseObject, dc=公司,dc=uni。

第二个构造函数的参数用于建立通信。 name="searchFilter"属性类型的下一个元素将调用 ActiveDirectoryLdapAuthenticationProvider 类的 setSearchFilter() 方法来设置搜索过滤器(这是我最初寻求取得一些进展的方法)。因此,它现在设置为搜索 (&(sAMAccountName={0})(objectClass=user))。

通过此设置,我可以在 WireShark 中看到 LDAP 对话并且绑定(bind)成功。绑定(bind)响应成功。接下来,搜索请求也成功,但不返回任何结果。因此,我仍然在我的日志中得到以下信息:
2015-04-16 10:30:28,201 DEBUG (o.s.s.a.ProviderManager.authenticate) [http-8443-2] Authentication attempt using org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider MDC{}
2015-04-16 10:30:28,201 DEBUG (o.s.s.l.a.AbstractLdapAuthenticationProvider.authenticate) [http-8443-2] Processing authentication request for user: myusername MDC{}
2015-04-16 10:30:28,294 DEBUG (o.s.s.l.SpringSecurityLdapTemplate.searchForSingleEntryInternal) [http-8443-2] Searching for entry under DN '', base = 'dc=fsapps,dc=company,dc=uni', filter = '(&(sAMAccountName={0})(objectClass=user))' MDC{}
2015-04-16 10:30:28,294 INFO (o.s.s.l.SpringSecurityLdapTemplate.searchForSingleEntryInternal) [http-8443-2] Ignoring PartialResultException MDC{}
2015-04-16 10:30:28,310 DEBUG (o.s.s.w.a.AbstractAuthenticationProcessingFilter.unsuccessfulAuthentication) [http-8443-2] Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials MDC{}
2015-04-16 10:30:28,310 DEBUG (o.s.s.w.a.AbstractAuthenticationProcessingFilter.unsuccessfulAuthentication) [http-8443-2] Updated SecurityContextHolder to contain null Authentication MDC{}
2015-04-16 10:30:28,310 DEBUG (o.s.s.w.a.AbstractAuthenticationProcessingFilter.unsuccessfulAuthentication) [http-8443-2] Delegating to authentication failure handler org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler@2876b359 MDC{}

我相信我快到了,但如果有人可以提供任何帮助,仍然可以使用一些帮助。经过仔细检查,似乎第一个构造函数的参数用于构造 baseObject 和 userPrincipalName 是我的问题。在我们的设置中,userPrincipalName 使用的域名不是 LDAP url 中的域名(即campaign.company.com)。到目前为止一切顺利,然后我可以更改参数以匹配用于构建用户主体的域名。现在,问题是这将更改必须与 LDAP url 模式(即 fsapps.company.uni)匹配的 baseObject。

从文档中,只有一种方法可以设置搜索过滤器,但是构造函数可以使用一个、两个或三个参数。第三个参数是提供 baseObject 值。

我的问题然后通过以下配置解决,我必须使用所有可用的 setter 和构造函数的参数来使其工作。 myADProvider bean 定义如下:
    <b:bean id="myADProvider" class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
<b:constructor-arg value="campus.company.com" />
<b:constructor-arg value="ldap://fsapps.company.uni:389/" />
<b:constructor-arg value="dc=fsapps,dc=company,dc=uni" />
<b:property name="searchFilter" value="(&amp;(userPrincipalName={0})(objectClass=user))" />
<b:property name="convertSubErrorCodesToExceptions" value="true" />
</b:bean>

就我而言,由于我回退到默认值,所以现在可以省略 searchFilter 属性。尽管对我的设置和问题进行了很长的描述。我希望其他人可以从中受益。

以下是 ActiveDirectorLdapAuthenticationProvider 类文档的链接: http://docs.spring.io/autorepo/docs/spring-security/4.0.0.RELEASE/apidocs/org/springframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProvider.html

我发现 WireShark 非常有助于查看应用程序服务器和 AD 服务器之间发生的情况以调试此问题。

最佳答案

我无法使用 Context.REFERRAL = "follow"解决这个问题,实际上问题在于 ActiveDirectoryLdapProvider 类的方法 searchForUser() 的代码。在此方法中,调用 SpringSecurityLdapTemplate.searchForSingleEntryInternal() 方法时使用 bindPrincipal,它实际上是 userPrincipalName,由传递给第一个参数中的构造函数的参数和用户名组成。因此,即使您将搜索过滤器设置为 userPrincipalName 以外的任何其他内容,它也会作为参数 0 传递 userPrincipalName。因此,带有 sAMAccountName 的过滤器将无法与 UPN 一起使用并引发异常。

应该修改或增加 searchForUser() 以检测 searchFilter 需要用户名而不是 UPN,或者提供额外的 setter 来使用 searchFilter 的模式设置参数。

但是在这种情况下没有办法让这个类在不修改代码的情况下正常工作。这就是我最后所做的。我编写了自己的类,基本上是原始 ActiveDirectoryLdapAUthenticationProvider 的副本,对 searchForUser() 进行了一个简单的修改,将用户名而不是 bindPrincipal 传递给 searchForSingleEntryInternal()。

你可以输入任何你想要的搜索过滤器,但被迫只使用一个参数,它实际上是 userPrincipalName 而没有其他参数,这有点废话。

关于java - Spring Security 4.0.0 + ActiveDirectoryLdapAuthenticationProvider + BadCredentialsException PartialResultException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29658844/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com