스프링의 보안을 위한 프레임워크. 간단한 설정을 통해 다양한 보안 기능을 추가할 수 있도록 제공한다
Maven
에선 다음처럼 의존성을 추가할 수 있다
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
크게 4가지 위협 요소가 존재하고, Spring Security는 이를 해결하는 기능을 제공한다
@Configuration
@EnableWebSecurity
public class WebSecurityConfigure extends WebSecurityConfigurerAdapter {
@Override
// WebSecurity : 필터 체인 관련 전역 설정을 처리할 수 있는 API 제공
public void configure(WebSecurity web) {
// 매칭되는 uri가 필터 체인을 적용하지 않도록 설정
web.ignoring().antMatchers("/assets/**");
}
@Override
// HttpSecurity : 세부적인 보안기능 설정을 처리할 수 있는 API 제공
protected void configure(HttpSecurity http) throws Exception {
http
// 공개 리소스 또는 보호받는 리소스에 대한 세부 설정
.authorizeRequests()
// USER 또는 ADMIN 역할이 있어야 html 파일로 이어짐
// 역할이 없을 경우 로그인 페이지로 이동
.antMatchers("/me").hasAnyRole("USER", "ADMIN")
.anyRequest().permitAll()
.and()
// 로그인 폼 기능 세부설정
.formLogin()
.defaultSuccessUrl("/")
.permitAll()
.and()
;
}
}
WebSecurity.ignoring()
api를 통해 설정 가능Spring Security
실행 시 기본적으로 user
계정이 제공된다 ...Granted Authorities=[]...
Failed to authorize filter invocation [GET /me] with attributes [hasAnyRole('ROLE_USER','ROLE_ADMIN')]
spring-boot-starter-security
는 기본적으로 SecurityProperties.java
의 User
클래스를 사용해 기본 유저를 만든다. 아래 코드처럼 유저를 생성하기 때문에 실행시마다 유저를 메모리에 생성하고 랜덤 생성된 비밀번호를 제공한다. 이를 고정하고 싶다면 application.yaml
에서 설정하면 된다package org.springframework.boot.autoconfigure.security;
public class SecurityProperties {
...
public static class User {
private String name = "user";
private String password = UUID.randomUUID().toString();
...
...
# application.yaml
spring:
security:
user:
name: user
password: 123!
roles: USER # 덤으로 역할 추가
thymeleaf-extras-springsecurity5
라이브러리를 통해 Thymeleaf View에서 스프링 시큐리티 기능 쉽게 사용 가능하다 <dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<html xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<div th:text="${#authentication.name}">
The value of the "name" property of the authentication object should appear here.
</div>
<div th:if="${#authorization.expression('hasRole(''ROLE_ADMIN'')')}">
This will only be displayed if authenticated user has role ROLE_ADMIN.
</div>
<div sec:authentication="name">
The value of the "name" property of the authentication object should appear here.
</div>
<div sec:authorize="hasRole('ROLE_ADMIN')">
This will only be displayed if authenticated user has role ROLE_ADMIN.
</div>