我有一个自定义UserDetails
实施,它有一个购物车属性。
class MyUserDetails implement UserDetails {
private Cart cart;
// getters & setters + other properties....
}
我希望匿名用户也是MyUserDetails的一个实例,到目前为止,我已经让它工作了,但所有匿名用户都有相同的购物车!
@Override
protected void configure(HttpSecurity http) throws Exception {
MyUserDetails anonymousUser = new MyUserDetails();
anonymousUser.setUsername("anonymousUser");
http.anonymous().principal(anonymousUser);
...
}
我如何为每个会话的匿名用户返回MyUserDetails的新实例?
答案 0 :(得分:1)
我很确定我设法通过创建这样的自定义AnonymousAuthenticationFilter
来实现它:
public class MyAnonymousAuthenticationFilter extends AnonymousAuthenticationFilter {
private static final String USER_SESSION_KEY = "user";
private final String key;
public MyAnonymousAuthenticationFilter(String key) {
super(key);
this.key = key;
}
@Override
protected Authentication createAuthentication(HttpServletRequest req) {
HttpSession httpSession = req.getSession();
MyUserDetails user = Optional.ofNullable((MyUserDetails) httpSession.getAttribute(USER_SESSION_KEY))
.orElseGet(() -> {
MyUserDetails anon = new MyUserDetails();
anon.setUsername("anonymousUser");
httpSession.setAttribute(USER_SESSION_KEY, anon);
return anon;
});
return new AnonymousAuthenticationToken(key, user, AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS"));
}
}
然后将其与http.anonymous().authenticationFilter(new MyAnonymousAuthenticationFilter(UUID.randomUUID().toString()));
如果这种方法有问题,或者你知道更好的方法,请告诉我!
答案 1 :(得分:1)
我的第一句话是,我倾向于同意@dur的评论,但这是另一个故事: - )
如果您仍然愿意坚持自己的方法,那么我认为如果不是过滤器,那么它将更符合Spring架构 实现您自己的AuthenticationProvider,它能够处理(验证)匿名令牌。像这样:
public class MyAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
//enrich the authentication here.
}
@Override
public boolean supports(Class<?> authentication) {
return (AnonymousAuthenticationToken.class
.isAssignableFrom(authentication));
}
}
然后,您将在过滤器链中注册此提供程序,例如,可能会由WebSecurityConfigurerAdapter初始化。您将通过配置本地身份验证管理器来执行此操作。这看起来像这样:
@Override
protected void configure(
AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(new MyAuthenticationProvider());
}
有关弹簧安全架构的深入审查,请参阅here。