🚧권한으로 접근을 제한시켜보자!
시작하기 전에 이전에 했던 JWT방식에서 다시 form로그인 방식으로 변경하고 시작합니다.
/board로 접근하는 것을 ADMIN 권한을 가진 유저만 접근할 수 있도록 변경했습니다.
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().and().formLogin().loginPage("/").loginProcessingUrl("/login").defaultSuccessUrl("/board",true)
.and().logout().deleteCookies("JSESSIONID").invalidateHttpSession(true)
.and().authorizeRequests()
.antMatchers("/vendor/**","/css/**","/js/**","/scss/**","/img/**","/","/user").permitAll()
.antMatchers("/board").hasRole("ADMIN")
.anyRequest().authenticated().and().csrf().disable();
아래 생략
}
다음과 같이 거부되는 것을 확인할 수 있습니다.
hasRole("USER")로 변경하면
성공적으로 접근이 됩니다. 그 이유는 UserVO에서 getAuthorities 메소드가 ROLE_USER 권한이 담긴 리스트를 반환하기 때문입니다. hasRole 메소드의 매개변수로 들어가는 문자열은 ROLE이 생략되어 있다고 생각하면 됩니다.
SecuirtyConfig 클래스에서 @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)로 Annotation을 허용했으므로 Annotation으로 메소드를 제한할 수 있습니다.
/board로 접근할 때 사용하는 메소드인 PostService의 findAll 메소드를 막아보겠습니다.
@Secured("ROLE_ADMIN")
@Override
public List<PostVO> findAll() {
return postMapper.findAll();
}
@PreAuthorize는 메소드 시작 전에 권한을 검사합니다. @Secured와 다른 점은 SpEL을 지원한다는 점입니다.
@PreAuthorize("hasRole('ADMIN')")
@Override
public List<PostVO> findAll() {
return postMapper.findAll();
}
SpEL은 Spring Expression Language의 준말입니다.
Controller의 메소드는 제한할 수 없습니다.
인증 객체의 email과 post의 유저의 email을 비교하는 부분을 아래와 같이 수정합니다. <sec:authorize> 태그를 사용하여서 권한에 따라 view를 제한할 수 있습니다. 여기서는 ADMIN권한이 있으면 email이 달라도 수정 버튼과 삭제 버튼이 보이도록 수정했습니다.
<c:choose>
<c:when test="${user.email == post.user.email}">
<c:choose>
<c:when test="${!isModify}">
<a id="modify" href="/post/${post.id}?isModify=true" class="btn btn-primary btn-user btn-block">
Modify
</a>
</c:when>
<c:otherwise>
<a id="modifySubmit" class="btn btn-primary btn-user btn-block">
Submit
</a>
</c:otherwise>
</c:choose>
<a id="delete" class="btn btn-danger btn-user btn-block">
Delete
</a>
</c:when>
<c:otherwise>
<sec:authorize access="hasRole('ADMIN')">
<c:choose>
<c:when test="${!isModify}">
<a id="modify" href="/post/${post.id}?isModify=true" class="btn btn-primary btn-user btn-block">
Modify
</a>
</c:when>
<c:otherwise>
<a id="modifySubmit" class="btn btn-primary btn-user btn-block">
Submit
</a>
</c:otherwise>
</c:choose>
<a id="delete" class="btn btn-danger btn-user btn-block">
Delete
</a>
</sec:authorize>
</c:otherwise>
</c:choose>
테스트 하기 전 다른 유저를 만들어서 글을 작성하고 유저의 권한을 반환하는 부분을 ADMIN권한을 반환하도록 수정합니다.
USER권한을 반환하도록 수정하면