본문 바로가기

Java/SpringBoot

리멤버미 권한 오류

remember-me 사용에 체크 후 세션이 종료되고 다시 브라우저를 띄우면 로그인 화면은 건너뛰고 main화면이 보여져야 하는데 , 다시 로그인 화면이 출력 되었다. 헤더의 coockie에는 remember-me 토큰이 있었다. 그래서 리소스 권한 설정쪽을 다시 살펴보니 로그인 화면에 대해 다음과 같이 fullyAuthenticated()를 적용하고 있었다.

.antMatchers("/").fullyAuthenticated()

이런 경우 remember-me 토큰 인증으로 로그인 할 수없다. 왜냐하면 fullyAuthenticated()는 anonymous나 remember-me 유저에 대한 접근을 허용하지 않는다. remember-me 인증을 받을 려면 hasRole()이나 Authenticated()를 사용해야한다. 참고로 hasRole()이나 hasAnyRole()은 ROLE이 prefix로 붙어야 하고, 이것을 사용하지 않으려면 hasAuthority()나 hasAnyAuthority()를 이용해야 한다.

더 많은 메소드와 동작은 아래와 같다. Spring security 5.1.0 reference

Expression Description
hasRole([role]) 현재 로그인 된 사용자가 지정된 role을 가지고 있으면 true를 반환 한다. 사용자의 role은 'ROLE_'를 perfix로 가져야 하지만 DefaultWebSecurityExpressionHandlerdefaultRolePrefix에서 prefix를 수정할 수 있다.
hasAnyRole([role1,role2]) 현재 로그인 된 사용자가 지정된 ,로 구분된 role들 중 하나라도 가지고 있으면 true를 반환 한다. 사용자의 role은 'ROLE_'를 perfix로 가져야 하지만 DefaultWebSecurityExpressionHandlerdefaultRolePrefix에서 prefix를 수정할 수 있다.
hasAuthority([authority]) 현재 로그인된 사용자가 지정된 권한을 가지고 있으면 true를 반환한다.
hasAnyAuthority([authority1,authority2]) 현재 로그인 된 사용자가 지정된 권한들 중 한가지라도 가지고 있으면 true를 반환한다.
principal 현재 사용자를 나타내는 principal객체제 직접 접근 할 수 있다.
authentication SecurityContext에서 가져온 현재 Authentication 객체(스프링 시큐리티 인증객체)에 직접 접근 할 수 있다.
permitAll() 항상 true
denyAll() 항상 false
isAnonymous() 현재 사용자가 Anonymous(익명 사용자) 이면 true를 반환한다.
isRememberMe() 현재 사용자가 remember-me로 인증한 사용자면 true를 반환한다.
isAuthenticated() 현재 사용자가 Anonymous가 아니라면 true를 반환한다.
isFullyAuthenticated() 오직 ID와 Password로 인증하여 로그인한 사용자만 true를 반환한다.
hasPermission(Object taget, Object permission) 사용자가 주어진 권한으로 제공된 대상에 접근할 수 있으면 true를 반환한다. Ex. hasPermission(domainObject,‘read’)
hasPermission(Object targetId, String tartgetType, Object permission) 특정 대상 ID에 지정된 권한으로 접근 할 수 있으면 true를 반환한다. Ex. hasPermission(1, ‘com.example.domain.Message’, ‘read’)