Spring Security Fundamentals(2)

Crow·2022년 11월 17일
0

InflearnOAuth2

목록 보기
4/12

2. Http Basic인증

Http Basic 인증 :

  • HTTP프로토콜은 액세스 제어와 인증을 위한 프레임워크를 제공하며
    가장 일반적인 인증 방식은 "Basic"인증 방식임
  • RFC 7235 표준이며 인증 프로토콜은 HTTP 인증 헤더에 기술되어 있음

HttpBasicConfigurer :

  • HTTP Basic 인증에 대한 초기화를 진행하면 속성들에 대한 기본값들을 설정

  • 기본 AuthenticationEntryPoint는 BasicAuthenticationEntryPoint임

  • 필터는 BasicAuthentication Filter를 사용함

BasicAuthenticationFilter :

  • 이 필터는 기본 인증 서비스를 제공하는 데 사용됨

  • BasicAuthenticationConverter를 사용해서 요청 헤더에 기술된 인증 정보의 유효성을 체크하며 Base64 인코딩된 username과 password를 추출함

  • 인증이 성공하면 Authentication이 SecurityContext에 저장되고 인증이 실패하면 Basic 인증을 통해 다시 인증하라는 메시지를 표시하는 BasicAuthenticationEntryPoint가 호출(invoke)됨

  • 인증 이후 세션을 사용하는 경우와 사용하지 않는 경우에 따라 처리되는 흐름에 차이가 있으며,
    세션을 사용하는 경우 매 요청 마다 인증과정을 거치지 않으나 세션을 사용하지 않는 경우 매 요청마다 인증과정을 거쳐야함

API


HttpBasicAPI 호출 필요시 customAuthenticationEntryPoint를 만들어서 설정할수있음

흐름도


모든 Spring Security 인증 처리는 필터 기반으로 이뤄짐

요청~인증절차를 완료한후 인증 객체 생성 그 후 authenticationIsRequired(username)을 이용해서 인증이 필요한지에 대해서 한번 더 체크함
인증을 이미 한번 받은 상태에선 그전에 추출한 username을 가지고 확인해서 Chain.doFilter로 보내줌

처음 인증을 하는거면 ProviderManager 호출해서 흐름을 다시 진행


BasicAuthenticationEntrtPoint처리

localhost:포트로 요청시 기본적으로 BasicAuthenticationEntrtPoint에서

@Override
	public void commence(HttpServletRequest request, HttpServletResponse response,
			AuthenticationException authException) throws IOException {
		response.addHeader("WWW-Authenticate", "Basic realm=\"" + this.realmName + "\"");
		response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());
	}

commence 메서드를 통해서 401 코드와 함께
response.addHeader("WWW-Authentication", "Basic realm=\"" + this.realmName + "\"");
를 응답해줌

(개발자 도구를 통해서 Response Headers에서 "WWW-Authentication"확인 가능)

따라서 브라우저가 로그인창을 띄워줌 그렇다면 만약 로그인에 성공한다면

개발자 도구의 Request Headers에서 Authorization항목에 Basic 인코딩된 값(임의의 값)으로 같이 보내진걸 확인 가능하며
Response Headers에서 "WWW-Authentication가 사라진걸 볼수있음

이상태에서 다시 접속한다면 HttpSession에 SecurityContext가 저장그 안에 authentication 객체가 존재하기 때문에 AuthenticationFilter에 존재하는 "authenticationIsRequired" 메서드를 통해서 기존 인증객체 존재 하는지
기존에 존재하던 인증 객체가 UsernamePasswordAuthenticationToken 타입이 맞는지

이미 인증받은 객체에서 가져온 Name하고 지금 Basic 문자열에서 추출한 user 네임하고 같는지 확인하고
이 authentication 객체가 타입이 AnonymousAuthentication인지 확인 하고 맞다면 다시 인증 받지 않고 서버에 접근 가능

response 헤더값을 바꿔본다면?

BasicAuthenticationEntrtPoint이 아닌 내가 만든 "CustomAuthenticationEntryPoint"에서

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        response.addHeader("WWWW-Authenticat", "Basic realm=localhost");
        response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());
    }

다음과 같이 의도적으로 오타를 내준다면 어떤 결과가 나올까?
답은 요청시 계속 401에러를 띄움(이걸로 확인 가능한건 인증(Authentication)실패후엔 헤더에 꼭 WWW-Authentication형태의 값을 보내줘야 한다


처음 Authentication성공후 Authentication처리 방식

Http Basic 인증 방식일지라도 우리가 인증 받는 방식인 Username과 Password를 인코딩한 문자열을 추출해서 추출된 문자열로부터 인증처리를 하는 과정이기 때문에 실질적으론 세션에서 저장한 값을 통해서 인증 처리할 필요가 없는 인증방식임

그러나 Spring Security에서는 인증받은 정보를 SecurityContext에 저장하고 그 SecurityContext를 다시 세션에 저장해서 다음에 인증 받을때는 다시금 인코딩된 문자열을 추출하지 않고 인증에 객체 상태를 보고 패스해줌

만약 Session을 사용하지 않는다면?

SecurityFulterChain에서
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

아예 세션안에 SecurityContext객체를 저장하지 않고
계속 새로운 Context를 만듬 당연히 인증객체 존재NullSecurityContextRepository클래스에서 아무런 작업 X
이럴땐 계속 Authentication과정을 통과해야함


내생각

로그인을 OAuth2와 JWT 토큰 방식으로 구현하면
위에서 나온 SessionCreationPolicy.STATELESS정책을 사용함

HTTP Basic내용 역시 사용하지도 않을 생각임


강의를 들으면서 많은걸 느끼는대
왜 이걸 사용하지 이건 무슨 클래스지 무슨 메서드인지 알아보는 이런 깊이있는 배움이 부족하다고 항상 생각됨

그리고 문서를 정리하는 실력이 너무 없는거 같음 다른사람꺼 참고를 많이 해봐야겠음(현재는 그냥 보면서 다 적고 필요없는 내용을 지우는 식이지만 그래도 너무 많은 내용이 기록됨)


출처

스프링 시큐리티 OAuth2 - Spring Boot 기반으로 개발하는 Spring Security OAuth2(https://www.inflearn.com/course/%EC%A0%95%EC%88%98%EC%9B%90-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0/dashboard)

profile
어제보다 개발 더 잘하기 / 많이 듣고 핵심만 정리해서 말하기 / 도망가지 말기 / 깃허브 위키 내용 가져오기

0개의 댓글