728x90
- AbstractAuthenticationProcessingFilter 상속
- 대부분의 인증을 하는 클래스들은 이를 상속받아 구현한다
-
필터 작동 조건
-
AntPathRequestMatcher("/api/login")로 요청정보와 매칭하고 요청 방식이 Ajax 이면 필터 작동
-
- AjaxAuthenticationToken 생성하여 AuthenticationManager에게 전달하여 인증처리
- Filter 추가
- http.addFilterBefore(AjaxAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
- 우리가 만든 필터를 UsernamePasswordAuthenticationFilter 전에 동작시키도록 한다.
- Filter
-
public class AjaxLoginProcessingFilter extends AbstractAuthenticationProcessingFilter { private ObjectMapper objectMapper = new ObjectMapper();//JSON 객체를 추출하고 반환하기위해 public AjaxLoginProcessingFilter() { super(new AntPathRequestMatcher("/api/login")); //사용자가 해당 URL로 요청을 할떄만 필터가 동작 } @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException { if(!isAjax(request)){ //AJAX인가? throw new IllegalStateException("Authentication is not supported"); } AccountDto accountDto = objectMapper.readValue(request.getReader(), AccountDto.class); if(StringUtils.isEmpty(accountDto.getUsername()) || StringUtils.isEmpty(accountDto.getPassword())){ throw new IllegalArgumentException("Username or Password is empty"); } AjaxAuthenticationToken ajaxAuthenticationToken = new AjaxAuthenticationToken(accountDto.getUsername(), accountDto.getPassword()); //현재는 Form인증 방식을 AuthenticationProvider 가 동작하게 되는데 Token 이 AjaxAuthenticationToken 과 다르기 떄문에 현재는 동작하지 않는다. return getAuthenticationManager().authenticate(ajaxAuthenticationToken); } private boolean isAjax(HttpServletRequest request) { //header에 값을 담아서 Ajax인지 판단. if("XMLHttpRequest".equals(request.getHeader("X-Requested-with"))){ return true; } return false; } } - AbstractAuthenticationProcessingFilter를 상속받아 구현한다.
- 생성자를 사용하여, 어떤 URL로 접근하였을 때 필터를 동작시킬지 적는다
- new AntPathRequestMatcher("/api/login")
- Client에서 AJAX 일 경우 Header에 X-Requested-with 필드의 값을 XMLHttpRequest값을 주게 되는데 이 값이 맞는지를 확인한다.
- Client에서 ID, Password값을 빈 값으로 주진 않았는지 확인한다.
- 모든 과정이 성공하게 된다면 AuthenticationManager() 에게 인증 권한을 넘긴다
- 현재는 Provider가 없기 때문에 성공적인 인증 처리를 할 수가 없다.
- Provider가 AjaxAuthenticationToken을 찾을 수 없기 때문
- AjaxAuthenticationToken
-
public class AjaxAuthenticationToken extends AbstractAuthenticationToken { private static final long serialVersionUID = 560L; private final Object principal; private Object credentials; public AjaxAuthenticationToken(Object principal, Object credentials) { //실제 인증 받기전 username, password를 받는 생성자 super((Collection)null); this.principal = principal; this.credentials = credentials; this.setAuthenticated(false); } public AjaxAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) { //실제 인증 받은 후 username, password를 받는 생성 super(authorities); this.principal = principal; this.credentials = credentials; super.setAuthenticated(true); } public Object getCredentials() { return this.credentials; } public Object getPrincipal() { return this.principal; } public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { Assert.isTrue(!isAuthenticated, "Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead"); super.setAuthenticated(false); } public void eraseCredentials() { super.eraseCredentials(); this.credentials = null; } }
-
- UsernamePasswordAuthenticationFilter 앞에 내 CustomFilter를 위치시킨다.

첫번째 파라미터에 등록시킬 Filter를 위치시킨다. 
내 필터 빈으로 등록 - 내 필터를 빈으로 등록하는데 이때 manager를 등록해야 되는데 authenticationManagerBean을 통해 Manager를 가지고와 주입해 준다.
-
728x90
'스프링 시큐리티 > 실전프로젝트 - 인증 프로세스 Ajax 인증 구현' 카테고리의 다른 글
| ch06. Ajax Custom DSLs 구현하기 (0) | 2022.01.21 |
|---|---|
| ch05. 인증 및 인가 예외 처리 - AjaxLoginUrlAuthenticationEntryPoint, AjaxAccessDeniedHandler (0) | 2022.01.21 |
| ch04. 인증 핸들러 - AjaxAuthenticationSuccessHandler, AjaxAuthenticationFailureHandler (0) | 2022.01.20 |
| ch03. 인증 처리자 - AjaxAuthenticationProvider (0) | 2022.01.20 |
| ch01. 흐름 및 개요 (0) | 2022.01.20 |