36

I have loaded the roles from the database for the current user. And I can access the user role with spring security expression in JSP, and can hide the options and URLs which are not authorized with hasRole. Now I wanted to have it in the servlet and display it in the logs (or store in the user object session). How can we achieve it?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Bhas
  • 875
  • 3
  • 10
  • 12

6 Answers6

83

You can try something like this:

Collection<SimpleGrantedAuthority> authorities = (Collection<SimpleGrantedAuthority>)    SecurityContextHolder.getContext().getAuthentication().getAuthorities();

You have the collection of roles in the authorities variable.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Dani
  • 3,744
  • 4
  • 27
  • 35
  • 4
    you should use the grantedauthority interface in this list as the implementation can differ between authoritization providers – Laures Apr 11 '12 at 05:26
  • 4
    If you do this there will be an unchecked case but you can avoid this by having the collection type as: Collection extends GrantedAuthority> – Stuart Paton Jan 25 '16 at 11:42
44

If you develop on Java 8, it's getting easier.

To get all user roles:

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

Set<String> roles = authentication.getAuthorities().stream()
     .map(r -> r.getAuthority()).collect(Collectors.toSet());

To check if the user has a particular role, for example, ROLE_USER:

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

boolean hasUserRole = authentication.getAuthorities().stream()
          .anyMatch(r -> r.getAuthority().equals("ROLE_USER"));
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Bogusz
  • 476
  • 4
  • 5
  • 1
    I tried your solution but It is getting the value from "authorties" , not the "role" and my code is: auth.jdbcAuthentication() .dataSource(dataSource).passwordEncoder(enc) .authoritiesByUsernameQuery("select USERNAME, role, authorities from vwuserrole where USERNAME=?") .usersByUsernameQuery("select USERNAME, PASSWORD, 1 as enabled from vwuser where USERNAME=?") I don't understand how authorities and role should be manipulated. – RAY Oct 01 '19 at 16:27
  • Ok, I searched and find the answer here: https://stackoverflow.com/questions/19525380/difference-between-role-and-grantedauthority-in-spring-security But I still puzzled why the role value is empty. with the query I put. – RAY Oct 01 '19 at 17:01
7

Try to call getUserPrincipal() from HttpServletRequest.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
maximdim
  • 8,041
  • 3
  • 33
  • 48
  • Thanks for the response, i didn't try it, but i have implemented what Dani told, it worked for me. – Bhas Apr 10 '12 at 19:36
  • 7
    Fair enough. Juts a quick note: Dani's approach have drawback of coupling your code with Spring security implementation while getUserPricipal() is standard call in servlet specification and should work with any provider. – maximdim Apr 10 '12 at 20:37
  • 3
    With getUserPrincipal() you only get the name of the requestor. I think question is how to get the roles assigned to that user, so I guess in getUserPrincipal() wont work that way also. – Jay Jul 13 '15 at 14:07
  • HttpServletRequest is applicable to a web module only. – no id Jul 25 '16 at 07:20
4

I've created a custom hasRole function for my project.

public static boolean hasRole (String roleName)
{
    return SecurityContextHolder.getContext().getAuthentication().getAuthorities().stream()
            .anyMatch(grantedAuthority -> grantedAuthority.getAuthority().equals(roleName));
}
Sebastian Ullrich
  • 1,007
  • 11
  • 21
2

To complete both answers...

Here is a Spring security implementation of getUserPrincipal, so you can see that the getUserPrincipal actually is SecurityContextHolder

public Principal getUserPrincipal() {
    Authentication auth = getAuthentication();

    if ((auth == null) || (auth.getPrincipal() == null)) {
        return null;
    }
    return auth;
}

// And the getAuthentication
private Authentication getAuthentication() {
    Authentication auth = SecurityContextHolder.getContext().getAuthentication();

    if (!trustResolver.isAnonymous(auth)) {
        return auth;
    }
    return null;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Alireza Fattahi
  • 42,517
  • 14
  • 123
  • 173
0

This may help someone.

import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.ui.Model;
import org.springframework.security.core.userdetails.User;
    
    @GetMapping("/home")
    public String getHomePage(Authentication authentication, Model model) {
        User u = (User) authentication.getPrincipal();
        model.addAttribute("cu", u);
        return "sb/homePage";
    }

And in template Thymeleaf:

Current user:</br>
    <div th:if="${cu}">
        Username: [[${cu.username}]]</br>
        Password: [[${cu.password}]]</br>
        Role: [[${cu.authorities[0]}]]</br>
        Enabled: [[${cu.enabled}]]</br>
        Full: [[${cu}]]</br>
    </div>
    <div th:unless="${cu}">
        Not logged-in!
    </div>
Sudhakar Krishnan
  • 732
  • 1
  • 8
  • 27