Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split responsibility of ServerHttpBearerAuthenticationConverter #2

Open
eximius313 opened this issue Apr 5, 2018 · 1 comment
Open
Labels
enhancement New feature or request

Comments

@eximius313
Copy link

I think ServerHttpBearerAuthenticationConverter should be used only for preparing the token for further processing:

Mono.justOrEmpty(serverWebExchange)
                .map(JWTAuthorizationPayload::extract)

while authenticating the token:

map(VerifySignedJWT::check)
                .map(UsernamePasswordAuthenticationFromJWTToken::create)

is the responsibility of JWTReactiveAuthenticationManager

By the way - instead of providing own implementation of JWTAuthorizationWebFilter just do:

@Component
public class JWTAuthenticationWebFilter extends AuthenticationWebFilter {

    public JWTAuthenticationWebFilter(final JWTAuthenticationManager authenticationManager,
            final ServerHttpBearerAuthenticationConverter converter,
            final UnauthorizedAuthenticationEntryPoint entryPoint) {
        super(authenticationManager);
        setAuthenticationConverter(converter);
        setAuthenticationFailureHandler(new ServerAuthenticationEntryPointFailureHandler(entryPoint));
        setRequiresAuthenticationMatcher(new JWTHeadersExchangeMatcher()); //this is necessary to match headers. Requests without JWT header should not be taken into account by this filter
    }
    private static class JWTHeadersExchangeMatcher implements ServerWebExchangeMatcher {

        @Override
        public Mono<MatchResult> matches(final ServerWebExchange exchange) {
            return Mono.just(exchange)
                    .map(ServerWebExchange::getRequest)
                    .map(ServerHttpRequest::getHeaders)
                    .filter(h -> h.containsKey("some JWT header"))
                    .flatMap($ -> MatchResult.match())
                    .switchIfEmpty(MatchResult.notMatch());
        }
    }
}

And don't forget to set:

        http
            .exceptionHandling()
                .authenticationEntryPoint(new UnauthorizedAuthenticationEntryPoint ())
            .and()

where

@Component
public class UnauthorizedAuthenticationEntryPoint implements ServerAuthenticationEntryPoint {

	@Override
	public Mono<Void> commence(final ServerWebExchange exchange, final AuthenticationException e) {
		return Mono.fromRunnable(() -> exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED));
	}
}

otherwise SpringSecurity will still display BasicAuth on requests without headers

@raphaelDL
Copy link
Owner

🤔 thank you for your suggestion. I will go through this and see what I can do

@raphaelDL raphaelDL added the enhancement New feature or request label Apr 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants