Spring安全访客用户

时间:2017-11-17 09:16:55

标签: java spring spring-mvc spring-boot spring-security

我有一个自定义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的新实例?

2 个答案:

答案 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