繁体   English   中英

通过Spring SecurityContextHolder更新权限

[英]Update authorities through Spring SecurityContextHolder

我正在使用Spring Security来验证用户身份。

问题是动态更新权限的最佳方法是什么? 我想根据请求更新它,现在我仅在用户登录系统后执行一次。

我有基于经理的应用程序,因此管理员可以决定用户可以做什么,并删除/添加角色。 这种方法存在问题,即用户只有在注销并重新登录后才能获得新的权限集。

我知道我可以用

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
List<GrantedAuthority> authorities = Lists.newArrayList();

userDao.getAuthorities(authorities, user);

Authentication newAuth = new UsernamePasswordAuthenticationToken(auth.getPrincipal(), auth.getCredentials(), authorities);
 SecurityContextHolder.getContext().setAuthentication(newAuth);

主要问题是什么时候是合适的时机? 框架到达控制器或拦截器之前有一些过滤器链吗? 它有多安全? 线程安全吗?

可以说,如果我将其放在拦截器中,并且在一个请求中更新SecurityContextHolder时又有另一个请求读取它-会发生什么?

只是草稿

public class VerifyAccessInterceptor extends HandlerInterceptorAdapter {
    public boolean preHandle(
            HttpServletRequest request,
            HttpServletResponse response,
            Object handler) throws Exception {

          Authentication auth =  SecurityContextHolder.getContext().getAuthentication();
           List<GrantedAuthority> authorities = Lists.newArrayList();

           userDao.getAuthorities(authorities, user);

           Authentication newAuth = new  UsernamePasswordAuthenticationToken(auth.getPrincipal(), auth.getCredentials(),             authorities);
               SecurityContextHolder.getContext().setAuthentication(newAuth);

    }
}

如果我错了,请纠正我。

从您的问题显而易见,您希望更改基于请求的Authority 理想情况下,管理员将具有一个不同的UI,可以在其中删除/添加权限。 这些更改必须实时反映在任何已登录的用户会话中。

当前,您提供的代码段是唯一的方法。

回答您的问题。

The main question is what would be the right moment to do it?

如果要将其仅应用于登录的用户,则必须将其放在拦截器中,因为它将仅在Spring安全过滤器链之后应用。

Some filter chain before framework hit controller or interceptor?

是的,在您的请求到达控制器或拦截器之前,将首先调用DelegatingFilterProxy和FilterChainProxy。

And how safe it is? Thread safe?

是的,如果将SecurityContextHolder与默认设置一起使用,它将使用线程安全的ThreadLocalSecurityContextHolderStrategy

由于所有请求都必须通过拦截器,因此性能会受到影响。 而且由于您仅需要更改权限才需要更改权限,以便在重新设置Authentication之前在拦截器中进行检查

public class VerifyAccessInterceptor extends HandlerInterceptorAdapter {
    public boolean preHandle(
            HttpServletRequest request,
            HttpServletResponse response,
            Object handler) throws Exception {

          Authentication auth =  SecurityContextHolder.getContext().getAuthentication();
           List<GrantedAuthority> authorities = Lists.newArrayList();

           userDao.getAuthorities(authorities, user);

           // If contents of auth.getAuthorities() equals authorities then no need to re-set.
           Authentication newAuth = new  UsernamePasswordAuthenticationToken(auth.getPrincipal(), auth.getCredentials(),             authorities);
               SecurityContextHolder.getContext().setAuthentication(newAuth);

    }
}

暂无
暂无

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

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