1. 소개
이 사용방법(예제)에서는 AuthenticationManagerResolver 를 소개 한 다음 기본 및 OAuth2 인증 흐름에 사용하는 방법을 보여줍니다.
2. AuthenticationManager 란 무엇입니까 ?
간단히 말해 AuthenticationManager 는 인증 을위한 주요 전략 인터페이스입니다.
입력 인증의 주체가 유효하고 확인 된 경우 AuthenticationManager # authenticate 는 인증 된 플래그가 true로 설정된 Authentication 인스턴스를 반환 합니다 . 그렇지 않으면 주체가 유효하지 않으면 AuthenticationException이 발생 합니다. 마지막 경우에 결정할 수 없으면 null 을 반환합니다 .
ProviderManager 는 AuthenticationManager 의 기본 구현입니다 . 인증 프로세스를 AuthenticationProvider 인스턴스 List에 위임합니다 .
WebSecurityConfigurerAdapter 를 확장하면 전역 또는 로컬 AuthenticationManager를 설정할 수 있습니다 . 로컬 AuthenticationManager의 경우 configure (AuthenticationManagerBuilder)를 재정의 할 수 있습니다 .
AuthenticationManagerBuilder 는 UserDetailService , AuthenticationProvider 및 기타 의존성을쉽게 설정하여 AuthenticationManager 를 빌드하는도우미 클래스입니다.
전역 AuthenticationManager의 경우 AuthenticationManager 를 빈으로 정의해야합니다 .
3. 왜 AuthenticationManagerResolver 인가?
AuthenticationManagerResolver를 사용하면 Spring이 컨텍스트별로 AuthenticationManager를 선택할 수 있습니다 . 버전 5.2.0의 Spring Security에 추가 된 새로운 기능입니다 .
public interface AuthenticationManagerResolver<C> {
AuthenticationManager resolve(C context);
}
AuthenticationManagerResolver # resolve 는 일반 컨텍스트를 기반으로 AuthenticationManager 의 인스턴스를 반환 할 수 있습니다 . 즉 , 이에 따라 AuthenticationManager 를 해결하려면 클래스를 컨텍스트로 설정할 수 있습니다 .
Spring Security는 HttpServletRequest 및 ServerWebExchange 를 컨텍스트로 사용 하여 AuthenticationManagerResolver 를 인증 흐름에 통합했습니다 .
4. 사용 시나리오
실제로 AuthenticationManagerResolver 를 사용하는 방법을 살펴 보겠습니다 .
예를 들어, 직원과 고객이라는 두 그룹의 사용자가있는 시스템을 가정 해보십시오. 이 두 그룹에는 특정 인증 논리가 있으며 별도의 데이터 저장소가 있습니다. 또한 이러한 그룹 중 하나의 사용자는 관련 URL 만 호출 할 수 있습니다.
5. AuthenticationManagerResolver 는 어떻게 작동합니까?
AuthenticationManager를 동적으로 선택해야하는 모든 곳에서 AuthenticationManagerResolver 를 사용할 수 있지만이 사용방법(예제)에서는 기본 제공 인증 흐름에서 사용하는 데 관심이 있습니다.
먼저 AuthenticationManagerResolver를 설정 한 다음 기본 및 OAuth2 인증에 사용합니다.
5.1. AuthenticationManagerResolver 설정
Security 구성을위한 클래스를 생성하는 것으로 시작하겠습니다. WebSecurityConfigurerAdapter 를 확장해야합니다 .
@Configuration
public class CustomWebSecurityConfigurer extends WebSecurityConfigurerAdapter {
// ...
}
그런 다음 고객에 대한 AuthenticationManager 를 반환하는 메서드를 추가해 보겠습니다 .
AuthenticationManager customersAuthenticationManager() {
return authentication -> {
if (isCustomer(authentication)) {
return new UsernamePasswordAuthenticationToken(/*credentials*/);
}
throw new UsernameNotFoundException(/*principal name*/);
};
}
의 AuthenticationManager 직원은 우리가 대체, 논리적으로 동일 isCustomer을 함께 isEmployee :
public AuthenticationManager employeesAuthenticationManager() {
return authentication -> {
if (isEmployee(authentication)) {
return new UsernamePasswordAuthenticationToken(/*credentials*/);
}
throw new UsernameNotFoundException(/*principal name*/);
};
}
마지막으로 요청 URL에 따라 확인 되는 AuthenticationManagerResolver 를 추가해 보겠습니다 .
AuthenticationManagerResolver<HttpServletRequest> resolver() {
return request -> {
if (request.getPathInfo().startsWith("/employee")) {
return employeesAuthenticationManager();
}
return customersAuthenticationManager();
};
}
5.2. 기본 인증의 경우
우리는 사용할 수 AuthenticationFilter를 동적으로 해결하기 위해 AuthenticationManager에 요청 당합니다. AuthenticationFilter 는 버전 5.2에서 Spring Security에 추가되었습니다.
Security 필터 체인에 추가하면 일치하는 모든 요청에 대해 먼저 인증 개체를 추출 할 수 있는지 여부를 확인합니다. 그렇다면 AuthenticationManagerResolver 에 적합한 AuthenticationManager 를 요청 하고 흐름을 계속합니다.
먼저 CustomWebSecurityConfigurer 에 AuthenticationFilter 를 생성하는 메서드를 추가해 보겠습니다 .
private AuthenticationFilter authenticationFilter() {
AuthenticationFilter filter = new AuthenticationFilter(
resolver(), authenticationConverter());
filter.setSuccessHandler((request, response, auth) -> {});
return filter;
}
No-op SuccessHandler 로 AuthenticationFilter # successHandler 를 설정하는 이유는 성공적인 인증 후 리디렉션의 기본 동작을 방지하기위한 것입니다.
그런 다음 CustomWebSecurityConfigurer 에서 WebSecurityConfigurerAdapter # configure (HttpSecurity) 를 재정 의하여이 필터를 Security 필터 체인에 추가 할 수 있습니다 .
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(
authenticationFilter(),
BasicAuthenticationFilter.class);
}
5.3. OAuth2 인증의 경우
BearerTokenAuthenticationFilter 는 OAuth2 인증을 담당합니다. BearerTokenAuthenticationFilter # doFilterInternal의 방법 A에 대한 체크 BearerTokenAuthenticationToken 요청에서, 그리고 가능한 경우, 그것은 적절한 해결 AuthenticationManager에이 토큰을 인증한다.
OAuth2ResourceServerConfigurer 는 BearerTokenAuthenticationFilter 를 설정하는 데 사용됩니다 .
따라서 WebSecurityConfigurerAdapter # configure (HttpSecurity)를 재정 의하여 CustomWebSecurityConfigurer 에서 리소스 서버에 대한 AuthenticationManagerResolver 를 설정할 수 있습니다 .
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.oauth2ResourceServer()
.authenticationManagerResolver(resolver());
}
6. 반응 형 애플리케이션에서 AuthenticationManager 해결
반응 형 웹 애플리케이션의 경우 컨텍스트에 따라 AuthenticationManager 를 해결하는 개념의 이점을 계속 누릴 수 있습니다 . 하지만 여기에 ReactiveAuthenticationManagerResolver가 대신 있습니다.
@FunctionalInterface
public interface ReactiveAuthenticationManagerResolver<C> {
Mono<ReactiveAuthenticationManager> resolve(C context);
}
ReactiveAuthenticationManager 의 Mono 를 반환합니다 . ReactiveAuthenticationManager 는 AuthenticationManager 와 반응 형 이므로 해당 인증 메서드는 Mono를 반환합니다 .
6.1. ReactiveAuthenticationManagerResolver 설정
Security 구성을위한 클래스를 생성하여 시작하겠습니다.
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class CustomWebSecurityConfig {
// ...
}
다음 으로이 클래스의 고객에 대해 ReactiveAuthenticationManager 를 정의 해 보겠습니다 .
ReactiveAuthenticationManager customersAuthenticationManager() {
return authentication -> customer(authentication)
.switchIfEmpty(Mono.error(new UsernameNotFoundException(/*principal name*/)))
.map(b -> new UsernamePasswordAuthenticationToken(/*credentials*/));
}
그런 다음 직원을위한 ReactiveAuthenticationManager 를 정의합니다 .
public ReactiveAuthenticationManager employeesAuthenticationManager() {
return authentication -> employee(authentication)
.switchIfEmpty(Mono.error(new UsernameNotFoundException(/*principal name*/)))
.map(b -> new UsernamePasswordAuthenticationToken(/*credentials*/));
}
마지막으로 시나리오를 기반으로 ReactiveAuthenticationManagerResolver 를 설정합니다 .
ReactiveAuthenticationManagerResolver<ServerWebExchange> resolver() {
return exchange -> {
if (match(exchange.getRequest(), "/employee")) {
return Mono.just(employeesAuthenticationManager());
}
return Mono.just(customersAuthenticationManager());
};
}
6.2. 기본 인증의 경우
반응 형 웹 애플리케이션에서 인증 을 위해 AuthenticationWebFilter 를 사용할 수 있습니다 . 요청을 인증하고 Security 컨텍스트를 채 웁니다.
AuthenticationWebFilter는 먼저 요청이 일치하는지 확인합니다. 그 후 요청에 인증 개체가 있으면 ReactiveAuthenticationManagerResolver 의 요청에 적합한 ReactiveAuthenticationManager 를 가져와 인증 흐름을 계속합니다.
따라서 Security 구성에서 사용자 정의 된 AuthenticationWebFilter 를 설정할 수 있습니다.
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
return http
.authorizeExchange()
.pathMatchers("/**")
.authenticated()
.and()
.httpBasic()
.disable()
.addFilterAfter(
new AuthenticationWebFilter(resolver()),
SecurityWebFiltersOrder.REACTOR_CONTEXT
)
.build();
}
먼저 ServerHttpSecurity # httpBasic 을 비활성화 하여 정상적인 인증 흐름을 방지 한 다음 수동으로이를 AuthenticationWebFilter로 바꾸고 사용자 지정 확인자를 전달합니다.
6.3. OAuth2 인증의 경우
ServerHttpSecurity # oauth2ResourceServer로 ReactiveAuthenticationManagerResolver 를 구성 할 수 있습니다 . ServerHttpSecurity # build 는 Security 필터 체인에 리졸버와 함께 AuthenticationWebFilter 의 인스턴스를 추가합니다 .
따라서 Security 구성에서 OAuth2 인증 필터에 대한 AuthenticationManagerResolver 를 설정해 보겠습니다 .
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
return http
// ...
.and()
.oauth2ResourceServer()
.authenticationManagerResolver(resolver())
.and()
// ...;
}
7. 결론
이 기사에서는 간단한 시나리오 내에서 기본 및 OAuth2 인증에 AuthenticationManagerResolver 를 사용했습니다 .
그리고, 승 e've 도의 사용 탐구 ReactiveAuthenticationManagerResolver을 모두 기본 및 OAuth2를 인증에 대한 반응 Spring 웹 응용 프로그램에서.
항상 그렇듯이 소스 코드는 GitHub에서 사용할 수 있습니다 . 우리의 반응 예제는 GitHub 에서도 사용할 수 있습니다 .
- https://docs.spring.io/spring-framework/docs/current/reference/html
- https://www.baeldung.com/spring-security-authenticationmanagerresolver
'Java' 카테고리의 다른 글
Spring Security 5의 새로운 비밀번호 저장소 (0) | 2021.04.12 |
---|---|
Spring Security 5의 기본 비밀번호 인코더 (0) | 2021.04.11 |
Spring Security를 사용한 수동 로그 아웃 (0) | 2021.04.11 |
스프링 Security 로그 아웃 리디렉션을 비활성화하는 방법 (0) | 2021.04.11 |
Spring Security를 사용하여 Amazon Cognito로 인증 (0) | 2021.04.11 |