问题描述
在基于Spring Security 3.2的应用程序中,我需要根据用户名和远程IP地址中的特定模式,针对两个不同的提供程序对用户进行身份验证.
In a Spring Security 3.2 based application I need to authenticate users against two different providers, based on a certain pattern in their username AND their remote ip address.
如果它们符合某些规则,则应针对ActiveDirectoryLdapAuthenticationProvider
对其进行身份验证,否则,使用已经存在的UserDetailsService
定制实现使用标准AuthenticationProvider
进行身份验证.
In case they match certain rules, they should be authenticated against an ActiveDirectoryLdapAuthenticationProvider
, otherwise with a standard AuthenticationProvider
using an already exisiting custom implementation of UserDetailsService
.
我需要扩展什么? AuthenticationManager
或AuthenticationProvider
?任何示例代码将不胜感激:-)
What do I need to extend ? AuthenticationManager
or AuthenticationProvider
? Any example code would be highly appreciated :-)
注意:我已经成功尝试在<authentication-manager />
中添加两个<authentication-provider />
节点,并且工作正常.但是令我感到困扰的是,每次身份验证尝试(甚至是不适合它的尝试)都会击中我的Ldap服务器.
Note: I have already successfully tried adding two <authentication-provider />
nodes in <authentication-manager />
, and this worked fine. But it bothers me that my Ldap-server is hit for every authentication attempt (even the ones which are not meant for it)
推荐答案
您可以创建一个包装器,该包装器检查模式/ip地址是否匹配(如果调用匹配),否则委托返回null.
You could create a wrapper which does the check for the pattern/ip-address if it matches calls the delegate else return null.
public class FilteringAuthenticationProvider implements AuthenticationProvider {
private final AuthenticationProvider delegate;
public FilteringAuthenticationProvider(AuthenticationProvider delegate) { this.delegate=delegate;}
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
Object details = authentication.getDetails();
String username = authentication.getPrincipal().toString();
String remoteAddress = null;
if (details instanceof WebAuthenticationDetails) {
remoteAddress = ((WebAuthenticationDetails) details).getRemoteAddress();
}
if (matches(remoteAddress, username)) {
return delegate.authenticate(authentication);
}
return null
}
private boolean matches(String remoteAddress, String Username) {
// your checking logic here
}
}
类似这样的事情.然后在您的安全性配置中对其进行配置,并让其包装ActiveDirectoryLdapAuthenticationProvider
.
Something like this. Then configure it in your security configuration and let it wrap the ActiveDirectoryLdapAuthenticationProvider
.
<sec:authentication-manager>
<sec:authentication-provider ref="filteringLdapProvider" />
<sec:authentication-provider>
<user-service ref="customUserDetailsService" />
</sec:authentication-provider>
</sec:authentication-manager>
<bean id="filteringLdapProvider" class="FilteringAuthenticationProvider">
<constructor-arg ref="ldapProvider" />
</bean>
<bean id="ldapProvider" class="ActiveDirectoryLdapAuthenticationProvider">
...
</bean>
类似这样的事情.
这篇关于根据用户名和远程IP地址使用不同的AuthenticationProvider的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!