如何使用 Spring Security 在我的控制器中获取用户登录的角色

Posted

技术标签:

【中文标题】如何使用 Spring Security 在我的控制器中获取用户登录的角色【英文标题】:How to get the role that a user logged in with in my controller using Spring Security 【发布时间】:2015-05-19 23:08:12 【问题描述】:

我正在尝试为授权和身份验证实现 Spring 安全功能。我面临一些有关用户角色的问题。我希望在我的控制器中检查用户登录的角色,以便根据角色我可以将用户重定向到相应的页面(因为用户可以拥有多个角色)。但是,我没有在我的 Java 控制器中获得登录角色。

登录jsp页面

   <form action="<c:url value='j_spring_security_check'/>"
                method="POST" name='loginForm'>
 <table class="center">
 <tr><td>User Name:  </td><td><input type="text" name="j_username"  id="userName" ></td></tr>
 <tr><td>Password:  </td><td><input type="password" name="j_password" id="password"></td></tr> 
 <tr><td>Role: </td><td>
 <select id="role" name="j_role">  
 <option style="font-weight: bold;">Select Roll </option>
 <option id="role1" value="role1">Role 1</option>
 <option id="role2" value="role2">Role 2 </option>
 <option id="role3" value="role3">Role 3 </option>
 </select></td></tr>

 <tr><td><input type="submit" value="Login" style="height: 25px; width: 100px"></td><td><input type="reset" value="Reset" style="height: 25px; width: 100px"></td></tr>
 <tr><td colspan=2>&nbsp;</td></tr>

  <tr><td colspan=2></td></tr>
 </table>
 </form>

控制器代码:

@RequestMapping(value="/home", method = RequestMethod.GET)
 public ModelAndView printWelcome(ModelMap model, Principal principal ) throws SQLException 

     ModelAndView mav = new ModelAndView(); 
try
    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
     String n= auth.getName();
    String r= auth.getAuthorities().toString();

     System.out.println("the value of username is "+n);
    System.out.println("the value of role is  "+r);

     returning result
   

在这里,我得到了哪个用户已登录,并且我正在检索他们的角色,如我的 spring-security.xml 文件中所定义的那样 - 例如。 [角色 1,角色 2]。这不会检索用户登录时使用的角色。通过用户登录的用户名,我从数据库中获取角色并重定向到相应的页面。如果用户只有一个角色,它工作正常,但如果他们有多个角色,那么我不清楚我将如何重定向他们。所以,我认为一旦登录用户就可以选择角色,在此基础上我会重定向。

Spring-Security.xml

   <http auto-config="true"  use-expressions="true">
 <intercept-url pattern="/home" access="hasAnyRole('role1','role2','role3')"/>

<form-login login-page="/login" default-target-url="/home" authentication-failure-url="/loginError" />


</http>
<authentication-manager alias="authenticationManager">
    <authentication-provider>
        <user-service>

            <user name="user1" password="123" authorities="role1,role2" />   
      <user name="user2" password="123" authorities="role2,role3" />   
            <user name="stephen" password="123" authorities="role1" />
            <user name="robert" password="123" authorities="role3" />
        </user-service>
    </authentication-provider>
</authentication-manager>

每个角色都有不同的视图页面,所以如果我使用 user1 登录并从下拉列表中选择角色 2,我将如何在我的控制器中获取此角色 2,以便我可以将 user1 重定向到相应的 jsp 页面?

如果有更好的方法来实现这一点,请告诉我。

【问题讨论】:

【参考方案1】:

Authentication 注入您的控制器,而不是Principal

@RequestMapping(value="/home", method = RequestMethod.GET)
public ModelAndView printWelcome(ModelMap model, Authentication authentication) 

authentication.getAuthorities(); 现在将返回您的角色。

【讨论】:

我正在获得角色,但我得到的是他们在 spring-security.xml 中的内容,而不是用户登录的内容。我也越来越早了。请帮助我获得用户在登录时选择的角色 对于 user1,我将 r 设为 [role1, role2] 但 user1 已以 role2 身份登录【参考方案2】:

这是我在控制器中的解决方案。 我的项目默认有两个页面。一个页面是受欢迎的,其他页面默认是一个仪表板,只有当用户包含角色 ROLE DASHBOARD 时才能访问。

@RequestMapping(value="/redirectToPageDefault",method=RequestMethod.GET)
public ModelAndView redirectToPageDefault(SecurityContextHolder auth)
    Collection<?extends GrantedAuthority> granted = auth.getContext().getAuthentication().getAuthorities();
    String role;
    //set page default to rules common
    ModelAndView mav = new ModelAndView("empty");
    for(int i=0;i<granted.size();i++)
        role = granted.toArray()[i] + "";
        logger.info("role verified" + i + " is -> " + role);
        //verify if user contain role to view dashboard page default
        if(role.equals("ROLE_DASHBOARD"))
            logger.warn("IDENTIFIED: ROLE_DASHBOARD = " + role );
            mav.setViewName("dasboard");
                       
       
    return mav;

【讨论】:

【参考方案3】:

尝试以下 2 项之一: 1. 将 java.security.Principal 传递给您的任何 Controller 方法。 2.通过SecurityContextHolder.getContext().getAuthentication()获取登录用户

【讨论】:

我在我的控制器中做请检查。我正在获取用户名,用户输入的密码,但不是角色。 获得 Authentication 对象后,只需遍历 authentication.getAuthorities() 并获取您的角色。 我之前也在我的控制器中获得了角色,但就像 user1 使用角色 1 登录一样,我在 spring-security.xml 中获得的角色是 [role1,role2]。如果用户从登录页面的下拉列表中选择角色 1 登录,我不想要这个我应该将角色作为角色 1 这是我的问题? 不确定您是否以正确的方式使用角色。如果您正在为用户设置某些角色(如复数形式),则您正在为他/她分配某些特权。如果您只想让用户访问您网站的 1 个区域,那么只给用户一个角色。您可以做的另一件事是将您的角色设置为具有层次结构而不是平面结构。这样,用户将分配 1 个角色,但可以根据角色层次结构访问多个级别。【参考方案4】:

您可以通过此方法检查角色

private boolean hasRole(String role) 
  Collection<GrantedAuthority> authorities = (Collection<GrantedAuthority>)
  SecurityContextHolder.getContext().getAuthentication().getAuthorities();
  boolean hasRole = false;
  for (GrantedAuthority authority : authorities) 
     hasRole = authority.getAuthority().equals(role);
     if (hasRole) 
      break;
     
  
  return hasRole;
  

您还可以看到这篇文章: How to Access Roles and User Details Using Spring Security

【讨论】:

以上是关于如何使用 Spring Security 在我的控制器中获取用户登录的角色的主要内容,如果未能解决你的问题,请参考以下文章

如何在我的 Spring 4.0 RestFul Web 服务上实现 Spring Security?

如何在Spring Security中获取用户名(在我的情况下是电子邮件)[UserDetails / String]

如何配置 Spring Security 以允许在 JSP 页面中使用 hasPermission?

如何在 Spring Security 无状态(jwt 令牌)中注销用户?

如何使用自定义 JAAS 堆栈配置 Spring Security?

如何在我的 Spring Boot Security OAuth2 应用程序中仅为某些类启用 OAuth2?