본문 바로가기
Programming/Spring Security

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

by 주리니e 2022. 8. 19.
728x90

[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

 

728x90

댓글