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는 고수준 사용자 정의가 가능한 인증 및 인가(access-control) 프레임워크이며, Spring 기반 어플리케이션의 사실상의 표준이다.
Spring Security의 기능들
공식 사이트에서는 크게 Authentication
, Protection Againist Exploits
, Integration
로 분야를 나누어 기능을 설명하고 있다.
Spring Security에서 제공하는 인증 방법은 아래와 같다.
자주 쓰이는 인증 방법에 대해 작동하는 방법을 알아보자.
GET /private
에 사용자가 접근을 요청한다.FilterSecurityInterceptor
에서 AccessDeniedException
예외를 던진다(throw).ExceptionTranslationFilter
가 실행되며 로그인 페이지로 리디렉션을 요청한다.GET /login
으로 요청을 보낸다.login.html
)을 반환한다.username(id)
와 password
를 제출하면 UsernamePasswordAuthenticationFilter
가 HttpServletRequest
에서 추출한 username
과 password
를 기반으로 UsernamePasswordAuthenticationToken (이하 Token)
을 생성한다.Token
을 AuthenticationManager
에 전달하여 인증을 수행한다.SecurityContextHolder
가 초기화된다.RememberMeService
의 loginFail
메소드를 실행한다. (remember me가 구성되지 않은 경우 작동되지 않는다.)AuthenticationFailureHandler
를 호출한다.SessionAuthenticationStrategy
가 새로운 로그인 요청에 대한 알림을 받는다.SecurityContextHolder
에 Authentication
가 설정된다.RememberMeService
의 loginSuccess
메소드를 실행한다. (remember me가 구성되지 않은 경우 작동되지 않는다.)ApplicationEventPublisher
에서 InteractiveAuthenticationSuccessEvent
이벤트를 발행한다.SimpleUrlAuthenticationSuccessHandler
가 호출되며, 로그인 후 리디렉션 되는 페이지는 ExceptionTranslationFilter
에 의해 저장된 URL이다.*참고
사전 작업
리디렉션 URI
를 설정하고client-id
, client-secret-key
를 발급받는다.리디렉션 URI
는 기본적으로 {baseUrl}/login/oauth2/code/{registrationId}
이다. (ex. 로컬 Spring boot 서버에 Google OAuth 2.0 로그인을 적용하는 경우 : localhost:8080/login/oauth2/code/google
)리디렉션 URI
를 기본적으로 제공하고 있기 때문에 따로 구현할 필요는 없다.Spring boot에 적용
application.yml
파일에client-id
, client-secret-key
를 기재한다.WebSecurityConfigurerAdapter
클래스에서 OAuth 2.0 Login
을 활성화한다.#application.yml
spring:
security:
oauth2:
client:
registration:
google:
client-id: {google-client-id}
client-secret: {google-client-secret}
// OAuth2LoginSecurityConfig.java
@EnableWebSecurity
public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.oauth2Login(withDefaults());
}
}
*참고
Remember Me
기능은 로그인 시 쿠키를 브라우저에 전송하고, 이후 웹사이트 재방문 시 발급된 쿠키를 발견하여 자동으로 로그인을 하는 기능이다.
그리고 이 기능은 UserDetailsService
클래스가 구현되어 있어야 작동한다.
<!-- login.html -->
<form action="/login" method="POST">
...
<input type="checkbox" name="remember-me">
</form>
// WebSecurityConfig.java
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.rememberMe()
.rememberMeParameter("remember-me") // 기본값, remember-me 기능 사용 여부를 입력하는 input 태그의 name을 적어주면 된다.
.tokenValiditySeconds(3600) // remember-me 쿠키 유효 기간
}
}
login form에서 체크박스 형태로 remember-me
사용 여부를 받아온 뒤, UsernamePasswordAuthenticationFilter
에서 remember-me 쿠키
를 발견하면 RememberMeServices
를 적시에 호출해 자동으로 로그인하게 된다.