How to get the role that a user logged in with in my controller using Spring Security

21,013

Solution 1

Inject an Authentication into your Controller, rather than Principal.

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

authentication.getAuthorities(); will now return your roles.

Solution 2

This is my solution in controller. My project there are two pages default. A page is welcome, and other page default is a dashboard where access only if the user contain role 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;
}

Solution 3

Try one of the below 2:
1. Pass java.security.Principal to any of your Controller methods.
2. Get logged in user via SecurityContextHolder.getContext().getAuthentication()

Solution 4

You can ckeck the roles by this method

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

Also you can see this article: How to Access Roles and User Details Using Spring Security

Share:
21,013
user07
Author by

user07

Updated on July 05, 2022

Comments

  • user07
    user07 almost 2 years

    I am trying to implement Spring security features for authorization and authentication. I am facing some issues regarding user roles. I want the role the user has logged in with to be checked in my controller, so that on the basis of the role I can redirect the user to the respective page (as a user canhave more than one role). However, I am not getting the logged in role in my Java controller.

    login jsp page

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

    Controller code :

    @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
      } 
    }
    

    Here I am getting which user has logged in and also I'm retrieving their roles, as defined in my spring-security.xml file - e.g. [role1 , role2]. This doesn't retrieve the role by which user has logged in with. Through the user name that the user has logged in with I then get the role from the database and redirect to the respective page. It works fine if user has only one role, but if they have more than one role then I am not clear how I will redirect them. So, I thought once logged in the user can select role and on that basis I will redirect.

    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>
    

    Each role has different view pages, so if I login with user1 and from dropdown I select role2 how will I get this role2 in my controller so that I can redirect the user1 to respective jsp page?

    If there is a better way to achieve this please let me know.