본문 바로가기

SpringSecurity

SpringSecurity(인증/인가 API-ExceptionTranslationFilter)

반응형

AuthenticationException

  • AuthenticationEntryPoint 호출하게 되는데 SpringSecurity가 구현체를 제공한다 
  • AuthenticationEntryPoint 사용자가 직접 구현해서 호출할수도 있다,
  • 인증된 사용자만 서버자원에 접근이 가능한데 만약 인증없이 서버자원에 접근할려면 로그인 페이지로 이동하게 처리한다 이때 인증예외가 발생하기전에 그사용자가 가고자 했던 자원정보를 저장한다 그러면 로그인에 성공을 하게 되면 이전에 사용자가 접근하려고 했던 서버자원으로 이동하게 처리한다 (RequestCache)
  • 예외가 발생하기전 파라메터 값과 헤더값을 저장한다 (SavedRequest)

 

 

AccessDeniedExeption

  • SecurityIntercepter 클래스가 AccessDeniedExeption 예와처리를 한다 SecurityIntercepter 이필터 전에 처리과정은ExceptionTranslationFilter 가 되겠다.

 

https://www.inflearn.com/course/%EC%BD%94%EC%96%B4-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0

 

  • 사용자가 인증을 받지 않고 서버자원에 접근시도 하려고 한다 FilterSecurityInterceptor가 요청을 받고 있다 현재 이사용자는 
  • 인증을 받지 않아서 인가예외를 발생시킨다 익명 사용자 또는 RememberMe를 통해 접근 하게 되면 인증이 아니라 인가예외로 간다
  • 하지만 처리 하는과정은 AuthenticationException으로 전달받아서 예외처리를 하게된다 

 

  • SecurityContext(인증객체저장소) 에서 인증객체를 null 처리하고 AuthenticationEntryPoint 호출해서 로그인페이지로 가게 한다

 

  • 예외가 발생하기 이전에 USER 정보와 접근하려 했던  서버자원을 DefaultSvedRequest에 전달되고 저장되어진 user 객체는 Session에저장된다. 이과정은 HttpSessionRequestCache가 관리한

 

  • 사용자가 인증을 받았지만 설정된 권한정보가 user 라고 한다면 admin에 접근할수 없기 때문에 인가예외가 발생한다.

 

  • AccessDeniedException -> AccessDeniedHandler ->response.redirect(/denied) 이자원에 접근할수 없다고 확인 하는 페이지를 호출한다 

 

 

필자는 두가지 API만 사용하기로 했다. // authenticationEntryPoint , accessDeniedHandler  //

 

authenticationEntryPoint - 인증예외를 처리 

accessDeniedHandler - 인가 예외 처리

 

보면 request, response ,authException 파라메터가 전달 받고 있다.

인증예외가 발생되면 로그인 페이지로 이동하게 하고 인가예외가 발생하면 denied 페이지로 이동하게끔 했다.

 

 

사용자가 로그인을 성공하게 되면 가고자 했던 자원의 요청정보가 저장된다고 했는데 successHandler를 사용해서 익명객체를 이용해

세션으로 부터 꺼내와서 인증에 성공하면 가고자 했던 url로 가게끔 처리를 했다. 

 

RequestCache - ExceptionTranslationFilter에서 사용자가 가고자 했던 요청정보를 RequestCache 활용해서 세션에 이미 저장되어 있는 상태다 getRquest로 저장되었던 세션의정보들을 가지고 올수 있다.

 

SavedRequest  -  getRequest 여기서 사용자가 가고자 했던 url를 참조할수가 있다.

 

response.sendRedirect(redirectUrl) - 이제 인증에 성공하게 되면 가고자 했더 url로 이동하도록 처리 했다

 

 

 

현재 모든 요청에도 인증을 받아야만 접근할수 있기 때문에 로그인으로 인증을 받지 않으면 로그인 페이지로 이동할수 있도록 permitAll()로 처리 했다.

 

 

ExceptionTranslationFilter.java

 

현재는 루트 페이지도 인증을 받지 않으면 접근이 불가능하다. 그래서 login페이지로 이동하게된다.  

현재 사용자는 인증을 받지 않은 익명 사용자 이다 하지만 인증자체를 받지 않았기 때문에 isAnonymous를 호출하여 

인증예외때 처리하는 구문을 호출한다

 

 

ExceptionTranslationFilter.java

SecurityContextHolder 여기서 인증객체 월레 저장되어 있던 인증객체를 null로 만든다

requestCache.saveRequest 사용자가 접근하고자 하는 url정보를 담고 있다.

 

 

 

HttpSessionRequestCache.java

if (requestMatcher.matches(request)) - 현재 요청하고자 하는 자원정보를 session에 저장한다  request.getSession().setAttribute(this.sessionAttrName, savedRequest) - 이 코드를 보면  객체를 저장하고 있다.

그리고 authenticationEntryPoint(ExceptionTranslationFilter.java)구현체를 호출하고 있다. 현재 필자는 위에 보면 익명 객체를 사용해서 구현을 했다.

 



필자는 "user"권한을 가진 계정으로 로그인을 했고 처음에 인증받기전 url정보를 세션에서 가지고와서 이동하게끔 처리 했다.

그리고 user권한을 가진 계정사용자는 admin 으로 접속이 불가능하다 만약 서버자원을 접근하려고 한다면 denied으로 이동하게끔 처리 하였다. 

 

ExceptionTranslationFilter.java

이렇게 되면  isAnonymous 익명사용자의 조건이 안되기 때문에 곧바로 accessDeniedHandler를 호출하게된다.

 

 

 

 

RequestCacheAwareFilter.java

 

RequestCache는 인증예외가 발생하기전에 사용자가 가고했던 url의 정보를 담고 있다.

그리고 이객체가 존재하는지를 판단하게 되는데 그 객체가  null이 아닐경우에 다음 필터로 넘겨주는 역활을 하는 클래스이다.

미리 저장된 데이터를 전달하여 활용할수 있도록 한다.

 

 

오늘은 사용자가 인증과 인가를 받기전 처리되는 로직과 예외가 발생하는 로직들을 알아봤다 

반응형

'SpringSecurity' 카테고리의 다른 글

SpringSecurity(위임필터 초기화)  (0) 2020.11.03
SpringSecurity(CSRF,CsrFilter)  (0) 2020.11.03
SringSecurity(기본API & Filter이해)  (0) 2020.11.01
SpringSecurity(세션제어API)  (0) 2020.10.31
SpringSecurity(세션제어 Filter)  (0) 2020.10.31