Rob*_*ans 10 spring spring-security spring-security-oauth2
上周,我开始扩展UserDetails类,以便能够支持自定义字段.关于这个领域的特殊之处在于它填充了一个取决于请求参数的值.我设法正确地实现了这个(所以问题不关注那个).
现在的问题是,在成功登录后,UserDetails对象被正确填充(我能够使用AuthenticationSuccessHandler看到这一点),并且客户端从OAuth2提供程序接收JWT令牌.然后,客户端通过访问"/ uaa/user"端点尝试获取有关用户的更多详细信息.这被设置为返回Principal对象.但在检查Principal对象的内容后,我被告知UserDetails对象丢失了.方法getPrincipal()仅返回用户名而不是UserDetails对象.
根据这个问题,这是登录失败的结果.AuthenticationToken(在本例中为UsernamePasswordAuthenticationToken)被AuthenticationManager拒绝.我不知道它为什么要做这样的事情.使用默认UserDetails对象的身份验证似乎工作得很好.有人可以帮我解决这个问题吗?
有关已实现类的一些细节(如上所述).有些代码因此被遗漏.
CustomUserDetails
public class CustomUserDetails extends User {
private final Integer custom;
public CustomUserDetails (...default params..., Integer custom) {
super(...default params...);
this.custom = custom;
}
}
Run Code Online (Sandbox Code Playgroud)
CustomUserDetailsService
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Override
public CustomUserDetails loadUserByUsername(String username) throw UsernameNotFoundException {
return new CustomUserDetails(...default params..., 12345);
}
}
Run Code Online (Sandbox Code Playgroud)
组态
@Autowired
private CustomUserDetails userDetails;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetails);
}
Run Code Online (Sandbox Code Playgroud)
用户端点
@RequestMapping(value = "/user", method = RequestMethod.GET)
@ResponseBody
public Principal getDetails(Principal user) {
return user;
}
Run Code Online (Sandbox Code Playgroud)
这里返回的Principal对象应该包含UserDetails对象,并且应该将它返回给客户端.但是,当你调用getPrincipal()时,它只返回一个带有用户名的String;
最后,我希望User端点返回的JSON(返回Principle对象)包含我添加到UserDetails的自定义字段.
提前致谢.
通常,您需要注释@AuthenticationPrincipal,但我建议您构建自己的注释,如下所示:
/**
* Our own {@link AuthenticationPrincipal} annotation as suggested by
* http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#mvc-authentication-principal
*
*/
@Target({ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@AuthenticationPrincipal
public @interface CurrentUser {}
Run Code Online (Sandbox Code Playgroud)
然后你可以Principal用这种方式:
@RequestMapping(..)
public Principal test(@CurrentUser Principal principal){..}
Run Code Online (Sandbox Code Playgroud)
但是,恕我直言,你应该拥有自己的校长Impl,或者更确切地说扩展现有的impl.这样的事情:
public MyPrincipal extends org.springframework.security.core.userdetails.User {..}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您可以随意返回值.
| 归档时间: |
|
| 查看次数: |
1130 次 |
| 最近记录: |