2016-04-23 36 views
0

考虑以下情形:春季安全对定制UserDetailsService执行验证的登录数据如下如何定制会话的行为由当前用户作用域的bean是Spring MVC的

@Override 
    public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException { 
     List<GrantedAuthority> authorities = new ArrayList<>(); 
     authorities.add(new SimpleGrantedAuthority("ROLE_USER")); 

     UserProfile profile = users.find(name); 
     if (profile.getUsername().equals("admin")) 
      authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN")); 

     return new User(profile.getUsername(), profile.getPassword(), authorities); 
    } 

如果认证成功,我想创造出独特的session scoped service在控制器中,通过有效的UserProfile对象状态自定义行为。我想最好的方法是在配置文件中手动声明会话bean,并以某种方式autowireUserProfile会话所有者它是构造函数,但是如何在UserProfile甚至不是托管对象时可能如此?

在这种情况下,我想服务器创建存储在UserProfile

另外,如何限制一个建立这样的服务,为验证用户的服务,保持与凭证SSH连接到远程主机刚刚登录后?是否有办法实现这种行为,还是实际上是糟糕的架构?

回答

0

您可以使用SecurityContextHolder访问当前请求的已认证用户。我认为最好的办法是建立一个集服务,像这样的方法:

public UserDetails getCurrentUser() { 
    Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 
    if (principal instanceof UserDetails) { 
     return (UserDetails) principal; 
    } else { 
     //handle not authenticated users 
     return null; 
    } 
} 

现在,您可以自动装配,并在控制器中使用该服务。

+0

我可以将实际的UserProfile对象添加到安全上下文并以相同的方式检索它吗?尝试使用会话作用域bean时,我也遇到以下错误:'org.springframework.web.util.NestedServletException:请求处理失败;嵌套异常是java.lang.IllegalArgumentException:setAttribute:名称为scopedTarget.sessionBean的不可序列化属性 ' –

+0

SecurityContextHolder返回从UserDetailsS​​ervice返回的同一对象。所以你应该可以将它转换为'UserProfile'而不是'UserDetails'。我的示例中的服务应该是单例,而不是会话/请求范围。而异常意味着会话范围的bean应该是'Serializable'。 – Cyril

+0

更正:你从'UserDetailsS​​ervice'返回'User'。这意味着你不能将其转换为'UserProfile'。为什么你需要'UserProfile'对象? – Cyril

相关问题