반응형
HTTP Security
아래는 configure method에서 구성 가능한 함수들이다.
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// Form 로그인 인증 기능 작동
.formLogin()
// SpringSecurity에서 기본 Form 로그인 화면 을 제공하지만
// 아래 설정을 하면 사용자 정의 로그인 페이지를 사용할 수 있다.
.loginPage("/loginPage")
// 로그인 성공 후 이동 페이지 URL
.defaultSuccessUrl("/")
// 로그인 실패 후 이동 페이지 URL
.failureUrl("/login")
// Form tag의 name 값, 기본적으로는 username이 사용되지만
// 다른 값으로도 사용 가능함.
.usernameParameter("userId")
// Form tag의 password 값, 기본적으로는 password가 사용되지만
// 다른 값으로도 사용 가능함.
.passwordParameter("passwd")
// Fortm tag의 action URL
.loginProcessingUrl("/login_proc")
// 로그인 성공 이후 핸들러 호출
.successHandler(loginSuccessHandler())
// 로그인 실패 이후 핸들러 호출
.failureHandler(loginFailureHandler())
}
처리 PROCESS
1. UsernamePasswordAuthenticationFilter
→ Login Form 인증 처리를 총체적으로 담당하는 클래스이다. 필요한 여러 클래스를 불러들여 인증을 처리한다.
2. AntPathRequestMatcher(/login)
→ 요청 정보 URL(Form tag의 action)이 매칭 되는지 확인한다. ( default는 login이다)
3. Authentication(Username + Password)
→ Login Form 에서 넘어온 username , password값을 인증 객체에 저장하고 그 값을 인증 관리자에게 넘겨준다.
4. AuthenticationManager
→ 인증 객체를 받아서 AuthenticationProvider에게 인증 처리를 위임한다.
- 인증성공
- Authentication 객체를 생성하여 유저정보, 권한정보를 저장하고 인증관리자에게 전달한다.
- 인증 실패
- AuthenticationException에게 전달하여 예외를 처리하도록 한다.
5. Authentication
→ AuthenticationManager 인증에 성공 하게 된 후 최종적으로 받은 Authentication 객체(유저 정보, 권한 정보)
6. SecurityContext
→ 인증 객체를 저장하는 보관소이다. 전역적으로 인증 객체를 참조할 수 있다.
7. SuccessHandler
→ 인증 성공 후 작업을 담당
로그인 PROCESS
AbstractAuthenticationProcessingFilter.java
private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
//2번. 로그인 요청이 아닐 경우에는 다음 필터로 넘긴다.
if (!requiresAuthentication(request, response)) {
chain.doFilter(request, response);
return;
}
try {
/* 3번. 로그인 시도 -> UsernamePasswordAuthenticationFilter에서 Overirde한다.
* 4~5번 처리 후 최종적으로 Authentication 객체를 authenticationResult에 넣음.
*/
Authentication authenticationResult = attemptAuthentication(request, response);
if (authenticationResult == null) {
return;
}
this.sessionStrategy.onAuthentication(authenticationResult, request, response);
// Authentication success
if (this.continueChainBeforeSuccessfulAuthentication) {
chain.doFilter(request, response);
}
//6~7번을 처리한다.
successfulAuthentication(request, response, chain, authenticationResult);
} catch (InternalAuthenticationServiceException failed) {
this.logger.error("An internal error occurred while trying to authenticate the user.", failed);
unsuccessfulAuthentication(request, response, failed);
} catch (AuthenticationException ex) {
// Authentication failed
unsuccessfulAuthentication(request, response, ex);
}
}
UsernamePasswordAuthenticationFilter.java
@Override
//3번.
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
if (this.postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
}
String username = obtainUsername(request);
username = (username != null) ? username : "";
username = username.trim();
String password = obtainPassword(request);
password = (password != null) ? password : "";
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
// 3번. 인증관리자에게 인증정보를 넘긴다.
return this.getAuthenticationManager().authenticate(authRequest);
}
ProviderManager.java
//AuthenticationManager 을 implements했음.
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
Class<? extends Authentication> toTest = authentication.getClass();
AuthenticationException lastException = null;
AuthenticationException parentException = null;
Authentication result = null;
Authentication parentResult = null;
int currentPosition = 0;
int size = this.providers.size();
for (AuthenticationProvider provider : getProviders()) {
if (!provider.supports(toTest)) {
continue;
}
if (logger.isTraceEnabled()) {
logger.trace(LogMessage.format("Authenticating request with %s (%d/%d)",
provider.getClass().getSimpleName(), ++currentPosition, size));
}
try {
//4번 provider에게 인증을 위임한다.
result = provider.authenticate(authentication);
if (result != null) {
copyDetails(authentication, result);
break;
}
} catch (AccountStatusException | InternalAuthenticationServiceException ex) {
prepareException(ex, authentication);
throw ex;
}
/* ...
* 중략...
* ...
*/
}
}
반응형
'Framework > Spring Framework' 카테고리의 다른 글
[Spring Boot] Spring Security Remember Me 인증 (0) | 2021.05.03 |
---|---|
[Spring Boot] Spring Security 로그아웃 처리 (0) | 2021.05.02 |
[Spring Boot] Spring Security 사용자 정의 보안 기능 구현 (0) | 2021.05.02 |
[SpringFramework] RESTFul Web Service Example - GET, POST, PUT, DELETE 예제 (2) | 2018.08.06 |
[SpringFramework] RESTFul Web Service - GET, POST, PUT, DELETE 개념 (0) | 2018.08.06 |
댓글