본문 바로가기

Backend/Spring | SpringBoot

[Spring Security] 인증 이후 핸들러 설정

반응형

인증 이후에는 크게 인증 성공 후, 인증 실패 후로 나눌 수 있다.

내가 하려고 하는 작업은 login후에 role에 따라서 일반 사용자(User)와 관리자(Admin) 각각의 main페이지로 이동하는 것이다.

 

인증까지는 성공적으로 이루어 지나 그 후 루트패스로 redirect된다.

인증에 실패하게 되면 다시 login페이지로 돌아온다는 글은 봤지만 해당 내용과는 무관한것으로 생각된다.

 

해본 시도

1. SecurityConfig에서 defaultSuccessUrl지정

.formLogin(login -> login
	.loginPage("/login")
	// 기본 redirect url 지정
	.defaultSuccessUrl("/main",true)
	.permitAll()
)

 

중간에 defaultTargetUrl이 변경되었지만 다시 돌아왔다.

 

2. SuccessHandler를 implements하여 선언

<잘 정리 되어있는 글이 있었다. : 참조>

.formLogin(login -> login
	.loginPage("/login")
	// successHandler 이용 redirect url 지정
	.successHandler(customSuccessHandler())
)

하지만 증상은 동일...

 

두 케이스의 차이점은 1번은 성공했을 때 targetURL에 의해, 2번은 Redirect전략에 의해 redirect시키는 것으로 이해했다. 하지만 두 케이스에서 모두 동일 증상을 보이는 것으로 보아 어느 설정에서 roll back(?)하고 있는 느낌이 들었다. 

 

2번 케이스의 log를 좀 더 들여다보니 HTTP STATUS가 302 FOUND가 발생하고 있었다.

상태코드만 받아오고 redirect가 되지 않는다는 생각이 들었다.

 

debugging을 하다가 확인한 중요한 포인트는 Custom으로 생성한 핸들러의 메서드가 동작하지 않고 implements된 핸들러의 메서드가 동작하는 것이었다.

 

➡️

successHandler 혹은 failureHandler를 Filter에 있는 Provider에게 인증 성공, 실패에 따라서 동작하게 하는 방법이 있었다.

그래서 인증 필터를 사용하는 곳에 추가를 해주었더니 정상 작동한다.

public AbstractAuthenticationProcessingFilter abstractAuthenticationProcessingFilter(
    final AuthenticationManager authenticationManager) {
  LoginAuthenticationFilter loginAuthenticationFilter = new LoginAuthenticationFilter("/ajax/loginProcess", authenticationManager);
  loginAuthenticationFilter.setAuthenticationSuccessHandler(customSuccessHandler());

  return loginAuthenticationFilter;
}

 

 

➡️ 필터 수정

// 인증 필터
public AbstractAuthenticationProcessingFilter abstractAuthenticationProcessingFilter(
	final AuthenticationManager authenticationManager) {
	LoginAuthenticationFilter loginAuthenticationFilter = new LoginAuthenticationFilter("/ajax/loginProcess", authenticationManager);
	loginAuthenticationFilter.setAuthenticationSuccessHandler(customSuccessHandler());
	// Rest API 방식을 사용하기 위해 추가
	loginAuthenticationFilter.setSecurityContextRepository(
		new DelegatingSecurityContextRepository(
			new RequestAttributeSecurityContextRepository(),
			new HttpSessionSecurityContextRepository()
	));
	return loginAuthenticationFilter;
}

필터의 추가 부분은 Rest API 방식을 사용하기 위해 추가 된 것이다.
Form Login 방식은 기본적으로 DelegatingSecurityContextRepository 가 설정되어있지만, Custom 한 필터에는 설정되어있지 않고 RequestAttributeSecurity 가 설정되어있다고 한다. 따라서 RequestAttributeSecurity 는 세션을 저장 하지 않기 때문에 로그인 후 API 요청시 Anonymous 토큰이 생성되게 한것이다.

반응형