Spring Security를 사용하여 Java 코드에서 "hasRole"을 확인하는 방법은 무엇입니까?
Java 코드에서 사용자 권한 또는 권한을 확인하는 방법은 무엇입니까? 예를 들어-역할에 따라 사용자의 버튼을 표시하거나 숨기고 싶습니다. 다음과 같은 주석이 있습니다.
@PreAuthorize("hasRole('ROLE_USER')")
Java 코드로 만드는 방법? 같은 것 :
if(somethingHere.hasRole("ROLE_MANAGER")) {
layout.addComponent(new Button("Edit users"));
}
Spring Security 3.0에는이 API가 있습니다
SecurityContextHolderAwareRequestWrapper.isUserInRole(String role)
랩퍼를 사용하기 전에 주입해야합니다.
SecurityContextHolderAwareRequestWrapper
HttpServletRequest 객체의 isUserInRole 메서드를 사용할 수 있습니다.
같은 :
public String createForm(HttpSession session, HttpServletRequest request, ModelMap modelMap) {
if (request.isUserInRole("ROLE_ADMIN")) {
// code here
}
}
루프를 사용하여 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;
}
아래와 같이 hasRole () 메소드를 구현할 수 있습니다-(이것은 다른 버전에 대해서는 확실하지 않은 스프링 보안 3.0.x에서 테스트되었습니다.)
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;
}
나는 이것을 사용하고있다 :
@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")) {
/* ... */
}
주의 사항 : 역할 계층이 존재하는 경우이를 확인하지 않습니다.
서비스 계층에있을 때 JoseK의 답변을 사용할 수 없습니다. 서비스 계층에서는 참조에서 HTTP 요청까지 웹 계층과의 연결을 도입하고 싶지 않습니다. 서비스 계층에있는 동안 역할을 해결하려는 경우 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;
}
대부분의 답변에는 몇 가지 요점이 없습니다.
스프링의 역할과 권한은 동일하지 않습니다. 자세한 내용은 여기를 참조 하십시오.
역할 이름은
rolePrefix
+authority
입니다.
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);
}
}
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
Better late then never, let me put in my 2 cents worth.
In JSF world, within my managed bean, I did the following:
HttpServletRequest req = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
SecurityContextHolderAwareRequestWrapper sc = new SecurityContextHolderAwareRequestWrapper(req, "");
As mentioned above, my understanding is that it can be done the long winded way as followed:
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
UserDetails userDetails = null;
if (principal instanceof UserDetails) {
userDetails = (UserDetails) principal;
Collection authorities = userDetails.getAuthorities();
}
The @gouki answer is best!
Just a tip of how spring really do this.
There is a class named SecurityContextHolderAwareRequestWrapper
which implements the ServletRequestWrapper
class.
The SecurityContextHolderAwareRequestWrapper
overrides the isUserInRole
and search user Authentication
(which is managed by Spring) to find if user has a role or not.
SecurityContextHolderAwareRequestWrapper
the code is as:
@Override
public boolean isUserInRole(String role) {
return isGranted(role);
}
private boolean isGranted(String role) {
Authentication auth = getAuthentication();
if( rolePrefix != null ) {
role = rolePrefix + role;
}
if ((auth == null) || (auth.getPrincipal() == null)) {
return false;
}
Collection<? extends GrantedAuthority> authorities = auth.getAuthorities();
if (authorities == null) {
return false;
}
//This is the loop which do actual search
for (GrantedAuthority grantedAuthority : authorities) {
if (role.equals(grantedAuthority.getAuthority())) {
return true;
}
}
return false;
}
This two annotation below is equal, "hasRole" will auto add prefix "ROLE_". Make sure you have the right annotation. This role is set in UserDetailsService#loadUserByUsername.
@PreAuthorize("hasAuthority('ROLE_user')")
@PreAuthorize("hasRole('user')")
then, you can get the role in java code.
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_user"))){
System.out.println("user role2");
}
This is sort of coming at the question from the other end but I thought I'd throw it in as I really had to dig on the internet to find this out.
There is a lot of stuff about how to check roles but not much saying what you are actually checking when you say hasRole("blah")
HasRole checks the granted authorities for the currently authenticated principal
So really when you see hasRole("blah") really means hasAuthority("blah").
In the case I've seen, you do this with a class that Implements UserDetails which defines a method called getAuthorities. In this you'll basically add some new SimpleGrantedAuthority("some name")
to a list based on some logic. The names in this list are the things checked by the hasRole statements.
I guess in this context the UserDetails object is the currently authenticated principal. There's some magic that happens in and around authentication providers and more specifically the authentication-manager that makes this happen.
In our project, we are using a role hierarchy, while most of the above answers only aim at checking for a specific role, i.e. would only check for the role given, but not for that role and up the hierarchy.
A solution for this:
@Component
public class SpringRoleEvaluator {
@Resource(name="roleHierarchy")
private RoleHierarchy roleHierarchy;
public boolean hasRole(String role) {
UserDetails dt = AuthenticationUtils.getSessionUserDetails();
for (GrantedAuthority auth: roleHierarchy.getReachableGrantedAuthorities(dt.getAuthorities())) {
if (auth.toString().equals("ROLE_"+role)) {
return true;
}
}
return false;
}
RoleHierarchy is defined as a bean in spring-security.xml.
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;
}
On your user model just add a 'hasRole' method like below
public boolean hasRole(String auth) {
for (Role role : roles) {
if (role.getName().equals(auth)) { return true; }
}
return false;
}
I usually use it to check if the authenticated user has the role admin as follows
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); // This gets the authentication
User authUser = (User) authentication.getPrincipal(); // This gets the logged in user
authUser.hasRole("ROLE_ADMIN") // This returns true or false
참고URL : https://stackoverflow.com/questions/3021200/how-to-check-hasrole-in-java-code-with-spring-security
'program tip' 카테고리의 다른 글
INNER JOIN으로 SQL 삭제 (0) | 2020.07.25 |
---|---|
Apache HttpClient 4.0에서 SSL 인증서 오류를 무시하는 방법 (0) | 2020.07.24 |
Ratingbar의 크기를 어떻게 줄일 수 있습니까? (0) | 2020.07.24 |
XDebug를 비활성화하는 방법 (0) | 2020.07.24 |
Javascript / jQuery에서 두 숫자를 포함하여 모든 정수의 배열을 만듭니다. (0) | 2020.07.24 |