在Spring 3.1中通过IP地址进行身份validation:最明智的方法吗?

我使用Spring Security 3.1实现了LDAP身份validation。 我的security.xml文件发布在下面。

我需要更改我的身份validation过程,以便当用户从“白名单”(保存在数据库表中)中的IP地址进入站点时,该用户应该自动使用Spring 3.1进行身份validation,然后重定向远离登录屏幕(不是我的想法,我被告知这样)。

如果用户不是来自白名单IP地址之一,则应强制他/她在登录页面上进行LDAP身份validation。

我是Spring和Spring Security的新手,所以我参阅了Spring 3.1参考文档并阅读了第I部分的所有内容。在那里,我阅读了一些建议,如果您有任何特殊的身份validation需求,您应该阅读第II部分的体系结构和实现 。 我做到了,非常缓慢并记笔记。

但是,由于我是所有这一切的新手,我不确定我是否完全理解我需要做什么以及最聪明的方法。


更新3:我得到了骨架代码,这是我最终得到的文件


我的自定义AuthenticationProvider实现,用于通过IP地址进行身份validation

// Authentication Provider To Authenticate By IP Address With Allowed IPs // Stored in a db table package acme.com.controller.security; //import acme.com.controller.security.CustomUserInfoHolder; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.WebAuthenticationDetails; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; import org.springframework.security.core.authority.mapping.NullAuthoritiesMapper; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.userdetails.UserDetails; import org.apache.log4j.Logger; public class CustomIPAddressAuthenticationProvider implements AuthenticationProvider { private static final Logger logger = Logger.getLogger(CustomIPAddressAuthenticationProvider.class); private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper(); @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { WebAuthenticationDetails wad = null; String userIPAddress = null; boolean isAuthenticatedByIP = false; // Get the IP address of the user tyring to use the site wad = (WebAuthenticationDetails) authentication.getDetails(); userIPAddress = wad.getRemoteAddress(); logger.debug("userIPAddress == " + userIPAddress); // Compare the user's IP Address with the IP address in the database // stored in the USERS_AUTHENTICATED_BY_IP table & joined to the // USERS tabe to make sure the IP Address has a current user //isAuthenticatedByIP = someDataObject.hasIPAddress(userIPAddress); isAuthenticatedByIP = true; // Authenticated, the user's IP address matches one in the database if (isAuthenticatedByIP) { logger.debug("isAuthenticatedByIP is true, IP Addresses match"); UserDetails user = null; UsernamePasswordAuthenticationToken result = null; result = new UsernamePasswordAuthenticationToken("John Principal", "PlaceholderPWE"); result.setDetails(authentication.getDetails()); return result; } // Authentication didn't happen, return null to signal that the // AuthenticationManager should move on to the next Authentication provider return null; } @Override public boolean supports(Class authentication) { // copied it from AbstractUserDetailsAuthenticationProvider return(UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication)); } } 

我的* -security.xml文件

                    

你的方法看起来很合理,你认为Spring会尝试每个AuthenticationProvider直到它获得成功结果是正确的,因此在你的情况下你将在LDAP提供者之前定义你的基于IP的提供者。

根据您的设置,您可能无法在authentication.getDetails()调用上获得WebAuthenticationDetails对象。 如果是这种情况,您应该将Spring的RequestContextListener或RequestContextFilter添加到您的web.xml。 然后,您可以使用RequestContextHolder类并调用RequestContextHolder.getRequestAttributes()来获取源IP地址。

您应该只需要实现AuthenticationProvider,不需要实现UserDetailsS​​ervice,UserDetails或Authentication类。 如果您无法通过其IP地址对用户进行身份validation,则应返回null。 在这种情况下,Spring将尝试LDAP提供程序。 如果由于某种原因您不想将尝试传递给LDAP,则应抛出AuthenticationException,这将停止该过程并最终导致用户403错误。

我希望这有帮助 :)