Merge remote-tracking branch 'upstream/0.4.x' into main
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.security.oauth2.server.authorization.authentication;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -87,7 +88,7 @@ public final class OAuth2ClientCredentialsAuthenticationProvider implements Auth
|
||||
throw new OAuth2AuthenticationException(OAuth2ErrorCodes.UNAUTHORIZED_CLIENT);
|
||||
}
|
||||
|
||||
Set<String> authorizedScopes = registeredClient.getScopes(); // Default to configured scopes
|
||||
Set<String> authorizedScopes = Collections.emptySet();
|
||||
if (!CollectionUtils.isEmpty(clientCredentialsAuthentication.getScopes())) {
|
||||
for (String requestedScope : clientCredentialsAuthentication.getScopes()) {
|
||||
if (!registeredClient.getScopes().contains(requestedScope)) {
|
||||
|
||||
@@ -211,6 +211,22 @@ public class OAuth2ClientCredentialsAuthenticationProviderTests {
|
||||
assertThat(accessTokenAuthentication.getAccessToken().getScopes()).isEqualTo(requestedScope);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authenticateWhenNoScopeRequestedThenAccessTokenDoesNotContainScope() {
|
||||
RegisteredClient registeredClient = TestRegisteredClients.registeredClient2().build();
|
||||
OAuth2ClientAuthenticationToken clientPrincipal = new OAuth2ClientAuthenticationToken(
|
||||
registeredClient, ClientAuthenticationMethod.CLIENT_SECRET_BASIC, registeredClient.getClientSecret());
|
||||
OAuth2ClientCredentialsAuthenticationToken authentication =
|
||||
new OAuth2ClientCredentialsAuthenticationToken(clientPrincipal, null, null);
|
||||
|
||||
when(this.jwtEncoder.encode(any()))
|
||||
.thenReturn(createJwt(Collections.singleton("mapped-scoped")));
|
||||
|
||||
OAuth2AccessTokenAuthenticationToken accessTokenAuthentication =
|
||||
(OAuth2AccessTokenAuthenticationToken) this.authenticationProvider.authenticate(authentication);
|
||||
assertThat(accessTokenAuthentication.getAccessToken().getScopes()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authenticateWhenAccessTokenNotGeneratedThenThrowOAuth2AuthenticationException() {
|
||||
RegisteredClient registeredClient = TestRegisteredClients.registeredClient2().build();
|
||||
|
||||
@@ -28,14 +28,17 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
|
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
||||
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
|
||||
import org.springframework.security.oauth2.core.oidc.OidcScopes;
|
||||
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||
import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationConsentService;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService;
|
||||
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
|
||||
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
|
||||
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
|
||||
import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
|
||||
import org.springframework.security.oauth2.server.authorization.settings.ProviderSettings;
|
||||
@@ -72,6 +75,7 @@ public class AuthorizationServerConfig {
|
||||
.exceptionHandling(exceptions ->
|
||||
exceptions.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"))
|
||||
)
|
||||
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
|
||||
.apply(authorizationServerConfigurer);
|
||||
return http.build();
|
||||
}
|
||||
@@ -89,6 +93,7 @@ public class AuthorizationServerConfig {
|
||||
.redirectUri("http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc")
|
||||
.redirectUri("http://127.0.0.1:8080/authorized")
|
||||
.scope(OidcScopes.OPENID)
|
||||
.scope(OidcScopes.PROFILE)
|
||||
.scope("message.read")
|
||||
.scope("message.write")
|
||||
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
|
||||
@@ -104,6 +109,11 @@ public class AuthorizationServerConfig {
|
||||
return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
|
||||
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ProviderSettings providerSettings() {
|
||||
return ProviderSettings.builder().issuer("http://localhost:9000").build();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020-2021 the original author or authors.
|
||||
* Copyright 2020-2022 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.
|
||||
@@ -23,6 +23,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
||||
import org.springframework.security.oauth2.core.oidc.OidcScopes;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsent;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
@@ -66,6 +67,9 @@ public class AuthorizationConsentController {
|
||||
authorizedScopes = Collections.emptySet();
|
||||
}
|
||||
for (String requestedScope : StringUtils.delimitedListToStringArray(scope, " ")) {
|
||||
if (OidcScopes.OPENID.equals(requestedScope)) {
|
||||
continue;
|
||||
}
|
||||
if (authorizedScopes.contains(requestedScope)) {
|
||||
previouslyApprovedScopes.add(requestedScope);
|
||||
} else {
|
||||
@@ -95,6 +99,10 @@ public class AuthorizationConsentController {
|
||||
private static final String DEFAULT_DESCRIPTION = "UNKNOWN SCOPE - We cannot provide information about this permission, use caution when granting this.";
|
||||
private static final Map<String, String> scopeDescriptions = new HashMap<>();
|
||||
static {
|
||||
scopeDescriptions.put(
|
||||
OidcScopes.PROFILE,
|
||||
"This application will be able to read your profile information."
|
||||
);
|
||||
scopeDescriptions.put(
|
||||
"message.read",
|
||||
"This application will be able to read your message."
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020-2021 the original author or authors.
|
||||
* Copyright 2020-2022 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.
|
||||
@@ -95,7 +95,7 @@ public class CustomConsentAuthorizationServerTests {
|
||||
assertThat(scope.isChecked()).isTrue();
|
||||
scopeIds.add(scope.getId());
|
||||
});
|
||||
assertThat(scopeIds).containsExactlyInAnyOrder("openid", "message.read", "message.write");
|
||||
assertThat(scopeIds).containsExactlyInAnyOrder("message.read", "message.write");
|
||||
|
||||
DomElement submitConsentButton = consentPage.querySelector("button[id='submit-consent']");
|
||||
this.webClient.getOptions().setRedirectEnabled(false);
|
||||
|
||||
@@ -32,9 +32,11 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
|
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
||||
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
|
||||
import org.springframework.security.oauth2.core.oidc.OidcScopes;
|
||||
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationConsentService;
|
||||
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService;
|
||||
@@ -63,7 +65,8 @@ public class AuthorizationServerConfig {
|
||||
http
|
||||
.exceptionHandling(exceptions ->
|
||||
exceptions.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"))
|
||||
);
|
||||
)
|
||||
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
|
||||
// @formatter:on
|
||||
return http.build();
|
||||
}
|
||||
@@ -81,6 +84,7 @@ public class AuthorizationServerConfig {
|
||||
.redirectUri("http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc")
|
||||
.redirectUri("http://127.0.0.1:8080/authorized")
|
||||
.scope(OidcScopes.OPENID)
|
||||
.scope(OidcScopes.PROFILE)
|
||||
.scope("message.read")
|
||||
.scope("message.write")
|
||||
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
|
||||
@@ -111,6 +115,11 @@ public class AuthorizationServerConfig {
|
||||
return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
|
||||
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ProviderSettings providerSettings() {
|
||||
return ProviderSettings.builder().issuer("http://localhost:9000").build();
|
||||
|
||||
@@ -34,9 +34,11 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
|
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
||||
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
|
||||
import org.springframework.security.oauth2.core.oidc.OidcScopes;
|
||||
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationConsentService;
|
||||
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService;
|
||||
@@ -62,6 +64,7 @@ public class AuthorizationServerConfig {
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
|
||||
http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
|
||||
http.apply(new FederatedIdentityConfigurer());
|
||||
return http.build();
|
||||
}
|
||||
@@ -84,6 +87,7 @@ public class AuthorizationServerConfig {
|
||||
.redirectUri("http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc")
|
||||
.redirectUri("http://127.0.0.1:8080/authorized")
|
||||
.scope(OidcScopes.OPENID)
|
||||
.scope(OidcScopes.PROFILE)
|
||||
.scope("message.read")
|
||||
.scope("message.write")
|
||||
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
|
||||
@@ -114,6 +118,11 @@ public class AuthorizationServerConfig {
|
||||
return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
|
||||
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ProviderSettings providerSettings() {
|
||||
return ProviderSettings.builder().issuer("http://localhost:9000").build();
|
||||
|
||||
@@ -22,7 +22,7 @@ spring:
|
||||
client-secret: secret
|
||||
authorization-grant-type: authorization_code
|
||||
redirect-uri: "http://127.0.0.1:8080/login/oauth2/code/{registrationId}"
|
||||
scope: openid
|
||||
scope: openid, profile
|
||||
client-name: messaging-client-oidc
|
||||
messaging-client-authorization-code:
|
||||
provider: spring
|
||||
|
||||
Reference in New Issue
Block a user