technosap · 6 years ago
Text
Servlet Filter and Servlet Chain
Servlet Filter and Servlet Chain
Servlet Filter and Servelt Chain -We have looked at servlets that take requests directly from the server and return their results directly to the client. Servlets were designed as a generic server extension technology, however, rather than one devoted solely to performing CGIlike functions.
Most web servers that implement servlets have also implemented a feature called servlet chaining, where the…
View On WordPress
0 notes
joo-yoon · 5 years ago
Text
Webflux의 spring security formlogin에서 IP 받기
결론부터 말하면 간단히 되지 않는다.
인증에 username, password 외에 IP가 필요하다. 처음엔 ReactiveAuthenticationManager를 수정해서 IP만 받아오면 되겠다고 생각했다. 근데 Reactive가 어디 그런 정보를 어디서 주던가? method 체인으로 받아오지 않으면 안된다. 그래서 이 ReactiveAuthenticationManager의 authenticate를 호출하는 곳은 어디인가 찾아봤다.
그것은 AuthenticationFilter였다. FormLoginSpec은 내부에 ReactiveAuthenticationManager를 가지고 있다가 AuthenticationFilter에게 넘겨주어 SecurityWebFiltersOrder.FORM_LOGIN에서 사용하게 만든다. 아! 이제 찾았군.
filter에서 뭘하는지 보니 ReactiveAuthenticationManagerResolver가 ReactiveAuthenticationManager에게 token을 넘겨주고 있다.
private Mono<Void> authenticate(ServerWebExchange exchange, WebFilterChain chain, Authentication token) { WebFilterExchange webFilterExchange = new WebFilterExchange(exchange, chain); return this.authenticationManagerResolver.resolve(exchange.getRequest()) .flatMap(authenticationManager -> authenticationManager.authenticate(token)) .switchIfEmpty(Mono.defer(() -> Mono.error(new IllegalStateException("No provider found for " + token.getClass())))) .flatMap(authentication -> onAuthenticationSuccess(authentication, webFilterExchange)) .onErrorResume(AuthenticationException.class, e -> this.authenticationFailureHandler .onAuthenticationFailure(webFilterExchange, e)); }
이제 조금만 찾으면 된다. 이 token은 어디서 만드는거지? 아! filter에서 authenticationConverter를 통해서 만드는구나. 거기서 아마 username, password를 파싱해서 token을 만드는거겠군.
@Override public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) { return this.requiresAuthenticationMatcher.matches(exchange) .filter( matchResult -> matchResult.isMatch()) .flatMap( matchResult -> this.authenticationConverter.convert(exchange)) .switchIfEmpty(chain.filter(exchange).then(Mono.empty())) .flatMap( token -> authenticate(exchange, chain, token)); }
이제 다 찾았다고 생각했다. 이제 그 converter만 교체하면 된다. 근데...
protected void configure(ServerHttpSecurity http) { // ... AuthenticationWebFilter authenticationFilter = new AuthenticationWebFilter( this.authenticationManager); authenticationFilter.setRequiresAuthenticationMatcher(this.requiresAuthenticationMatcher); authenticationFilter.setAuthenticationFailureHandler(this.authenticationFailureHandler); authenticationFilter.setAuthenticationConverter(new ServerFormLoginAuthenticationConverter()); authenticationFilter.setAuthenticationSuccessHandler(this.authenticationSuccessHandler); authenticationFilter.setSecurityContextRepository(this.securityContextRepository); http.addFilterAt(authenticationFilter, SecurityWebFiltersOrder.FORM_LOGIN); }
다른 건 다 외부에서 받아와서 넘겨주는데 converter만 new ServerFormLoginAuthenticationConverter()로 넣고 있다. filter마저도 local변수다. 이걸 교체할 방법은? 없다. 직접 SecurityWebFiltersOrder.FORM_LOGIN를 처리하는 filter를 만드는 방법 뿐이다. ㅠㅠ
어디서부터 얼마나 만들어서 넣어야 하는지 이제부터 봐야한다.
0 notes