◻ 스프링 기반의 어플리케이션의 보안을 담당하는 하위 프레임워크표준이다.
◻ java 애플리케이션에 인증 및 권한 부여를 모두 제공하는데 중점을 둔 프레임워크이다.
특징
인증 및 권한 부여에 대한 포괄적이고 확장 가능한 지원
세션 고정, 클릭재킹, 교차 사이트 요청 위조 등과 같은 공격으로부터 보호
서블릿 API 통합
Spring Web MVC와의 선택적 통합 그외 등등.
◻ 접근 주체(Principal) : 보호된 리소스에 접근하는 대상
◻ 인증(Authentication) : 보호된 리소스에 접근한 대상에 대해 이 유저가 누구인지, 애플리케이션의 작업을 수행해도 되는 주체인지 확인하는 과정(ex. Form 기반 Login)
◻ 인가(Authorize) : 해당 리소스에 대해 접근 가능한 권한을 가지고 있는지 확인하는 과정(After Authentication, 인증 이후)
◻ 권한 : 어떠한 리소스에 대한 접근 제한, 모든 리소스는 접근 제어 권한이 걸려있다. 즉, 인가 과정에서 해당 리소스에 대한 제한된 최소한의 권한을 가졌는지 확인.
<해당 flow의 동작과정>
user가 관련 loginForm을 이용하여 로그인 정보를 입력하고 인증요청을 보낸다.
AuthenticationFilter가 httpServletRequest에 있는 user의 아이디와 패스워드를 intercept한다. 그후 validation을 위한 null여부를 판단하고 UsernamePasswordAuthenticationToken을 생성=> 인증용, 커스터마이징 가능
AuthenticationManager는 Authentication 형식으로 된 인증용 객체를 전달 받고 AuthenticationManager에게 처리를 위임한다.
Token을 처리가능한 Authentication Provider를 선택해서 실제 인증할 Provider에게 객체를 다시 전달.
인증을위해 AuthenticationProvider인터페이스가 실행, DB의 정보와 입력받은 로그인 정보를 비교한다.
UserDetailsService의 LoadUserByUsername 메소드를 실행해서 DB에 등록된 사용자인지 파악한다. 만약 등록된 사용자라면 해당 USER정보와 권한등을 해당 UserDeatils의 구현체 지역변수에 저장
getUsername, getPassword, getAuthorities등의 메소드로 가져오기 가능.
인증이 완료된 해당정보를 생성한 Authentication 객체에 담고 이를
SecurityContextHolder에 담은 이후 AuthenticationSuccessHandler를 실행한다.
💨 즉 filter를 통해 요청이 들어온 정보들의 validation이 이루어지고, 이상이 없다면 token을 생성하여 Authentication Provider를 통해 인증이 이루어진다. 해당정보가 맞다면 SecurityContextHolder 에 사용자 정보가 담기게 된다.
📍 DelegatingFilterProxy
📍📍 ServletFilter
◻ servlet 스펙 2.3부터 도입됨. servlet으로 요청이 들어가기 전, 후에 동작
◻ servlet 컨테이너가 만들고 관리
◻ 스프링에서 만든 내용을 주입받아 사용할 수 없음
📍📍 DelegatingFilterProxy
◻ servlet 필터를 거친 요청을 Spring Bean에 위임시키는 역할
◻ servlet컨테이너가 초기화될 때 servletFilter로 등록됨
◻ ApplicationContext에서 springSecurityFilterChain을 찾아 보안처리 위임
📍 FilterChainProxy
◻ springSecurityFilterChain이름으로 생성되는 스프링 빈
스프링 시큐리티가 초기화될 때 관리할 필터들을 결정(기본필터 + 설정을 통한 추가필터)
◻ 필터를 순서대로 호출해서 사용자 요청을 각각의 필터에 전달
◻ 마지막 필터까지 예외가 발생하지 않으면 인증 통과
<동작과정>
- 서블릿 컨테이너 초기화할 때 SpringSecurity의 DelegatingFilterProxy를 서블릿 필터로 등록
- ApplicationContext 초기화 될 때 springSecurityFilterChain 이름으로 설정된 securityFilter들을 가진 FilterChainProxy 등록
- 서블릿 request가 들어오면 서블릿은 DelegatingFilterProxy를 통해 FilterChainProxy로 request를 보내 보안작업을 위임시킴
- FilterChainProxy는 보안 작업을 수행
- 보안 작업이 완료되면 서버로 요청 전달(DispatherServlet)
📍 SecurityContextPersistenceFilter : SecurityContextRepository에서 SecurityContext를 가져오거나 저장하는 역할을 한다.
📍 LogoutFilter : 설정된 로그아웃 URL로 오는 요청을 감시하며, 해당 유저를 로그아웃 처리
📍 (UsernamePassword)AuthenticationFilter : (아이디와 비밀번호를 사용하는 form 기반 인증) 설정된 로그인 URL로 오는 요청을 감시하며, 유저 인증 처리 AuthenticationManager를 통한 인증 실행
◻ 인증 성공 시, 얻은 Authentication 객체를 SecurityContext에 저장 후 AuthenticationSuccessHandler 실행
◻ 인증 실패 시, AuthenticationFailureHandler 실행
DefaultLoginPageGeneratingFilter : 인증을 위한 로그인폼 URL을 감시한다.
📍 BasicAuthenticationFilter : HTTP 기본 인증 헤더를 감시하여 처리한다.
📍 RequestCacheAwareFilter : 로그인 성공 후, 원래 요청 정보를 재구성하기 위해 사용된다.
📍 SecurityContextHolderAwareRequestFilter : HttpServletRequestWrapper를 상속한 SecurityContextHolderAwareRequestWapper 클래스로 HttpServletRequest 정보를 감싼다. SecurityContextHolderAwareRequestWrapper 클래스는 필터 체인상의 다음 필터들에게 부가정보를 제공한다.
📍 AnonymousAuthenticationFilter : 이 필터가 호출되는 시점까지 사용자 정보가 인증되지 않았다면 인증토큰에 사용자가 익명 사용자로 나타난다.
📍 SessionManagementFilter : 이 필터는 인증된 사용자와 관련된 모든 세션을 추적한다.
📍 ExceptionTranslationFilter : 이 필터는 보호된 요청을 처리하는 중에 발생할 수 있는 예외를 위임하거나 전달하는 역할을 한다.
📍 FilterSecurityInterceptor : 이 필터는 AccessDecisionManager 로 권한부여 처리를 위임함으로써 접근 제어 결정을 쉽게해준다.
public class exampleAuth implements Authentication {
@Override
public boolean implies(Subject subject) {
return Authentication.super.implies(subject);
}
@Override
public String getName() {
return null;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
@Override
public Object getCredentials() {
return null;
}
@Override
public Object getDetails() {
return null;
}
@Override
public Object getPrincipal() {
return null;
}
@Override
public boolean isAuthenticated() {
return false;
}
@Override
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
}
}
위와 같이 해당 user 아이디, 인증여부, 비밀번호등을 get해서 가져 올 수 있음을 알 수 있다.
public class exampleAuth implements AuthenticationManager {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
Authentication auth = new UsernamePasswordAuthenticationToken(username,"",getAuthrities);
Authentication auth2= authentication.setAuthenticated(auth);
SecurityContextHolder.getContext().setAuthentication(auth2);
return null;
}
}
authentication Manager는 실제로 인증을 처리할 여러개의 AuthenticationProvider를 가지고 있다.
https://spring.io/projects/spring-security#overview
https://velog.io/@seongwon97/Spring-Security-Filter%EB%9E%80
https://mangkyu.tistory.com/77
https://velog.io/@kyungwoon/Spring-Security-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC
https://dotheright.tistory.com/355