How to check user authority or permission in Java Code ? For example - I want to show or hide button for user depending on role. There are annotations like:
User Roles can be checked using following ways:
Using call static methods in SecurityContextHolder:
Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null && auth.getAuthorities().stream().anyMatch(role -> role.getAuthority().equals("ROLE_NAME"))) { //do something}
Using HttpServletRequest
@GetMapping("/users")
public String getUsers(HttpServletRequest request) {
if (request.isUserInRole("ROLE_NAME")) {
}
Strangely enough, I don't think there is a standard solution to this problem, as the spring-security access control is expression based, not java-based. you might check the source code for DefaultMethodSecurityExpressionHandler to see if you can re-use something they are doing there
Most answers are missing some points:
Role and authority are not the same thing in Spring. See here for more details.
Role names are equal to rolePrefix
+ authority
.
The default role prefix is ROLE_
, however, it is configurable. See here.
Therefore, a proper role check needs to respect the role prefix if it is configured.
Unfortunately, the role prefix customization in Spring is a bit hacky, in many places the default prefix, ROLE_
is hardcoded, but in addition to that, a bean of type GrantedAuthorityDefaults
is checked in the Spring context, and if it exists, the custom role prefix it has is respected.
Bringing all this information together, a better role checker implementation would be something like:
@Component
public class RoleChecker {
@Autowired(required = false)
private GrantedAuthorityDefaults grantedAuthorityDefaults;
public boolean hasRole(String role) {
String rolePrefix = grantedAuthorityDefaults != null ? grantedAuthorityDefaults.getRolePrefix() : "ROLE_";
return Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication())
.map(Authentication::getAuthorities)
.map(Collection::stream)
.orElse(Stream.empty())
.map(GrantedAuthority::getAuthority)
.map(authority -> rolePrefix + authority)
.anyMatch(role::equals);
}
}
My Approach with the help of Java8 , Passing coma separated roles will give you true or false
public static Boolean hasAnyPermission(String permissions){
Boolean result = false;
if(permissions != null && !permissions.isEmpty()){
String[] rolesArray = permissions.split(",");
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
for (String role : rolesArray) {
boolean hasUserRole = authentication.getAuthorities().stream().anyMatch(r -> r.getAuthority().equals(role));
if (hasUserRole) {
result = true;
break;
}
}
}
return result;
}
You can retrieve the security context and then use that:
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
protected boolean hasRole(String role) {
// get security context from thread local
SecurityContext context = SecurityContextHolder.getContext();
if (context == null)
return false;
Authentication authentication = context.getAuthentication();
if (authentication == null)
return false;
for (GrantedAuthority auth : authentication.getAuthorities()) {
if (role.equals(auth.getAuthority()))
return true;
}
return false;
}
You can get some help from AuthorityUtils class. Checking role as a one-liner:
if (AuthorityUtils.authorityListToSet(SecurityContextHolder.getContext().getAuthentication().getAuthorities()).contains("ROLE_MANAGER")) {
/* ... */
}
Caveat: This does not check role hierarchy, if such exists.