如何在Java代码中检查用户权限或权限?例如,我想根据用户角色显示或隐藏按钮。有注释如:
@PreAuthorize("hasRole('ROLE_USER')")
如何在Java代码中实现?类似这样:
if(somethingHere.hasRole("ROLE_MANAGER")) {
layout.addComponent(new Button("Edit users"));
}
如何在Java代码中检查用户权限或权限?例如,我想根据用户角色显示或隐藏按钮。有注释如:
@PreAuthorize("hasRole('ROLE_USER')")
如何在Java代码中实现?类似这样:
if(somethingHere.hasRole("ROLE_MANAGER")) {
layout.addComponent(new Button("Edit users"));
}
public String createForm(HttpSession session, HttpServletRequest request, ModelMap modelMap) {
if (request.isUserInRole("ROLE_ADMIN")) {
// code here
}
}
Spring Security 3.0有这个API
SecurityContextHolderAwareRequestWrapper.isUserInRole(String role)
在你使用它之前,你需要注入这个包装器。
SecurityContextHolderAwareRequestWrapper
实例。你可以改进一下,解释一下如何获取它,并对答案本身进行更清晰的澄清。 - Aritzpublic String sampleMethod(SecurityContextHolderAwareRequestWrapper requestWrapper, Model model){
//方法代码
requestWrapper. isUserInRole("role");
}
- Dot Batch你可以不使用循环来从UserDetails中查找权限,而是可以这样做:
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
boolean authorized = authorities.contains(new SimpleGrantedAuthority("ROLE_ADMIN"));
您可以检索安全上下文,然后使用它:
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;
}
SecurityContextHolder.getContext()
永远不会是 NULL
,请查看文档。因此,您可以避免检查上下文是否为 NULL
。 - Imtiaz Shakil Siddique protected final boolean hasRole(String role) {
boolean hasRole = false;
UserDetails userDetails = getUserDetails();
if (userDetails != null) {
Collection<GrantedAuthority> authorities = userDetails.getAuthorities();
if (isRolePresent(authorities, role)) {
hasRole = true;
}
}
return hasRole;
}
/**
* Get info about currently logged in user
* @return UserDetails if found in the context, null otherwise
*/
protected UserDetails getUserDetails() {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
UserDetails userDetails = null;
if (principal instanceof UserDetails) {
userDetails = (UserDetails) principal;
}
return userDetails;
}
/**
* Check if a role is present in the authorities of current user
* @param authorities all authorities assigned to current user
* @param role required authority
* @return true if role is present in list of authorities assigned to current user, false otherwise
*/
private boolean isRolePresent(Collection<GrantedAuthority> authorities, String role) {
boolean isRolePresent = false;
for (GrantedAuthority grantedAuthority : authorities) {
isRolePresent = grantedAuthority.getAuthority().equals(role);
if (isRolePresent) break;
}
return isRolePresent;
}
SecurityContextHolder.getContext().getAuthentication()
可能会检索到 null
。你可以添加一些检查吗? - Mrusful我正在使用这个:
@RequestMapping(method = RequestMethod.GET)
public void welcome(SecurityContextHolderAwareRequestWrapper request) {
boolean b = request.isUserInRole("ROLE_ADMIN");
System.out.println("ROLE_ADMIN=" + b);
boolean c = request.isUserInRole("ROLE_USER");
System.out.println("ROLE_USER=" + c);
}
您可以从AuthorityUtils类中获取一些帮助。 检查角色只需要一行代码:
if (AuthorityUtils.authorityListToSet(SecurityContextHolder.getContext().getAuthentication().getAuthorities()).contains("ROLE_MANAGER")) {
/* ... */
}
因此,如果已经配置了角色前缀,则合适的角色检查需要尊重该前缀。
不幸的是,Spring 中的角色前缀自定义有点复杂,在许多地方,默认前缀 ROLE_
是硬编码的,但除此之外,Spring 上下文中会检查类型为 GrantedAuthorityDefaults
的 Bean,如果存在,它就会尊重它所具有的自定义角色前缀。
将所有这些信息汇集起来,更好的角色检查实现应该像这样:
@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);
}
}
@PreAuthorize("hasAuthority('ROLE_user')")
@PreAuthorize("hasRole('user')")
然后,您可以在Java代码中获得该角色。
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_user"))){
System.out.println("user role2");
}
JoseK的答案不能用于服务层,因为您不希望通过引用HTTP请求来引入与Web层的耦合。如果您想在服务层解决角色问题,那么Gopi的答案是正确的方法。
然而,这有点冗长。权限可以直接从身份验证中访问。因此,如果您可以假设已经有用户登录,那么可以使用以下代码:
/**
* @return true if the user has one of the specified roles.
*/
protected boolean hasRole(String[] roles) {
boolean result = false;
for (GrantedAuthority authority : SecurityContextHolder.getContext().getAuthentication().getAuthorities()) {
String userRole = authority.getAuthority();
for (String role : roles) {
if (role.equals(userRole)) {
result = true;
break;
}
}
if (result) {
break;
}
}
return result;
}
((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest()
获取请求怎么样? :) - Petr Újezdský