Spring Security:如何向经过身份验证的用户添加额外的角色

Posted

技术标签:

【中文标题】Spring Security:如何向经过身份验证的用户添加额外的角色【英文标题】:Spring Security: How To add extra role to authenticated user 【发布时间】:2012-01-13 03:02:52 【问题描述】:

我有一个与 REST 服务和 Spring Security 配合使用的应用程序。我有基本身份验证,需要硬登录和软登录。

场景是:当用户登录时,他被分配了 ROLE_SOFT 并且可以访问需要 ROLE_SOFT 的 URL,但是如果他想访问需要 ROLE_HARD 的 URL,他必须向指定的 Web 服务发送一些代码或一些东西。

所以我读了这个 Acegi Security: How do i add another GrantedAuthority to Authentication to anonymous user

之后我创建了我的:

public class AuthenticationWrapper implements Authentication

   private Authentication original;

   public AuthenticationWrapper(Authentication original)
   
      this.original = original;
   


   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 );
   

public Collection<? extends GrantedAuthority> getAuthorities() 
    System.out.println("EXISTING ROLES:");
    System.out.println("Size=:"+original.getAuthorities().size());
    for (GrantedAuthority iterable : original.getAuthorities()) 

        System.out.println(iterable.getAuthority());
    

    GrantedAuthority newrole = new SimpleGrantedAuthority("ROLE_HARD");
    System.out.println("ADD new ROLE:"+newrole.getAuthority());
    Collection<? extends GrantedAuthority> originalRoles = original.getAuthorities();

     ArrayList<GrantedAuthority> temp = new ArrayList<GrantedAuthority>(originalRoles.size()+1);
     temp.addAll(originalRoles);
     temp.add(newrole); 
     System.out.println("RETURN NEW LIST SIZE"+temp.size());
     for (GrantedAuthority grantedAuthority : temp) 
        System.out.println("NEW ROLES:"+grantedAuthority.getAuthority());
    

    return Collections.unmodifiableList(temp);

和控制器

@Controller
@RequestMapping("/login")
public class LoginControllerImpl implements LoginController 


    LoginService loginService;


    @RequestMapping(method = RequestMethod.GET, headers = "Accept=application/json")
    @ResponseBody
    public User getUserSettings()
        loginService=new LoginServiceImpl();
        Authentication auth =   SecurityContextHolder.getContext().getAuthentication();
        AuthenticationWrapper wrapper = new AuthenticationWrapper(auth);
        SecurityContextHolder.getContext().setAuthentication( wrapper );

        return loginService.getUser();
    



但是在我更改身份验证后,我的会话停止了.. 也许有人知道更好的解决方案...

【问题讨论】:

【参考方案1】:

只是一个想法.. 如果用户第一次使用登录表单登录并需要访问需要额外权限的资源,那么为什么不第二次将用户重定向回登录页面呢?

    <http auto-config="true" use-expressions="true">
                <intercept-url pattern="/resources/**" access="denyAll"/>
                <intercept-url pattern="/login.do" access="permitAll"/>
                <intercept-url pattern="/role_soft_url_domain/* " access="hasRole('ROLE_SOFT') and fullyAuthenticated"/>
                <intercept-url pattern="/role_hard_url_domain/*" access="hasRole('ROLE_HARD') and fullyAuthenticated"/>             
                <intercept-url pattern="/*" access="hasRole('ROLE_SOFT')"/>
                <form-login login-page="/login.do" />               
                <logout invalidate-session="true"
                    logout-success-url="/"
                    logout-url="/j_spring_security_logout"/>
                </http>

【讨论】:

以上是关于Spring Security:如何向经过身份验证的用户添加额外的角色的主要内容,如果未能解决你的问题,请参考以下文章

如何在 spring-security-oauth 中获取经过身份验证的用户

Spring-Security:优化获取当前经过身份验证的用户...

JAX-RS 和 Spring Security - 获取经过身份验证的用户

Spring security + JWT + 经过身份验证并且 hasRole 不起作用?

重启后 Spring Security 仍然经过身份验证(但没有会话)

具有角色的经过身份验证的用户的 Spring Security Java 配置