Get a User's Authorities Based on the Current Request URI

Andrew Lalis :

I want to have the ability to grant different authorities to users depending on which resource they're attempting to access. Of course, I could do this by implementing logic in each of the relevant controllers, but I would really like to take advantage of the Thymeleaf security extras in my templates, as well as Spring's @PreAuthorize() annotations.

As of right now I am using a simple implementation of a UserDetails to provide a list of granted authorities from some models in a database:

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
    return this.userAccount.getRoles().stream()
            .map(role -> new SimpleGrantedAuthority(role.getName()))
            .collect(Collectors.toList());
}

However, I want behavior that can do the following:

User requests /courses/1. They're a student in that course, so they get these roles: (...)

User requests /courses/2. They're an admin in that course, so they get these roles: (...)

The problem is that Spring's UserDetailService and UserDetails interfaces don't allow for auto-wiring the context's current request anywhere, as far as I can see. Is there any way that this can be done? Ideally I'd just want access to the HttpServletRequest. Something like this:

@Override
public Collection<? extends GrantedAuthority> getAuthorities(HttpServetRequest request) {
    return this.userAccount.getRolesForURI(request.getURI()).stream()
            .map(role -> new SimpleGrantedAuthority(role.getName()))
            .collect(Collectors.toList());
}
Marco Behler :

You can simply @Autowire the HttpServletRequest into your UserDetailsService.

 @Autowired
 private HttpServletRequest request;

For it to work you might need to register a RequestContextListener.

@Bean 
public RequestContextListener requestContextListener(){
    return new RequestContextListener();
} 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=352967&siteId=1