티스토리 뷰
Form Login 인증과 Form Login 인증 필터인 UsernamePasswordAuthenticationFilter
사용자가 GET 방식으로 home url로 이동하려고 하면 인증이 되지 않았기 때문에 서버에서는 로그인 페이지로 리다이렉트 시킨다.
기본적으로 스프링 부트 시큐리티가 제공하는 로그인 페이지가 나타나지만 이 페이지는 별도로 만들 수도 있다.
사용자는 POST 방식으로 username과 password를 입력해서 서버에 전송하고 서버에서는 세션을 생성하고 Authentication 타입 클래스의 인증 객체를 생성, SecurityContext에 세션을 저장한다.
이후에 클라이언트가 다시 home url로 이동할 때 세션에 저장된 인증 토큰으로 접근하게 되고 서버는 세션에 저장된 인증 토큰이 있게 되면 사용자가 인증된 사용자라고 판단하고 인증을 유지하게 된다.
formLogin 인증 API
몇가지만 얘기해보면 스프링 부트 시큐리티가 자동으로 만들어주는 form 태그의 사용자 계정과 비밀번호의 input name은 기본적으로 username과 password로 되어있는데 usernameParameter와 passwordParameter를 사용해서 이름을 바꿀 수 있다.
input의 name이 usernamer과 password로 설정되어 있는 걸 확인할 수 있다.
추가로 defaultScuccesUrl과 successHandler는 약간의 차이점이 있다. 로그인이 성공했을 때 이동할 수 있는 경로를 지정하는 것은 똑같은데 일반적으로 Handler가 붙은 API를 사용할 경우 조금 더 커스텀하게 로직을 구성할 수 있다.
defaultSuccessUrl은 인증이 성공했을 경우 이동할 수 있는 경로만 지정할 수 있는 것에 비해 successHandler는 HttpServletRequest, HttpServletResponse, Authentication와 같은 인자가 전달되기 때문에 이를 활용해서 필요한 비즈니스 로직을 구성할 수 있는 장점이 있다.
@Override
protected void configure(HttpSecurity http) throws Exception {
//인증정책
http
.formLogin()
.defaultSuccessUrl("/")
.successHandler((request, response, authentication) -> {
System.out.println("authentication: " + authentication.getName());
response.sendRedirect("/");
});
}
UsernamePasswordAuthenticationFilter
실제로 사용자가 Form 로그인했을 때 인증처리를 담당하는 필터가 UsernamePasswordAuthenticationFilter 이다.
사용자가 로그인을 요청하면
(1) Authentication 객체를 만들어서 객체 안에 사용자가 로그인할 때 입력한 username과 password를 Authentication 인증 객체에 저장해서 인증처리를 맡기게 된다.
(2) 인증 객체를 생성해서 인증처리를 맡게되는 클래스가 AuthenticationManager이다.
(3) AuthenticationManager는 내부적으로 AuthenticationProvider 클래스 타입의 객체를 갖고있는데 이 객체들중 하나를 선택해서 인증처리를 위임한다.
(4) AuthenticationProvider 클래스가 실제적으로 인증처리를 담당하는 클래스이다. 이 클래스가 인증의 성공과 실패를 리턴하게 되는데 인증이 실패하면 인증예외 AuthenticationException을 발생시킨다.
(5) 인증이 성공하면 사용자의 정보와 권한등을 Authentication 인증 객체를 AuthenticationManager에게 다시 리턴한다.
(6) Authentication의 인증 객체를 SecurityContext에 저장한다.
UsernamePasswordAuthenticationFilter의 핵심코드
@Override
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);
return this.getAuthenticationManager().authenticate(authRequest);
}
참고
- Total
- Today
- Yesterday
- localtime
- Spring Security
- Github Status
- Java
- elasticsearch
- svn
- 북리뷰
- config-location
- jQuery
- input
- rocky
- springboot
- 베리 심플
- Linux
- intellij
- maven
- JavaScript
- mybatis
- LocalDate
- mybatis config
- docker
- window
- Spring
- k8s
- Bash tab
- Kotlin
- 오라클
- LocalDateTime
- oracle
- Mac
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |