【问题标题】:Acegi Security: How do i add another GrantedAuthority to Authentication to anonymous userAcegi Security:如何向匿名用户添加另一个 GrantedAuthority 到身份验证
【发布时间】:2010-09-21 23:35:45
【问题描述】:

我为用户提供带有访问密钥的特殊 URL。与简单的匿名用户相比,通过这个特殊 url 访问公共页面的用户应该能够看到一些额外的数据。

我想根据请求中提供的参数给匿名用户一些额外的角色,这样我就可以在我的模板中做这样的事情:

<@sec.authorize ifAnyGranted="ROLE_ADMIN, ROLE_USER, ROLE_INVITED_VISITOR">
...some additional stuff for invited user to see
</@sec.authorize>

目前我正在实现 Spring 的 OncePerRequestfilter:

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
    if (null != request.getParameter("accessKey")) {
        if(isValid(request.getParameter("accessKey"))) {
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            //how do i add additional roles to authenticated (potentially anonymous) user?
        }
    }
}

【问题讨论】:

    标签: spring-security roles anonymous


    【解决方案1】:

    为什么不直接创建一个委托给原始的包装类,而是添加几个额外的 GrantedAuthorities:

    public class AuthenticationWrapper implements Authentication
    {
       private Authentication original;
       private GrantedAuthority[] extraRoles;
    
       public AuthenticationWrapper( Authentication original, GrantedAuthority[] extraRoles )
       {
          this.original = original;
          this.extraRoles = extraRoles;
       }
    
       public GrantedAuthority[] getAuthorities()
       {
          GrantedAuthority[] originalRoles = original.getAuthorities();
          GrantedAuthority[]  roles = new GrantedAuthority[originalRoles.length + extraRoles.length];
          System.arraycopy( originalRoles, 0, roles, 0, originalRoles.length );
          System.arraycopy( extraRoles, 0, roles, originalRoles.length, extraRoles.length );
          return roles;
       }
    
       public String getName() { return original.getName(); }
       public Object getCredentials() { return original.getCredentials(); }
       public Object getDetails() { return original.getDetails(); }   
       public Object getPrincipal() { return original.getPrincipal(); }
       public boolean isAuthenticated() { return original.isAuthenticated(); }
       public void setAuthenticated( boolean isAuthenticated ) throws IllegalArgumentException
       {
          original.setAuthenticated( isAuthenticated );
       }  
    }
    

    然后在您的过滤器中执行此操作:

    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    GrantedAuthority extraRoles = new GrantedAuthority[2];
    extraRoles[0] = new GrantedAuthorityImpl( "Role X" );
    extraRoles[1] = new GrantedAuthorityImpl( "Role Y" );
    AuthenticationWrapper wrapper = new AuthenticationWrapper( auth, extraRoles );
    SecurityContextHolder.getContext().setAuthentication( wrapper );
    

    身份验证现在被您的版本替换为具有额外角色的版本。 NB 您可能必须处理尚未对 Authentication 进行身份验证的情况,因此其 getAuthorities() 返回 null。 (包装器实现当前假设它总是会从其包装的身份验证中获取一个非空数组)

    【讨论】:

    • 不错的一个!我自己通过创建一个具有其他角色的新 AnonymousAuthenticationToken 来解决它,但这更加优雅。谢谢
    猜你喜欢
    • 1970-01-01
    • 2014-08-09
    • 1970-01-01
    • 1970-01-01
    • 2010-10-01
    • 1970-01-01
    • 2019-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多