💡 이전 내용
Spring의 하위 프레임워크로 애플리케이션의 보안을 담당하며, 인증과 인가에 중점을 두고 있습니다.
지난 글에서는 인증의 대표적인 예시로 로그인 기능을 구현하였습니다.
이번 글에서는 인가의 대표적인 예시로 역할 및 권한 기능을 구현하겠습니다.
📖 개념 정리
1. 인가란?
엔터프라이즈 애플리케이션의 경우, 모든 사용자가 전체 애플리케이션에 접근할 수 있는 것은 아닙니다.
Spring Security를 사용하면 역할과 권한을 기반으로 사용자의 접근을 제어할 수 있습니다.
2. 역할(Role)이란?
특정 수준의 권한 부여를 나타내며, 하나의 역할은 여러 권한을 가질 수 있습니다.
관리자, 사용자, 영업사원, 고객센터 등이 있습니다.
3. 권한(Authority, Operation)이란?
보다 세분화된 방식으로 접근을 제한하는 방식입니다.
READ, WRITE, EDIT, DELETE, ACCESS, ASSIGN, SHARE, APPEND 등이 있습니다.
4. Role 과 Authority 의 차이(예시)
예를 들어, A계정과 B계정은 둘다 관리자로서 ADMIN 역할을 가지고 있지만,
A계정은 게시글을 등록할 수만 있으며, B계정은 게시글을 삭제할 수만 있다고 했을 때
A계정과 B계정은 역할은 같지만 권한은 다르게 부여해야합니다.
💻 Role 설정 기능 구현
이 글에서는 Role 기반의 접근 제어를 다루고 있으며, 세부적인 권한에 대해서는 다루지 않겠습니다.
또한 모든 사용자에게 User 역할을 부여하고, 추후 관리자 페이지에 역할 및 권한 부여 기능을 추가하겠습니다.
1. Role 생성
public enum UserRole {
ADMIN("관리자"),
MANAGER("매니저"),
USER("일반사용자");
private String label;
private UserRole(String label) {
this.label = label;
}
public String getLabel() {
return this.label;
}
}
2. 사용자에게 Role 부여
Accout 생성 시 Role 을 User 로 초기화하여, 모든 사용자에게 User 역할을 부여하였습니다.
다른 Role에 대한 접근 확인 시, DB에서 값을 변경하여 테스트 하겠습니다.
@Getter
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Account implements Serializable {
...
@Enumerated(EnumType.STRING)
private UserRole userRole = UserRole.USER;
}
3. Role 가져오기
Spring Security에서 접근 제어는 UserDetails 의 getAuthorities() 를 이용하여 구현할 수 있습니다.
Role 부여와 Authority 부여는 기본적으로 동일한 방식이지만, Role 부여할 때는 반드시 prefix로 'ROLE_' 을 써줘야 합니다.
public class CustomUserDetails implements UserDetails {
private Account account;
public CustomUserDetails(Account account) {
this.account = account;
}
@Override
public List<GrantedAuthority> getAuthorities() {
List<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("ROLE_" + account.getUserRole().name()));
return authorities;
}
...
}
4. 요청(Request)시 접근 제어 설정
/admin/ 이 포함된 URL 에 접근할 수 있는 권한은 ADMIN,
/manager/ 이 포함된 URL 에 접근할 수 있는 권한은 ADMIN과 MANAGER 로 설정하였습니다.
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
...
// 접근 권한
http.authorizeRequests()
.mvcMatchers("/", "/login", "/signup").permitAll()
.mvcMatchers("/admin/**").hasRole(UserRole.ADMIN.name())
.mvcMatchers("/manager/**").hasAnyRole(UserRole.ADMIN.name(), UserRole.MANAGER.name())
.anyRequest().authenticated();
}
}
5. URL 접근
"/admin/list"는 관리자 역할을 가진 사용자만 접근할 수 있으며, 접근 시 "관리자" 라는 텍스트가 보여집니다.
@Slf4j
@Controller
@AllArgsConstructor
public class AccountController {
@GetMapping("/")
public String index() {
return "index";
}
@ResponseBody
@GetMapping("/admin/list")
public String adminPage() {
return "관리자";
}
@ResponseBody
@GetMapping("/manager/list")
public String managerPage() {
return "매니저";
}
}
6. 화면에 사용자 정보 출력
"/"는 모든 사용자가 접근할 수 있습니다.
로그인하지 않은 사용자는 "로그인" 버튼만 보여지며, 로그인한 사용자에게는 아이디와 "로그아웃" 버튼이 보여집니다.
로그인한 사용자는 역할에 따라 추가 문구가 다르게 보입니다.
<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{board2/layouts/default_layout}">
<div layout:fragment="content">
<h1>스프링 시큐리티 데모</h1>
<div sec:authorize="isAuthenticated()">
<p>
안녕하세요,
<span sec:authentication="principal.username"></span> 님
<span sec:authentication="principal.authorities"></span>
</p>
<div sec:authorize="hasRole('USER')">
<span>사용자에게 보이는 문구</span>
</div>
<div sec:authorize="hasRole('MANAGER')">
<span>매니저에게 보이는 문구</span>
</div>
<div sec:authorize="hasRole('ADMIN')">
<span>관리자에게 보이는 문구</span>
</div>
<a th:href="@{/logout}">로그아웃</a>
</div>
<div sec:authorize="isAnonymous()">
<a th:href="@{/login}">로그인</a>
</div>
</div>
</html>
💬 실행 화면
참고 사이트:
https://jiurinie.tistory.com/71
https://www.javadevjournal.com/spring-security/spring-security-roles-and-permissions/
https://dev-gorany.tistory.com/139
'Web 개발 > 게시판 만들기' 카테고리의 다른 글
[JPA/Thymeleaf] 게시글 작성자만 수정하게 하기(2) (0) | 2022.09.04 |
---|---|
[JPA] 게시글 작성자만 수정하게 하기(1) (0) | 2022.09.04 |
[Spring Security] 로그인 기능 구현 (3) 회원 가입 기능 (0) | 2022.08.27 |
[Spring Security] 로그인 기능 구현 (3) 로그인 기능 확장 (0) | 2022.08.26 |
[Spring Security] 로그인 기능 구현 (1) Spring Security Authentication (0) | 2022.08.25 |