웹 어플리케이션의 주요 보안 위협 요소
인증(Authentication) 절차 미비
- 인증(Authentication)은 인가(Authorization)와 함께 보안 관련 핵심 개념 중 하나
- 사용자의 신원을 확인하는 과정
- 아이디/패스워드 기반 로그인
- OAuth2.0 프로토콜을 통한 Social 인증
- 보통 어플리케이션은 인증영역과 인증되지 않은 영역(익명영역)으로 나눌 수 있음
- 익명 영역 — 사용자의 신원과 무관한 기능들
- 사용자의 민감 정보를 노출하지 않아야 함
- 시스템의 상태를 변경하거나 데이터를 관리할 수 있는 기능을 제공하지 않아야 함
- 인증 영역 — 사용자의 개인정보를 확인 하고, 수정할 수 있음

인가(Authorization) 처리의 미비
- 적절한 권한이 부여된 사용자들만 특정 기능 수행 또는 데이터 접근을 허용함
- 주어진 권한을 넘어서는 기능 수행은 민감 데이터 유출 등 보안사고 발생 가능성이 높음
- E-Commerce 서비스 사용자가 다른 고객의 주문 정보를 확인하거나 주문을 취소하고 수정할 수 있다면?
개판
크리덴셜(Credential) 보안
- 민감정보(연락처, 결제정보, 비밀번호 등)를 보호하는 것은 항상 최우선 순위를 둬야 하는 일
- 민간정보를 암호화하지 않고, 일반 텍스트로 저장하는 것은 매우 위험함
- 그런데 생각보다 기본이 지켜지지 않는 서비스가 많음
전송 레이어 보안
- 널리 알려진 웹 서비스에서 SSL 보호를 적용하지 않는 것은 존재하지 않음
다행히당연히 프로그래머스 웹 사이트도 SSL 보호가 적용됨

Spring Security는 어플리케이션 보안 관련 다양한 기능을 제공함
Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.
Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirements
- Spring Boot 웹 어플리케이션에
쉽게적용 가능하며 적은 노력으로 각 상황에 보안을 적용할 수 있음
- 사용자 인증 및 인가 처리는 기본
- 필요에 따라
쉽게커스터마이징 가능
- 다양한 확장 기능과 자연스러운 통합
- Spring Session (세션 클러스터 기능 추상화 제공)
- Spring Security Oauth (Oauth 1a, Oauth2 인증 프로토콜 제공)
Spring Security 바로 시작해보기
의존성 추가
- spring-boot-starter-security — spring security 모듈
- spring-security-test — security 테스트 모듈
- thymeleaf-extras-springsecurity5 — thymeleaf spring security 확장 모듈
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity5</artifactId> </dependency>
Java Configuration
@Configuration @EnableWebSecurity public class WebSecurityConfigure extends WebSecurityConfigurerAdapter { @Override public void configure(WebSecurity web) { web.ignoring().antMatchers("/assets/**"); } @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/me").hasAnyRole("USER", "ADMIN") .anyRequest().permitAll() .and() .formLogin() .defaultSuccessUrl("/") .permitAll() ; } }
- @EnableWebSecurity 어노테이션, WebSecurityConfigurerAdapter 클래스
- WebSecurityConfigurerAdapter 추상 클래스를 상속하는 구현체에 @EnableWebSecurity 어노테이션을 추가
- 기본적인 Spring Security 설정이 자동으로 추가되며, 개별 설정을 override 할수 있음
- WebSecurity 클래스는 필터 체인 관련 전역 설정을 처리할 수 있는 API 제공
- ignoring()
- Spring Security 필터 체인을 적용하고 싶지 않은 리소스에 대해 설정
- 일반적으로 정적 리소스(*.html, *.css, *.js 등)을 예외 대상으로 설정함
- 불필요한 서버 자원 낭비를 방지함
- HttpSecurity 클래스는 세부적인 웹 보안기능을 설정을 처리할 수 있는 API를 제공
기본 로그인 계정 설정을 추가
- 기본 로그인 계정을 추가하지 않으면 매번 랜덤으로 비밀번호가 생성됨
- UserDetailsServiceAutoConfiguration 클래스 구현을 보면 InMemoryUserDetailsManager (InMemory 기반 사용자 관리 UserDetailsService) Bean을 등록함
- InMemoryUserDetailsManager Bean 생성 시 SecurityProperties 클래스를 통해 spring.security 관련 설정을 처리함

- application.yml 파일에 기본 로그인 계정 정보를 입력함
- 물론 실제 프로젝트에서는 이런식으로 사용자 계정을 관리하지 않음 (추후 개선)
spring: application: name: spring security 01 thymeleaf: cache: true security: user: name: user password: user123 roles: USER messages: basename: i18n/messages encoding: UTF-8 cache-duration: PT1H server: port: 8080
Thymeleaf 확장
- thymeleaf-extras-springsecurity5 라이브러리를 추가하면 Thymeleaf View에서 Spring Security 관련 기능을 쉽게 사용 가능
- 네임스페이스 http://www.thymeleaf.org/extras/spring-security 추가 필요함
<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>
미션
configure(AuthenticationManagerBuilder auth) 메소드 override
- passwordEncoder는 NoOpPasswordEncoder로 사용함 (힌트: DelegatingPasswordEncoder)
- 기본 로그인 계정을 AuthenticationManagerBuilder 클래스를 통해 추가
로그아웃, Cookie 기반 자동 로그인 (Remember-Me) 기능 설정하기 어렵지 않아요
- HttpSecurity 클래스의 logout() API를 통해 로그아웃 기능을 설정
- 로그아웃 처리 path “/logout”
- 로그아웃 성공 후 리다이렉션 path “/”
- HttpSecurity 클래스의 rememberMe() API를 통해 Cookie 기반 자동 로그인 기능을 설정
- 파라미터명 “remember-me”
- 자동 로그인 토큰 유효기간 5분