Skip to content

Add new configuration options for OAuth2LoginSpec #6462

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

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -53,6 +53,7 @@
import org.springframework.security.oauth2.client.web.server.OAuth2AuthorizationCodeGrantWebFilter;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update Copyright header to 2019

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done and updated the unit test in OAuth2LoginTests

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome thanks! This looks great and it's ready to be merged. But before we merge can you please squash to 1 commit and update the commit message to follow this format.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All done.

import org.springframework.security.oauth2.client.web.server.OAuth2AuthorizationRequestRedirectWebFilter;
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizationCodeAuthenticationTokenConverter;
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizationRequestResolver;
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
import org.springframework.security.oauth2.client.web.server.authentication.OAuth2LoginAuthenticationWebFilter;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
Expand Down Expand Up @@ -588,6 +589,10 @@ public class OAuth2LoginSpec {

private ServerAuthenticationConverter authenticationConverter;

private ServerOAuth2AuthorizationRequestResolver authorizationRequestResolver;

private ServerWebExchangeMatcher authenticationMatcher;

/**
* Configures the {@link ReactiveAuthenticationManager} to use. The default is
* {@link OAuth2AuthorizationCodeReactiveAuthenticationManager}
Expand Down Expand Up @@ -664,6 +669,23 @@ public OAuth2LoginSpec authorizedClientRepository(ServerOAuth2AuthorizedClientRe
return this;
}

public OAuth2LoginSpec authorizationRequestResolver(ServerOAuth2AuthorizationRequestResolver authorizationRequestResolver) {
this.authorizationRequestResolver = authorizationRequestResolver;
return this;
}

public OAuth2LoginSpec authenticationMatcher(ServerWebExchangeMatcher authenticationMatcher) {
this.authenticationMatcher = authenticationMatcher;
return this;
}

private ServerWebExchangeMatcher getAuthenticationMatcher() {
if (this.authenticationMatcher == null) {
this.authenticationMatcher = createAttemptAuthenticationRequestMatcher();
}
return this.authenticationMatcher;
}

/**
* Allows method chaining to continue configuring the {@link ServerHttpSecurity}
* @return the {@link ServerHttpSecurity} to continue configuring
Expand All @@ -676,12 +698,12 @@ public ServerHttpSecurity and() {
protected void configure(ServerHttpSecurity http) {
ReactiveClientRegistrationRepository clientRegistrationRepository = getClientRegistrationRepository();
ServerOAuth2AuthorizedClientRepository authorizedClientRepository = getAuthorizedClientRepository();
OAuth2AuthorizationRequestRedirectWebFilter oauthRedirectFilter = new OAuth2AuthorizationRequestRedirectWebFilter(clientRegistrationRepository);
OAuth2AuthorizationRequestRedirectWebFilter oauthRedirectFilter = getRedirectWebFilter();

ReactiveAuthenticationManager manager = getAuthenticationManager();

AuthenticationWebFilter authenticationFilter = new OAuth2LoginAuthenticationWebFilter(manager, authorizedClientRepository);
authenticationFilter.setRequiresAuthenticationMatcher(createAttemptAuthenticationRequestMatcher());
authenticationFilter.setRequiresAuthenticationMatcher(getAuthenticationMatcher());
authenticationFilter.setServerAuthenticationConverter(getAuthenticationConverter(clientRegistrationRepository));
RedirectServerAuthenticationSuccessHandler redirectHandler = new RedirectServerAuthenticationSuccessHandler();

Expand Down Expand Up @@ -756,6 +778,16 @@ private ReactiveClientRegistrationRepository getClientRegistrationRepository() {
return this.clientRegistrationRepository;
}

private OAuth2AuthorizationRequestRedirectWebFilter getRedirectWebFilter() {
OAuth2AuthorizationRequestRedirectWebFilter oauthRedirectFilter;
if (this.authorizationRequestResolver == null) {
oauthRedirectFilter = new OAuth2AuthorizationRequestRedirectWebFilter(getClientRegistrationRepository());
} else {
oauthRedirectFilter = new OAuth2AuthorizationRequestRedirectWebFilter(this.authorizationRequestResolver);
}
return oauthRedirectFilter;
}

private ServerOAuth2AuthorizedClientRepository getAuthorizedClientRepository() {
ServerOAuth2AuthorizedClientRepository result = this.authorizedClientRepository;
if (result == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -37,6 +37,7 @@
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.InMemoryReactiveClientRegistrationRepository;
import org.springframework.security.oauth2.client.userinfo.ReactiveOAuth2UserService;
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizationRequestResolver;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.TestOAuth2AccessTokens;
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
Expand All @@ -59,6 +60,7 @@
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.WebFilterChainProxy;
import org.springframework.security.web.server.authentication.ServerAuthenticationConverter;
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
Expand Down Expand Up @@ -100,7 +102,7 @@ public class OAuth2LoginTests {

@Test
public void defaultLoginPageWithMultipleClientRegistrationsThenLinks() {
this.spring.register(OAuth2LoginWithMulitpleClientRegistrations.class).autowire();
this.spring.register(OAuth2LoginWithMultipleClientRegistrations.class).autowire();

WebTestClient webTestClient = WebTestClientBuilder
.bindToWebFilters(this.springSecurity)
Expand All @@ -120,7 +122,7 @@ public void defaultLoginPageWithMultipleClientRegistrationsThenLinks() {
}

@EnableWebFluxSecurity
static class OAuth2LoginWithMulitpleClientRegistrations {
static class OAuth2LoginWithMultipleClientRegistrations {
@Bean
InMemoryReactiveClientRegistrationRepository clientRegistrationRepository() {
return new InMemoryReactiveClientRegistrationRepository(github, google);
Expand Down Expand Up @@ -165,6 +167,8 @@ public void oauth2LoginWhenCustomObjectsThenUsed() {
.getBean(OAuth2LoginMockAuthenticationManagerConfig.class);
ServerAuthenticationConverter converter = config.authenticationConverter;
ReactiveAuthenticationManager manager = config.manager;
ServerWebExchangeMatcher matcher = config.matcher;
ServerOAuth2AuthorizationRequestResolver resolver = config.resolver;

OAuth2AuthorizationExchange exchange = TestOAuth2AuthorizationExchanges.success();
OAuth2User user = TestOAuth2Users.create();
Expand All @@ -174,6 +178,8 @@ public void oauth2LoginWhenCustomObjectsThenUsed() {

when(converter.convert(any())).thenReturn(Mono.just(new TestingAuthenticationToken("a", "b", "c")));
when(manager.authenticate(any())).thenReturn(Mono.just(result));
when(matcher.matches(any())).thenReturn(ServerWebExchangeMatcher.MatchResult.match());
when(resolver.resolve(any())).thenReturn(Mono.empty());

webTestClient.get()
.uri("/login/oauth2/code/github")
Expand All @@ -182,6 +188,8 @@ public void oauth2LoginWhenCustomObjectsThenUsed() {

verify(converter).convert(any());
verify(manager).authenticate(any());
verify(matcher).matches(any());
verify(resolver).resolve(any());
}

@Configuration
Expand All @@ -190,6 +198,10 @@ static class OAuth2LoginMockAuthenticationManagerConfig {

ServerAuthenticationConverter authenticationConverter = mock(ServerAuthenticationConverter.class);

ServerWebExchangeMatcher matcher = mock(ServerWebExchangeMatcher.class);

ServerOAuth2AuthorizationRequestResolver resolver = mock(ServerOAuth2AuthorizationRequestResolver.class);

@Bean
public SecurityWebFilterChain springSecurityFilter(ServerHttpSecurity http) {
http
Expand All @@ -198,14 +210,16 @@ public SecurityWebFilterChain springSecurityFilter(ServerHttpSecurity http) {
.and()
.oauth2Login()
.authenticationConverter(authenticationConverter)
.authenticationManager(manager);
.authenticationManager(manager)
.authenticationMatcher(matcher)
.authorizationRequestResolver(resolver);
return http.build();
}
}

@Test
public void oauth2LoginWhenCustomJwtDecoderFactoryThenUsed() {
this.spring.register(OAuth2LoginWithMulitpleClientRegistrations.class,
this.spring.register(OAuth2LoginWithMultipleClientRegistrations.class,
OAuth2LoginWithJwtDecoderFactoryBeanConfig.class).autowire();

WebTestClient webTestClient = WebTestClientBuilder
Expand Down