- springboot
- @transactional
- DI
- Docker
- 자바
- Django
- spring boot
- Git
- spring
- AWS
- mysql
- 스프링부트
- SSL
- session
- 스프링
- ORM
- nginx
- spring security 6
- string
- jpa
- 1차원 배열
- 문자열
- select
- java
- join
- spring mvc
- sql
- 데이터베이스
- 프로그래머스
- PYTHON
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
개발하는 자몽
[Spring Security] GrantedAuthority, SimpleGrantedAuthority 본문
GrantedAuthority
스프링 공식문서는 GrantedAuthority를 아래와 같이 설명하고 있다.
Represents an authority granted to an Authentication object
(이 글의 Authentication은 인터페이스이다. AuthenticationManager.authenticate 메소드에서 요청을 처리한 후 authenticated principal 또는 인증 요청에 대한 토큰을 나타낸다. (나는 '나타낸다'로 하면 헷갈려서 '토큰의 정보를 갖고있다'로 해석한다))
GrantedAuthority는 인터페이스로 Authentication에 부여한 권한을 나타낸다. Authentication에는 User(사용자)정보가 있어야 한다. 그리고 User 객체의 타입은 UserDetails 객체여야 한다. (이전 포스트 참고 : 2023.01.03 - [Spring] - [Spring Security] UserDetails, UserDetailsService)
(직역인 'Authentication에 부여한 권한을 나타낸다' 보다는 'Authentication이 갖고 있는 권한을 나타낸다'이 더 자연스러운 것 같다. '갖고 있다'라고 한 이유는 위에서 Authentication은 token의 정보를 갖고 있다 했기 때문이다. 즉 이 토큰이 가진 권한을 나타낸다고 볼 수 있다)
궁금했던 부분
공부하면서 GrantedAuthority와 Role의 차이점이 궁금했다. GrantedAuthority가 무엇인지 검색해보니 스택 오버플로우에서 비슷한 질문이 있었다. 채택된 답변을 여기에 적어보자.
GrantedAuthority를 정말 "권한(permission / right)"으로만 생각해보자. 이 "권한"은 보통 getAuthority() 메소드로 String으로 표현된다.이 String으로 사용자의 권한을 확인할 수 있고, 권한을 부여하는 사람은 어떤 것에 대한 접근 권한을 부여할지 말지 결정할 수 있다.
우리는 Security Context에 사용자를 넣어서 여러 가지 권한(GrantedAuthority)을 부여할 수 있다. 보통 우리가 구현한 UserDetailsService로 이를 처리할 수 있다. (UserDetailsServices는 UserDetails를 반환하고, UserDetails는 필요한 GrantedAuthorities를 반환한다)
Role는 역할이 접두사 ROLE_로 시작하는 GrantedAuthority라는 네이밍 컨벤션이 있는 "권한(GrantedAuthority)"일뿐이다. SpringSecurity를 다루는 많은 곳에서 ROLE_로 시작하는 role을 정말 많이 본다. 이는 우리에게 접두사 ROLE_ 없이도 역할의 이름을 제공할 수 있도록 한다. 스프링 시큐리티 4 이전에는 Role에 대한 특별한 취급은 일관성 있게 지켜지지 않았고 Authority와 Role은 주로 동일하게 취급되었다. 스프링 시큐리티 4부터는 Role을 일관성있게 취급하고, 역할(Role)을 다루는 코드도 ROLE_을 항상 추가했다. 따라서 ROLE_ 자동으로 추가되기 때문에 hasAuthority('ROLE_ADMIN')는 hasRole('ADMIN')과 동일한 의미를 갖는다.
그래도 Role은 ROLE_이라는 특별한 접두사가 붙은 권한일 뿐이다.
@Getter
public enum UserRole {
ADMIN("ROLE_ADMIN"),
USER("ROLE_USER");
private String value;
UserRole(String value) {
this.value = value;
}
}
@RequiredArgsConstructor
@Service
public class UserSecurityService implements UserDetailsService {
private final UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Optional<SiteUser> userOptional = userRepository.findByUsername(username);
SiteUser user = userOptional.orElseThrow(() -> {
throw new UsernameNotFoundException("사용자를 찾을 수 없습니다.");
});
List<GrantedAuthority> authorities = new ArrayList<>();
if ("admin".equals(username)) { //ADMIN 권한 부여
authorities.add(new SimpleGrantedAuthority(UserRole.ADMIN.getValue()));
} else { //USER 권한 부여
authorities.add(new SimpleGrantedAuthority(UserRole.USER.getValue()));
}
return new User(user.getUsername(), user.getPassword(), authorities);
}
}
번역한 말을 바탕으로 위 코드를 보면...
변수 authorities는 인증된 권한(GrantedAuthority)들을 담을 수 있다. 파라미터로 들어온 사용자의 이름이 "admin"이라면 "ROLE_ADMIN" 권한을 authorities 변수에 추가한다. 사용자의 이름이 "admin"이 아닌 경우에는 "ROLE_USER" 권한을 authorities 변수에 추가한다.
즉, ROLE_ 접두사가 붙은 역할(role)은 권한(GrantedAuthority)으로 취급된다.
어? 그러면 SimpleGrantedAuthority는 무엇일까. 위 코드에서 authorities에 인증된 권한을 담을 때 authorities에 SimpleGrantedAuthority라는 객체를 생성(new)하고 여기에 역할(UserRole)을 감싸고 있다.
SimpleGrantedAuthority
SimpleGrantedAuthority는 GrantedAuthority의 기본 구현체(클래스)다. 이 클래스는 Authentication 객체에 부여된 권한을 String으로 변환한다. 생성자에는 String 타입의 역할을 넣어주면 된다.
authorities.add(new SimpleGrantedAuthority(UserRole.ADMIN.getValue()));
이 코드는 넘겨준 사용자의 역할(이 코드에서는 enum 타입)을 String으로 변환하여 authorities에 담는 역할을 수행한다. 방금까지 정리한 내용을 바탕으로 순서대로 설명해 보자.
- GrantedAuthority 타입인 authorities 변수에 ~ 저장한다.
- ROLE_ 접두사로 시작하는 권한(role)을
- GrantedAuthority의 구현체인 SimpleGrantedAuthority를 통해 String으로 변환하여
SUMMARY
정리해 보면...
GrantedAuthority는 Authentication(token ~ User(UserDetails))이 갖고 있는 권한을 String으로 표현한다.내가 사용자에게 admin 권한을 주고자 하면 ROLE_ADMIN으로 명명하여(또는 자동으로) SimpleGrantedAuthority 통해 권한 명을 String으로 변환한 뒤 GrantedAuthority 타입의 객체에 저장한다.
▶ 즉, 사용자의 GrantedAuthority는 "ROLE_ADMIN"이 되는 것이다.
열심히 작성했지만 용어들이 비슷하고 괄호를 많이 사용해서 정신이 없다... 그래도 이해는 됐다!
'Java > Spring' 카테고리의 다른 글
[Thymeleaf + Spring Security] sec:authorize (0) | 2023.01.06 |
---|---|
[Spring Security] @PreAuthorize (0) | 2023.01.05 |
[Spring Security] UserDetails, UserDetailsService (0) | 2023.01.03 |
[Spring Security] BCryptPasswordEncoder (0) | 2023.01.02 |
[Spring Security] @EnableWebSecurity (0) | 2022.12.30 |