Spring Security를 사용하여 Java 코드에서 "hasRole"을 확인하는 방법
Java Code에서 사용자 권한 또는 권한을 확인하는 방법? 예를 들어 역할에 따라 사용자에 대한 버튼을 표시하거나 숨깁니다.다음과 같은 주석이 있습니다.
@PreAuthorize("hasRole('ROLE_USER')")
자바 코드로 만드는 방법?예를 들어 다음과 같습니다.
if(somethingHere.hasRole("ROLE_MANAGER")) {
layout.addComponent(new Button("Edit users"));
}
HttpServletRequest 객체의 isUserInRole 메서드를 사용할 수 있습니다.
예를 들어 다음과 같습니다.
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)
사용하기 전에 포장지를 주사해야 합니다.
Security Context Holder Aware Request Wrapper
루프를 사용하여 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")) {
/* ... */
}
주의: 역할 계층이 존재하는 경우 이 작업은 확인하지 않습니다.
대부분의 답변에는 몇 가지 요점이 누락되어 있습니다.
봄에는 역할과 권위가 같지 않다.자세한 내용은 여기를 참조하십시오.
은 음음음 role role are are role role role role role role role role 。
rolePrefix
+authority
.는 "Default Role Prefix" 입니다.
ROLE_
단, 설정 가능합니다.여기 보세요.
따라서 역할 프레픽스가 설정되어 있는 경우 적절한 역할체크를 실시할 필요가 있습니다.
기본 프레픽스인 "Default Prefix"는 "Default prefix는 "Default prefix"입니다.ROLE_
되어 그 에 타입의 빈, 타입의 빈, 타입의 빈, 타입의 빈, 타입의 있습니다.GrantedAuthorityDefaults
는 Spring 컨텍스트에서 체크되며, 이 컨텍스트가 존재하는 경우 해당 컨텍스트에 있는 커스텀롤 프리픽스가 존중됩니다.
이러한 모든 정보를 종합하면 다음과 같은 롤 체커의 구현이 효율화됩니다.
@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);
}
}
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;
}
아래 두 개의 주석은 동일합니다. "hasRole"은 접두사 "ROLE_"을 자동으로 추가합니다.올바른 주석이 있는지 확인하십시오.이 역할은 UserDetailsService#loadUserByUsername으로 설정됩니다.
@PreAuthorize("hasAuthority('ROLE_user')")
@PreAuthorize("hasRole('user')")
그러면 자바 코드에서 역할을 얻을 수 있습니다.
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_user"))){
System.out.println("user role2");
}
이것은 반대쪽에서 온 질문이지만, 이것을 알아내기 위해 인터넷을 검색해야 했기 때문에 나는 그것을 던져버리고 싶었다.
역할을 확인하는 방법은 많지만 실제로 확인하는 내용은 has Role('blah')이라고 할 때 많이 말하지 않습니다.
HasRole은 현재 인증된 주체에 대해 부여된 권한을 확인합니다.
has Role ("blah")는 has Authority ("blah")를 의미합니다.
적이 있는 는, 「이 작업을 이 클래스는 get 「Implements User Details」라고 불리는 합니다.이에는 기본적으로 몇 가지 더 해요.new SimpleGrantedAuthority("some name")
어떤 논리에 근거한 목록으로 이동합니다.에는 has Role이 있습니다.
이 컨텍스트에서 UserDetails 객체는 현재 인증된 주체입니다.인증 프로바이더, 특히 이를 실현하는 인증 매니저에서는 몇 가지 마법이 발생합니다.
이상하게도 스프링 보안 접근컨트롤은 자바 베이스가 아닌 표현 베이스이기 때문에 이 문제에 대한 표준적인 해결책은 없다고 생각합니다.소스 코드에서 DefaultMethodSecurity를 확인할 수 있습니다.Expression Handler에서 그들이 하고 있는 것을 재사용할 수 있는지 확인합니다.
이 프로젝트에서는 역할 계층을 사용하고 있지만, 위의 답변의 대부분은 특정 역할만 확인하는 것을 목적으로 하고 있습니다.즉, 주어진 역할만 확인하는 것일 뿐 해당 역할과 계층 위는 확인하지 않습니다.
이를 위한 솔루션:
@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;
}
Role Hierarchy는 spring-security.xml의 빈으로 정의되어 있습니다.
늦더라도 안하는 것보다는 낫지, 내 2센트어치를 넣을게.
JSF 월드에서 관리 대상 빈에서 다음을 수행했습니다.
HttpServletRequest req = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
SecurityContextHolderAwareRequestWrapper sc = new SecurityContextHolderAwareRequestWrapper(req, "");
위에서 설명한 바와 같이, 다음과 같이 긴 시간 동안 할 수 있는 것으로 알고 있습니다.
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
UserDetails userDetails = null;
if (principal instanceof UserDetails) {
userDetails = (UserDetails) principal;
Collection authorities = userDetails.getAuthorities();
}
@gouki가 제일 좋아!
봄이 진짜 어떻게 하는지 보여주는 단서일 뿐이야.
라는 이름의 클래스가 있다.SecurityContextHolderAwareRequestWrapper
'하다'를 시행하고 있습니다.ServletRequestWrapper
SecurityContextHolderAwareRequestWrapper
무시하다isUserInRole
검색 " " " "Authentication
(스프링에 의해 관리됨)을 사용하여 사용자에게 역할이 있는지 여부를 확인합니다.
SecurityContextHolderAwareRequestWrapper
을 사용하다
@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;
}
사용자 역할은 다음 방법으로 확인할 수 있습니다.
SecurityContextHolder에서 콜 스태틱 메서드를 사용하는 경우:
Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null && auth.getAuthorities().stream().anyMatch(role -> role.getAuthority().equals("ROLE_NAME"))) { //do something}
Http Servlet Request 사용
@GetMapping("/users")
public String getUsers(HttpServletRequest request) {
if (request.isUserInRole("ROLE_NAME")) {
}
사용자 모델에 다음과 같은 'hasRole' 메서드를 추가합니다.
public boolean hasRole(String auth) {
for (Role role : roles) {
if (role.getName().equals(auth)) { return true; }
}
return false;
}
보통 인증된 사용자가 관리자 역할을 가지고 있는지 확인하기 위해 사용합니다.
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
Java8을 사용한 My 어프로치, 혼수상태의 역할 분리를 통해 참 또는 거짓을 알 수 있습니다.
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;
}
주석을 사용할 수 있습니다.@Secured
또는@RolesAllowed
또는@PreAuthorise
/@PostAuthorise
스프링 보안에서요
주의:이 코드를 추가해야 합니다.
@Configuration
@EnableGlobalMethodSecurity(
securedEnabled = true,
jsr250Enabled = true,
prePostEnabled = true
)
public class MyConfig extends WebSecurityConfigurerAdapter{
}
configure 클래스 앞에 있습니다.3개의 파라미터를 모두 사용할 필요는 없습니다.securedEnabled
,jsr250Enabled
,prePostEnabled
. 사용하려는 주석에 따라 하나만 필요합니다.
그런 다음 컨트롤러 클래스에 역할 확인 주석을 추가합니다.
@Secured("ROLE_admin")
@GetMapping("/hello")
public String hello(){
return "hello";
}
또는
@RolesAllowed("ROLE_admin")
@GetMapping("/hello")
public String hello(){
return "hello";
}
또는
@PreAuthorize("hasRole('ROLE_user')")
@GetMapping("/hello")
public String hello(){
return "hello";
}
여기 튜토리얼이 있습니다.https://www.baeldung.com/spring-security-method-security
언급URL : https://stackoverflow.com/questions/3021200/how-to-check-hasrole-in-java-code-with-spring-security
'sourcecode' 카테고리의 다른 글
Java Enum 메서드 - 반대 방향 열거를 반환합니다. (0) | 2023.01.10 |
---|---|
Stripe() 값이 잘못되었습니다.apiKey는 문자열이어야 합니다.지정한: 정의되지 않음 (0) | 2023.01.10 |
Java - SQL 주입을 방지하는 이스케이프 문자열 (0) | 2023.01.10 |
MySQL에서 Lock wait timeout exceededed를 디버깅하는 방법 (0) | 2023.01.10 |
MySQL의 외부 키 기본 사항 (0) | 2023.01.10 |