SpringSecurity – 自定义自动身份validation

这是我的情景:

  • Web应用程序为许多应用程序执行一种SSO
  • 登录用户而不是单击链接,应用程序使用用户信息(名称,pwd [无用],角色)发布到适当的应用程序
  • 我正在其中一个应用程序上实现SpringSecurity,以便从它的function中受益(会话中的权限,其类提供的方法等)

所以,我需要开发一个自定义filter – 我想 – 能够从请求中检索用户信息,从数据库检索,通过自定义DetailsUserService ,有关用户的更多信息(电子邮件等等),然后执行身份validation该用户,根据从请求中检索到的角色。

我正在查看预身份validationfilter,但我不确定它是否是正确的选择。 似乎这些对象在主体已经在会话中时被使用,由一些先前的认证机制放置(是不是?)。

我认为,一旦确定了正确的filter,我应该在以下内容中执行:

GrantedAuthority[] ga= new GrantedAuthority[1]; ga[0] = new GrantedAuthorityImpl(myUser.getRole()); SecurityContext sc = SecurityContextHolder.getContext(); Authentication a = new UsernamePasswordAuthenticationToken(userName, userPwd, ga); a = authenticationManager.authenticate(a); sc.setAuthentication(a); 

这是解决我问题的正确方向吗? 你有什么建议可以帮我找到遗失的东西吗?

谢谢你们,

卢卡

加成:

嗨Xearxess! 很抱歉再次打扰你,但似乎根据SpringSecurity 2.0.4的代码翻译比我想象的更难:S问题是XML …我尝试了不同的配置,但我总是遇到命名空间问题,缺少属性等等……

                     

引用CUSTOM-FILTER元素的2行是两次不同的尝试,它们都被标记为错误。 如何指定filter作为属性的位置?

此外,auth manager定义上的身份validation提供程序引用也标记为错误。 我认为我也需要将它指定为属性,对吧?

希望你能给我最后一次推动;)再次感谢你,

卢卡

是的,预身份validation方案正是您所需要的。

似乎这些对象在主体已经在会话中时被使用,由一些先前的认证机制放置(是不是?)。

实际上,您可以根据需要使用预身份validation从请求创建PreAuthenticatedAuthenticationToken 。 只做我在另一个问题中描述的一些事情 。

首先扩展AbstractPreAuthenticatedProcessingFilter以从请求获取用户名和角色:

 public class MyPreAuthenticatedProcessingFilter extends AbstractPreAuthenticatedProcessingFilter { public MyPreAuthenticatedProcessingFilter( AuthenticationManager authenticationManager) { setAuthenticationDetailsSource(new MyAuthenticationDetailsSource()); } @Override protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) { return "Anonymous"; } @Override protected Object getPreAuthenticatedCredentials(HttpServletRequest request) { return "N/A"; } public static class MyAuthenticationDetailsSource implements AuthenticationDetailsSource { // roles probably should be encrypted somehow static final String ROLES_PARAMETER = "pre_auth_roles"; @Override public MySessionUserDetails buildDetails(HttpServletRequest req) { // create container for pre-auth data return new MySessionUserDetails(req.getParameter(ROLES_PARAMETER)); } } } 

MySessionUserDetails类将弹出角色为List of SimpleGrantedAuthority或任何其他GrantedAuthority实现。 此外,建议使用List并优于GrantedAuthority[]

其次,实现AuthenticationUserDetailsService

 public class MyPreAuthenticatedUserDetailsService implements AuthenticationUserDetailsService { @Override public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token) throws UsernameNotFoundException { MySessionUserDetails sessionUserDetails = (MySessionUserDetails) token.getDetails(); List authorities = sessionUserDetails.getAuthorities(); return new User(token.getName(), "N/A", true, true, true, true, authorities); } } 

然后在你的XML连接块中:

                

瞧! 您应该在您的应用程序中使用经过身份validation的User主体。

我在这里编写的代码需要Spring Security 3.1,如果您即将使用它,我强烈建议使用它(它确实需要Spring 3.0.7+)。 另外, Spring Security参考手册是您的朋友!

为了完整起见,在Spring Security 4中,事情略有改变。 例如,强烈建议使用Java配置。 通过这种方式,可以更轻松地与Spring Boot集成。

它遵循Java配置,等同于上面答案中给出的XML配置。

 @Configuration @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.addFilterBefore(customAuthFilter(), AbstractPreAuthenticatedProcessingFilter.class) .authenticationProvider(preauthAuthProvider()) .authorizeRequests() .anyRequest().authenticated(); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(preauthAuthProvider()); } @Bean public PreAuthenticatedAuthenticationProvider preauthAuthProvider() { PreAuthenticatedAuthenticationProvider preauthAuthProvider = new PreAuthenticatedAuthenticationProvider(); preauthAuthProvider.setPreAuthenticatedUserDetailsService( userDetailsServiceWrapper()); return preauthAuthProvider; } @Bean public OnlyRolesPreAuthenticatedUserDetailsService userDetailsServiceWrapper() { OnlyRolesPreAuthenticatedUserDetailsService service = new MyPreAuthenticatedUserDetailsService(); return service; } @Bean public MyPreAuthenticatedProcessingFilter customAuthFilter() throws Exception { MyPreAuthenticatedProcessingFilter filter = new MyPreAuthenticatedProcessingFilter(); filter.setAuthenticationManager(authenticationManager()); return filter; } } 

我认为上面的代码是值得的,因为互联网上的例子非常基础,Spring文档缺乏这些细节。