[Spring Boot] Spring Security (4) - 역할 별 페이지 접근제어

개발환경
- Eclipse IDE 2022-06
- Spring Boot 2.7.2
- Gradle 7.0
- Lombok
- PostgreSQL
지난 시간에 이어서 이번에는 사용자가 가지고 있는 역할을 확인하여 페이지 별 접근제어를 해보자. sysetm 계정은 SYSTEM 역할을 가지고 있어 모든 페이지에 접근이 가능하고 user 계정은 USER 역할과 BOARD 권한을 가지고 있어 SYSTEM 역할을 가져야만 접근할 수 있는 페이지에는 접근이 불가하다. 이때 오류페이지로 사용자에게 안내해줄 수 있도록 해보자.

- SecurityConfiguration.java
package com.example.security; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import com.example.security.enums.UserRole; import lombok.AllArgsConstructor; @EnableWebSecurity @AllArgsConstructor public class SecurityConfiguration { private final UserDetailsService userDetailsService; @Bean public static BCryptPasswordEncoder bCryptPasswordEncoder() { return new BCryptPasswordEncoder(); } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { /* @formatter:off */ http .authorizeRequests() .antMatchers("/", "/home", "/signUp").permitAll() // 설정한 리소스의 접근을 인증절차 없이 허용 .antMatchers("/system").hasRole(UserRole.SYSTEM.toString()) // SYSTEM 역할을 가지고 있어야 접근 허용 .anyRequest().authenticated() // 그 외 모든 리소스를 의미하며 인증 필요 .and() .formLogin() .permitAll() .loginPage("/login") // 기본 로그인 페이지 .and() .logout() .permitAll() // .logoutUrl("/logout") // 로그아웃 URL (기본 값 : /logout) // .logoutSuccessUrl("/login?logout") // 로그아웃 성공 URL (기본 값 : "/login?logout") .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) // 주소창에 요청해도 포스트로 인식하여 로그아웃 .deleteCookies("JSESSIONID") // 로그아웃 시 JSESSIONID 제거 .invalidateHttpSession(true) // 로그아웃 시 세션 종료 .clearAuthentication(true) // 로그아웃 시 권한 제거 .and() .exceptionHandling() .accessDeniedPage("/accessDenied"); return http.build(); /* @formatter:on */ } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder()); } }
- SystemContorller.java
package com.example.security.web.controller; import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller public class SystemController { @GetMapping("/system") public String system(HttpServletRequest request) { return "system"; } @GetMapping("/accessDenied") public String accessDenied() { return "accessDenied"; } }
- system.html
<!DOCTYPE html> <html xmlns:th="https://www.thymeleaf.org"> <head> <title>Spring Security Example</title> </head> <body> <h1>SYSTEM</h1> <p>안녕하세요. 이 페이지는 시스템 역할을 가지고 있는 사용자만 접근이 가능합니다.</p> </body> </html>
- accessDenied.html
<!DOCTYPE html> <html xmlns:th="https://www.thymeleaf.org"> <head> <title>Spring Security Example</title> </head> <body> <h1 class="display-1">ACCESS-DENIED</h1> <h2>죄송합니다. 요청하신 페이지의 접근 권한이 없습니다.</h2> <p> 방문하시려는 페이지의 접근 권한이 없습니다. </p> </body> </html>
- hello.html
<!DOCTYPE html> <html xmlns:th="https://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security"> <head> <title>Hello World!</title> </head> <body> <h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1> <br> <!--SYSTEM 역할을 갖는다면 이 글이 보임--> <h3 sec:authorize="hasRole(T(com.example.security.enums.UserRole).SYSTEM)">Has SYSTEM Role</h3> <!--USER 역할을 갖는다면 이 글이 보임--> <h3 sec:authorize="hasRole(T(com.example.security.enums.UserRole).USER)">Has USER Role</h3> <!--USER 역할을 갖는다면 이 글이 보임--> <h3 sec:authorize="hasRole('BOARD')">Has BOARD Role</h3> <!--어떤 역할이건 상관없이 인증이 되었다면 이 글이 보임--> <h3 sec:authorize="isAuthenticated()">Only Authenticated user can see this Text</h3> <div> Authorities : <span sec:authentication="principal.authorities"></span> </div> <br> <p> 시스템 관리자 페이지로 이동 <a th:href="@{/system}">SYSTEM</a> </p> <form th:action="@{/logout}" method="post"> <input type="submit" value="Sign Out" /> </form> </body> </html>
- 시스템 계정이 /system 페이지에 접근


- user 계정이 /system 페이지에 접근


이로써 역할별 페이지 접근제어를 확인해보았다. 다음 시간에는 역할(Role)과 권한(Authority)의 차이에 대해서 자세히 알아보자.
이전글 : [Spring Boot] Spring Security (3) - 로그인 시 사용자 권한 조회 및 부여
[Spring Boot] Spring Security (3) - 로그인 시 사용자 역할 조회 및 부여
[Spring Boot] Spring Security (3) - 로그인 시 사용자 역할 조회 및 부여 개발환경 Eclipse IDE 2022-06 Spring Boot 2.7.2 Gradle 7.0 Lombok PostgreSQL 지난 시간에 이어서 이번에는 로그인 시 사용자가 가..
jiurinie.tistory.com
다음글 : [Spring Boot] Spring Security (5) - 역할(hasRole)과 권한(hasAuthority)의 차이는 무엇일까?
[Spring Boot] Spring Security (5) - 역할(hasRole)과 권한(hasAuthority)의 차이는 무엇일까?
[Spring Boot] Spring Security (5) - 역할(Role)과 권한(Authority)의 차이는 무엇일까? 흔히 Spring Security에서 제공하는 역할(Role)과 권한(Authority)을 혼동하는 사용하는 경우가 많은데 비슷하..
jiurinie.tistory.com
'Programming > Spring Security' 카테고리의 다른 글
[Spring Boot] Spring Security (5) - 역할(hasRole)과 권한(hasAuthority)의 차이는 무엇일까? (0) | 2022.08.22 |
---|---|
[Spring Boot] Spring Security (3) - 로그인 시 사용자 역할 조회 및 부여 (0) | 2022.08.17 |
[Spring Boot] Spring Security (2) - 회원가입 및 로그인을 위한 데이터베이스 연동 (0) | 2022.08.16 |
[Spring Boot] Spring Security (1) - 기본 프로젝트 생성 (3) | 2022.07.21 |
댓글