简体   繁体   English

未在安全链过滤器中设置SecurityContext

[英]SecurityContext not set within security chain filter

In my spring project, I would like to create an endpoint which returns the security context user details for a clients active session cookie. 在我的春季项目中,我想创建一个端点,该端点返回客户端活动会话cookie的安全上下文用户详细信息。

One way would be a specific method implementation within a controller 一种方法是在控制器内执行特定的方法

@RequestMapping(value = "/session", method = GET)
public AuthenticatedUserDto getCurrentSession(HttpServletResponse response) {
    if (SecurityContextHolder.getContext().getAuthentication().getPrincipal() != null && SecurityContextHolder.getContext().getAuthentication().getPrincipal() instanceof User) {
        return AuthenticatedUserBuilder.build(SecurityContextHolder.getContext().getAuthentication());
    }
    throw new BadCredentialsException("unkown session");
}

There is few things which bother me on this approach: 这种方法让我有些困扰:

  • I need a ugly if to determine if it's not an anonymous authentication 我需要一个丑陋的if确定它不是一个匿名认证

  • I am handling this issue far to deep within the context, as I have all information already as soon the session cookie gets resolved. 我正在上下文中深入处理此问题,因为一旦解决了会话cookie,我已经拥有了所有信息。

So my other approach is using a security chain filter for matching the specific url ("/session), and handle the task there. 因此,我的另一种方法是使用安全链过滤器来匹配特定的url(“ / session”),并在那里处理任务。

public class SessionObjectResponder extends GenericFilterBean {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        ...//do create my response
        ..
    }
}

Adding the filter just before the AnonymousAuthenticationFilter , should guarantee that I would have the security context available matching the session cookie. AnonymousAuthenticationFilter之前添加过滤器,应确保我可以使用与会话cookie匹配的安全上下文。 So I configured my web security like this: 所以我这样配置我的网络安全性:

httpSecurity.antMatcher("/session").addFilterBefore(new SessionObjectResponder(),AnonymousAuthenticationFilter.class);

Oddly, the SecurityContextHolder contains a null authentication even when a valid session cookie is passed. 奇怪的是,即使通过了有效的会话cookie, SecurityContextHolder包含空身份验证。 I also can see that within the SecurityContextPersistenceFilter no security context gets set. 我还可以看到在SecurityContextPersistenceFilter没有设置安全上下文。

When I remove the httpSecurity configuration for this filter and add the @Component to the filter class, the SecurityContext is loaded correctly again. 当我删除此过滤器的httpSecurity配置并将@Component添加到过滤器类时,将再次正确加载SecurityContext (Without path matching of course) (当然没有路径匹配)

Why is that? 这是为什么?

You can ask for the Authentication or Principal like this: 您可以这样请求AuthenticationPrincipal

@RequestMapping(value = "/session", method = GET)
public AuthenticatedUserDto getCurrentSession(Authentication auth) {
    if (auth == null || !auth.isAuthenticated())
        throw new BadCredentialsException("unkown session");
    return AuthenticatedUserBuilder.build(auth);
}

When you use @Component or @Service or @Controller ... then it becomes spring managed been. 当您使用@Component或@Service或@Controller ...时,它将成为Spring管理的对象。 Their life cycle is managed by spring container. 它们的生命周期由弹簧容器管理。 Therefore context is available in container created instances. 因此,上下文在容器创建的实例中可用。

But in your case of 但是在你的情况下

httpSecurity.antMatcher("/session").addFilterBefore(new SessionObjectResponder(),AnonymousAuthenticationFilter.class);

You are creating the instance with new operator. 您正在使用new运算符创建实例。 It is not created by the container. 它不是由容器创建的。 So this instance is outside the container scope. 因此,此实例不在容器范围内。 Therefore the context is not available in that instance at runtime. 因此,上下文在运行时在该实例中不可用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM