Spring
- Spring security Role 관련 이모저모
저번 주 내내 고생한 프로젝트에서 인증 파트를 맡았는데 스프링도 잘 모르는 상태로 security 를 다루려고 하니 어려움이 많았는데 가장 시간을 많이 할애했던 Role에 대해 이야기 해보려 한다.
Role의 쓰임새는 사용자의 Role에 따라 특정 url에 대한 접근을 제어하기 위함이다.
가장 많이 쓰이는 메소드는 requestMatchers.~~~이다.
//Role에 관계없이 모든 사용자가 이용가능
.requestMatchers("/api/user/**").permitAll()
//Role이 USER인 사용자만 이용가능. 근데 여기서는 "ROLE"을 앞에 알아서 붙여주기 때문에 "ROLE_USER"하면 오류
.requestMatchers({uri}).hasRole("USER")
//hasRole과 동일한 기능
.requestMatchers({uri)).hasAuthority("ROLE_USER")
hasAnyRole 로 해서 여러 권한도 넣어줄 수 있고 한데 주의할 건 Role이 들어간 메소드는 ROLE_을 앞에 붙여준다는 의미이다. 오류 메시지에도 잘 나오니까 크게 걱정할 필요는 없다.
그럼 과연 이 ROLE들을 어떻게 구분하는 것일까. 비밀은 바로 UserDetails에 있다.
UserDetails는 security에서 제공하는 인터페이스로 사용자에 대한 인증에 이용된다.
public interface UserDetails extends Serializable {
/**
* Returns the authorities granted to the user. Cannot return <code>null</code>.
* @return the authorities, sorted by natural key (never <code>null</code>)
*/
Collection<? extends GrantedAuthority> getAuthorities();
/**
* Returns the password used to authenticate the user.
* @return the password
*/
String getPassword();
/**
* Returns the username used to authenticate the user. Cannot return
* <code>null</code>.
* @return the username (never <code>null</code>)
*/
String getUsername();
/**
* Indicates whether the user's account has expired. An expired account cannot be
* authenticated.
* @return <code>true</code> if the user's account is valid (ie non-expired),
* <code>false</code> if no longer valid (ie expired)
*/
boolean isAccountNonExpired();
/**
* Indicates whether the user is locked or unlocked. A locked user cannot be
* authenticated.
* @return <code>true</code> if the user is not locked, <code>false</code> otherwise
*/
boolean isAccountNonLocked();
/**
* Indicates whether the user's credentials (password) has expired. Expired
* credentials prevent authentication.
* @return <code>true</code> if the user's credentials are valid (ie non-expired),
* <code>false</code> if no longer valid (ie expired)
*/
boolean isCredentialsNonExpired();
/**
* Indicates whether the user is enabled or disabled. A disabled user cannot be
* authenticated.
* @return <code>true</code> if the user is enabled, <code>false</code> otherwise
*/
boolean isEnabled();
}
함수 명들만 보더라도 사용자 인증에 가져다 쓰라고 만든 것 같다.
UserDetails에서 Role과 관련된 메소드는 getAuthorities()이다. 본인이 커스텀하기 나름이겠지만 이 함수 리턴값에 특정 유저에 대한 모든 권한 리스트를 담아주면 된다.
이번에 가장 헷갈렸던 부분!
hasRole("USER")가 호출 -> securitycontextholder에서 UserDetails 가져옴 -> UserDetails.getAuthorities() 에 "ROLE_USER" 가 존재하는지 확인 -> 요청을 막거나 허가.
컨트롤러 단에서 권한을 검증하는 @Secured @PreAuthorize도 있다.
간혹 jwt claim에 권한을 넣어주는 경우도 있는데 이는 클라이언트에게 유저의 권한을 활용할 수 있도록 하거나
jwt를 완전히 신용한다면 따로 UserDetails를 검사하지 않고 넘겨주는 필터를 적용할 수도 있겠다.
알고리즘
- 프로그래머스 : 압축(Level 2, 해시, 문자열)
느낀 점
.
'TIL' 카테고리의 다른 글
[23.11.30] (1) | 2023.12.01 |
---|---|
[23.11.29] (0) | 2023.11.29 |
[23.11.22] (1) | 2023.11.22 |
[23.11.21] (0) | 2023.11.21 |
[23.11.20] (0) | 2023.11.20 |