9 changed files with 923 additions and 0 deletions
@ -0,0 +1,414 @@
@@ -0,0 +1,414 @@
|
||||
/* |
||||
* Copyright 2004-present 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.security.config.annotation.web |
||||
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity |
||||
import org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization.* |
||||
import org.springframework.security.config.annotation.web.oauth2.server.authorization.OidcDsl |
||||
import org.springframework.security.oauth2.core.OAuth2Token |
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService |
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService |
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository |
||||
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings |
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator |
||||
|
||||
/** |
||||
* A Kotlin DSL to configure [HttpSecurity] OAuth 2.1 Authorization Server support using idiomatic Kotlin code. |
||||
* |
||||
* @author Mehrdad Bozorgmehr |
||||
* @since 7.0 |
||||
* @property registeredClientRepository the repository of registered clients. |
||||
* @property authorizationService the authorization service. |
||||
* @property authorizationConsentService the authorization consent service. |
||||
* @property authorizationServerSettings the authorization server settings. |
||||
* @property tokenGenerator the token generator. |
||||
*/ |
||||
@SecurityMarker |
||||
class OAuth2AuthorizationServerDsl { |
||||
var registeredClientRepository: RegisteredClientRepository? = null |
||||
var authorizationService: OAuth2AuthorizationService? = null |
||||
var authorizationConsentService: OAuth2AuthorizationConsentService? = null |
||||
var authorizationServerSettings: AuthorizationServerSettings? = null |
||||
var tokenGenerator: OAuth2TokenGenerator<out OAuth2Token>? = null |
||||
|
||||
private var clientAuthenticationConfig: ((OAuth2ClientAuthenticationConfigurer) -> Unit)? = null |
||||
private var authorizationServerMetadataEndpointConfig: ((OAuth2AuthorizationServerMetadataEndpointConfigurer) -> Unit)? = null |
||||
private var authorizationEndpointConfig: ((OAuth2AuthorizationEndpointConfigurer) -> Unit)? = null |
||||
private var pushedAuthorizationRequestEndpointConfig: ((OAuth2PushedAuthorizationRequestEndpointConfigurer) -> Unit)? = null |
||||
private var tokenEndpointConfig: ((OAuth2TokenEndpointConfigurer) -> Unit)? = null |
||||
private var tokenIntrospectionEndpointConfig: ((OAuth2TokenIntrospectionEndpointConfigurer) -> Unit)? = null |
||||
private var tokenRevocationEndpointConfig: ((OAuth2TokenRevocationEndpointConfigurer) -> Unit)? = null |
||||
private var deviceAuthorizationEndpointConfig: ((OAuth2DeviceAuthorizationEndpointConfigurer) -> Unit)? = null |
||||
private var deviceVerificationEndpointConfig: ((OAuth2DeviceVerificationEndpointConfigurer) -> Unit)? = null |
||||
private var clientRegistrationEndpointConfig: ((OAuth2ClientRegistrationEndpointConfigurer) -> Unit)? = null |
||||
private var oidcConfig: ((OidcConfigurer) -> Unit)? = null |
||||
|
||||
/** |
||||
* Configures OAuth 2.0 Client Authentication. |
||||
* |
||||
* Example: |
||||
* |
||||
* ``` |
||||
* @Configuration |
||||
* @EnableWebSecurity |
||||
* class SecurityConfig { |
||||
* |
||||
* @Bean |
||||
* fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { |
||||
* http { |
||||
* oauth2AuthorizationServer { |
||||
* clientAuthentication { |
||||
* // custom configuration |
||||
* } |
||||
* } |
||||
* } |
||||
* return http.build() |
||||
* } |
||||
* } |
||||
* ``` |
||||
* |
||||
* @param clientAuthenticationConfiguration custom configurations to configure OAuth 2.0 client authentication |
||||
*/ |
||||
fun clientAuthentication(clientAuthenticationConfiguration: OAuth2ClientAuthenticationConfigurer.() -> Unit) { |
||||
this.clientAuthenticationConfig = clientAuthenticationConfiguration |
||||
} |
||||
|
||||
/** |
||||
* Configures the OAuth 2.0 Authorization Server Metadata Endpoint. |
||||
* |
||||
* Example: |
||||
* |
||||
* ``` |
||||
* @Configuration |
||||
* @EnableWebSecurity |
||||
* class SecurityConfig { |
||||
* |
||||
* @Bean |
||||
* fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { |
||||
* http { |
||||
* oauth2AuthorizationServer { |
||||
* authorizationServerMetadataEndpoint { |
||||
* // custom configuration |
||||
* } |
||||
* } |
||||
* } |
||||
* return http.build() |
||||
* } |
||||
* } |
||||
* ``` |
||||
* |
||||
* @param authorizationServerMetadataEndpointConfiguration custom configurations to configure the metadata endpoint |
||||
*/ |
||||
fun authorizationServerMetadataEndpoint(authorizationServerMetadataEndpointConfiguration: OAuth2AuthorizationServerMetadataEndpointConfigurer.() -> Unit) { |
||||
this.authorizationServerMetadataEndpointConfig = authorizationServerMetadataEndpointConfiguration |
||||
} |
||||
|
||||
/** |
||||
* Configures the OAuth 2.0 Authorization Endpoint. |
||||
* |
||||
* Example: |
||||
* |
||||
* ``` |
||||
* @Configuration |
||||
* @EnableWebSecurity |
||||
* class SecurityConfig { |
||||
* |
||||
* @Bean |
||||
* fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { |
||||
* http { |
||||
* oauth2AuthorizationServer { |
||||
* authorizationEndpoint { |
||||
* // custom configuration |
||||
* } |
||||
* } |
||||
* } |
||||
* return http.build() |
||||
* } |
||||
* } |
||||
* ``` |
||||
* |
||||
* @param authorizationEndpointConfiguration custom configurations to configure the authorization endpoint |
||||
*/ |
||||
fun authorizationEndpoint(authorizationEndpointConfiguration: OAuth2AuthorizationEndpointConfigurer.() -> Unit) { |
||||
this.authorizationEndpointConfig = authorizationEndpointConfiguration |
||||
} |
||||
|
||||
/** |
||||
* Configures the OAuth 2.0 Pushed Authorization Request Endpoint. |
||||
* |
||||
* Example: |
||||
* |
||||
* ``` |
||||
* @Configuration |
||||
* @EnableWebSecurity |
||||
* class SecurityConfig { |
||||
* |
||||
* @Bean |
||||
* fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { |
||||
* http { |
||||
* oauth2AuthorizationServer { |
||||
* pushedAuthorizationRequestEndpoint { |
||||
* // custom configuration |
||||
* } |
||||
* } |
||||
* } |
||||
* return http.build() |
||||
* } |
||||
* } |
||||
* ``` |
||||
* |
||||
* @param pushedAuthorizationRequestEndpointConfiguration custom configurations to configure the PAR endpoint |
||||
*/ |
||||
fun pushedAuthorizationRequestEndpoint(pushedAuthorizationRequestEndpointConfiguration: OAuth2PushedAuthorizationRequestEndpointConfigurer.() -> Unit) { |
||||
this.pushedAuthorizationRequestEndpointConfig = pushedAuthorizationRequestEndpointConfiguration |
||||
} |
||||
|
||||
/** |
||||
* Configures the OAuth 2.0 Token Endpoint. |
||||
* |
||||
* Example: |
||||
* |
||||
* ``` |
||||
* @Configuration |
||||
* @EnableWebSecurity |
||||
* class SecurityConfig { |
||||
* |
||||
* @Bean |
||||
* fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { |
||||
* http { |
||||
* oauth2AuthorizationServer { |
||||
* tokenEndpoint { |
||||
* // custom configuration |
||||
* } |
||||
* } |
||||
* } |
||||
* return http.build() |
||||
* } |
||||
* } |
||||
* ``` |
||||
* |
||||
* @param tokenEndpointConfiguration custom configurations to configure the token endpoint |
||||
*/ |
||||
fun tokenEndpoint(tokenEndpointConfiguration: OAuth2TokenEndpointConfigurer.() -> Unit) { |
||||
this.tokenEndpointConfig = tokenEndpointConfiguration |
||||
} |
||||
|
||||
/** |
||||
* Configures the OAuth 2.0 Token Introspection Endpoint. |
||||
* |
||||
* Example: |
||||
* |
||||
* ``` |
||||
* @Configuration |
||||
* @EnableWebSecurity |
||||
* class SecurityConfig { |
||||
* |
||||
* @Bean |
||||
* fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { |
||||
* http { |
||||
* oauth2AuthorizationServer { |
||||
* tokenIntrospectionEndpoint { |
||||
* // custom configuration |
||||
* } |
||||
* } |
||||
* } |
||||
* return http.build() |
||||
* } |
||||
* } |
||||
* ``` |
||||
* |
||||
* @param tokenIntrospectionEndpointConfiguration custom configurations to configure the token introspection endpoint |
||||
*/ |
||||
fun tokenIntrospectionEndpoint(tokenIntrospectionEndpointConfiguration: OAuth2TokenIntrospectionEndpointConfigurer.() -> Unit) { |
||||
this.tokenIntrospectionEndpointConfig = tokenIntrospectionEndpointConfiguration |
||||
} |
||||
|
||||
/** |
||||
* Configures the OAuth 2.0 Token Revocation Endpoint. |
||||
* |
||||
* Example: |
||||
* |
||||
* ``` |
||||
* @Configuration |
||||
* @EnableWebSecurity |
||||
* class SecurityConfig { |
||||
* |
||||
* @Bean |
||||
* fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { |
||||
* http { |
||||
* oauth2AuthorizationServer { |
||||
* tokenRevocationEndpoint { |
||||
* // custom configuration |
||||
* } |
||||
* } |
||||
* } |
||||
* return http.build() |
||||
* } |
||||
* } |
||||
* ``` |
||||
* |
||||
* @param tokenRevocationEndpointConfiguration custom configurations to configure the token revocation endpoint |
||||
*/ |
||||
fun tokenRevocationEndpoint(tokenRevocationEndpointConfiguration: OAuth2TokenRevocationEndpointConfigurer.() -> Unit) { |
||||
this.tokenRevocationEndpointConfig = tokenRevocationEndpointConfiguration |
||||
} |
||||
|
||||
/** |
||||
* Configures the OAuth 2.0 Device Authorization Endpoint. |
||||
* |
||||
* Example: |
||||
* |
||||
* ``` |
||||
* @Configuration |
||||
* @EnableWebSecurity |
||||
* class SecurityConfig { |
||||
* |
||||
* @Bean |
||||
* fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { |
||||
* http { |
||||
* oauth2AuthorizationServer { |
||||
* deviceAuthorizationEndpoint { |
||||
* // custom configuration |
||||
* } |
||||
* } |
||||
* } |
||||
* return http.build() |
||||
* } |
||||
* } |
||||
* ``` |
||||
* |
||||
* @param deviceAuthorizationEndpointConfiguration custom configurations to configure the device authorization endpoint |
||||
*/ |
||||
fun deviceAuthorizationEndpoint(deviceAuthorizationEndpointConfiguration: OAuth2DeviceAuthorizationEndpointConfigurer.() -> Unit) { |
||||
this.deviceAuthorizationEndpointConfig = deviceAuthorizationEndpointConfiguration |
||||
} |
||||
|
||||
/** |
||||
* Configures the OAuth 2.0 Device Verification Endpoint. |
||||
* |
||||
* Example: |
||||
* |
||||
* ``` |
||||
* @Configuration |
||||
* @EnableWebSecurity |
||||
* class SecurityConfig { |
||||
* |
||||
* @Bean |
||||
* fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { |
||||
* http { |
||||
* oauth2AuthorizationServer { |
||||
* deviceVerificationEndpoint { |
||||
* // custom configuration |
||||
* } |
||||
* } |
||||
* } |
||||
* return http.build() |
||||
* } |
||||
* } |
||||
* ``` |
||||
* |
||||
* @param deviceVerificationEndpointConfiguration custom configurations to configure the device verification endpoint |
||||
*/ |
||||
fun deviceVerificationEndpoint(deviceVerificationEndpointConfiguration: OAuth2DeviceVerificationEndpointConfigurer.() -> Unit) { |
||||
this.deviceVerificationEndpointConfig = deviceVerificationEndpointConfiguration |
||||
} |
||||
|
||||
/** |
||||
* Configures the OAuth 2.0 Dynamic Client Registration Endpoint. |
||||
* |
||||
* Example: |
||||
* |
||||
* ``` |
||||
* @Configuration |
||||
* @EnableWebSecurity |
||||
* class SecurityConfig { |
||||
* |
||||
* @Bean |
||||
* fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { |
||||
* http { |
||||
* oauth2AuthorizationServer { |
||||
* clientRegistrationEndpoint { |
||||
* // custom configuration |
||||
* } |
||||
* } |
||||
* } |
||||
* return http.build() |
||||
* } |
||||
* } |
||||
* ``` |
||||
* |
||||
* @param clientRegistrationEndpointConfiguration custom configurations to configure the client registration endpoint |
||||
*/ |
||||
fun clientRegistrationEndpoint(clientRegistrationEndpointConfiguration: OAuth2ClientRegistrationEndpointConfigurer.() -> Unit) { |
||||
this.clientRegistrationEndpointConfig = clientRegistrationEndpointConfiguration |
||||
} |
||||
|
||||
/** |
||||
* Configures OpenID Connect 1.0 support (disabled by default). |
||||
* |
||||
* Example: |
||||
* |
||||
* ``` |
||||
* @Configuration |
||||
* @EnableWebSecurity |
||||
* class SecurityConfig { |
||||
* |
||||
* @Bean |
||||
* fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { |
||||
* http { |
||||
* oauth2AuthorizationServer { |
||||
* oidc { |
||||
* userInfoEndpoint { |
||||
* userInfoMapper = myUserInfoMapper |
||||
* } |
||||
* } |
||||
* } |
||||
* } |
||||
* return http.build() |
||||
* } |
||||
* } |
||||
* ``` |
||||
* |
||||
* @param oidcConfiguration custom configurations to configure OpenID Connect 1.0 support |
||||
* @see [OidcDsl] |
||||
*/ |
||||
fun oidc(oidcConfiguration: OidcDsl.() -> Unit) { |
||||
this.oidcConfig = OidcDsl().apply(oidcConfiguration).get() |
||||
} |
||||
|
||||
internal fun get(): (OAuth2AuthorizationServerConfigurer) -> Unit { |
||||
return { oauth2AuthorizationServer -> |
||||
registeredClientRepository?.also { oauth2AuthorizationServer.registeredClientRepository(it) } |
||||
authorizationService?.also { oauth2AuthorizationServer.authorizationService(it) } |
||||
authorizationConsentService?.also { oauth2AuthorizationServer.authorizationConsentService(it) } |
||||
authorizationServerSettings?.also { oauth2AuthorizationServer.authorizationServerSettings(it) } |
||||
tokenGenerator?.also { oauth2AuthorizationServer.tokenGenerator(it) } |
||||
clientAuthenticationConfig?.also { oauth2AuthorizationServer.clientAuthentication(it) } |
||||
authorizationServerMetadataEndpointConfig?.also { oauth2AuthorizationServer.authorizationServerMetadataEndpoint(it) } |
||||
authorizationEndpointConfig?.also { oauth2AuthorizationServer.authorizationEndpoint(it) } |
||||
pushedAuthorizationRequestEndpointConfig?.also { oauth2AuthorizationServer.pushedAuthorizationRequestEndpoint(it) } |
||||
tokenEndpointConfig?.also { oauth2AuthorizationServer.tokenEndpoint(it) } |
||||
tokenIntrospectionEndpointConfig?.also { oauth2AuthorizationServer.tokenIntrospectionEndpoint(it) } |
||||
tokenRevocationEndpointConfig?.also { oauth2AuthorizationServer.tokenRevocationEndpoint(it) } |
||||
deviceAuthorizationEndpointConfig?.also { oauth2AuthorizationServer.deviceAuthorizationEndpoint(it) } |
||||
deviceVerificationEndpointConfig?.also { oauth2AuthorizationServer.deviceVerificationEndpoint(it) } |
||||
clientRegistrationEndpointConfig?.also { oauth2AuthorizationServer.clientRegistrationEndpoint(it) } |
||||
oidcConfig?.also { oauth2AuthorizationServer.oidc(it) } |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
/* |
||||
* Copyright 2004-present 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.security.config.annotation.web.oauth2.server.authorization |
||||
|
||||
/** |
||||
* Marker annotation indicating that the annotated class is part of the OAuth2 Authorization Server Security DSL. |
||||
* |
||||
* @author Mehrdad Bozorgmehr |
||||
* @since 7.0 |
||||
*/ |
||||
@DslMarker |
||||
annotation class OAuth2AuthorizationServerSecurityMarker |
||||
|
||||
@ -0,0 +1,51 @@
@@ -0,0 +1,51 @@
|
||||
/* |
||||
* Copyright 2004-present 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.security.config.annotation.web.oauth2.server.authorization |
||||
|
||||
import org.springframework.security.authentication.AuthenticationProvider |
||||
import org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization.OidcClientRegistrationEndpointConfigurer |
||||
import org.springframework.security.web.authentication.AuthenticationConverter |
||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler |
||||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler |
||||
import java.util.function.Consumer |
||||
|
||||
/** |
||||
* A Kotlin DSL to configure the OpenID Connect Dynamic Client Registration 1.0 Endpoint using idiomatic Kotlin code. |
||||
* |
||||
* @author Mehrdad Bozorgmehr |
||||
* @since 7.0 |
||||
*/ |
||||
@OAuth2AuthorizationServerSecurityMarker |
||||
class OidcClientRegistrationEndpointDsl { |
||||
|
||||
var clientRegistrationRequestConverter: AuthenticationConverter? = null |
||||
var clientRegistrationRequestConverters: Consumer<MutableList<AuthenticationConverter>>? = null |
||||
var authenticationProviders: Consumer<MutableList<AuthenticationProvider>>? = null |
||||
var clientRegistrationResponseHandler: AuthenticationSuccessHandler? = null |
||||
var errorResponseHandler: AuthenticationFailureHandler? = null |
||||
|
||||
internal fun get(): (OidcClientRegistrationEndpointConfigurer) -> Unit { |
||||
return { clientRegistrationEndpoint -> |
||||
clientRegistrationRequestConverter?.also { clientRegistrationEndpoint.clientRegistrationRequestConverter(it) } |
||||
clientRegistrationRequestConverters?.also { clientRegistrationEndpoint.clientRegistrationRequestConverters(it) } |
||||
authenticationProviders?.also { clientRegistrationEndpoint.authenticationProviders(it) } |
||||
clientRegistrationResponseHandler?.also { clientRegistrationEndpoint.clientRegistrationResponseHandler(it) } |
||||
errorResponseHandler?.also { clientRegistrationEndpoint.errorResponseHandler(it) } |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,88 @@
@@ -0,0 +1,88 @@
|
||||
/* |
||||
* Copyright 2004-present 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.security.config.annotation.web.oauth2.server.authorization |
||||
|
||||
import org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization.OidcConfigurer |
||||
import org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization.OidcProviderConfigurationEndpointConfigurer |
||||
import org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization.OidcLogoutEndpointConfigurer |
||||
import org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization.OidcClientRegistrationEndpointConfigurer |
||||
import org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization.OidcUserInfoEndpointConfigurer |
||||
|
||||
/** |
||||
* A Kotlin DSL to configure OpenID Connect 1.0 support using idiomatic Kotlin code. |
||||
* |
||||
* @author Mehrdad Bozorgmehr |
||||
* @since 7.0 |
||||
*/ |
||||
@OAuth2AuthorizationServerSecurityMarker |
||||
class OidcDsl { |
||||
|
||||
private var providerConfigurationEndpointConfig: ((OidcProviderConfigurationEndpointConfigurer) -> Unit)? = null |
||||
private var logoutEndpointConfig: ((OidcLogoutEndpointConfigurer) -> Unit)? = null |
||||
private var clientRegistrationEndpointConfig: ((OidcClientRegistrationEndpointConfigurer) -> Unit)? = null |
||||
private var userInfoEndpointConfig: ((OidcUserInfoEndpointConfigurer) -> Unit)? = null |
||||
|
||||
/** |
||||
* Configures the OpenID Connect 1.0 Provider Configuration Endpoint. |
||||
* |
||||
* @param providerConfigurationEndpointConfiguration custom configuration to apply |
||||
*/ |
||||
fun providerConfigurationEndpoint(providerConfigurationEndpointConfiguration: OidcProviderConfigurationEndpointDsl.() -> Unit) { |
||||
this.providerConfigurationEndpointConfig = OidcProviderConfigurationEndpointDsl() |
||||
.apply(providerConfigurationEndpointConfiguration).get() |
||||
} |
||||
|
||||
/** |
||||
* Configures the OpenID Connect 1.0 RP-Initiated Logout Endpoint. |
||||
* |
||||
* @param logoutEndpointConfiguration custom configuration to apply |
||||
*/ |
||||
fun logoutEndpoint(logoutEndpointConfiguration: OidcLogoutEndpointDsl.() -> Unit) { |
||||
this.logoutEndpointConfig = OidcLogoutEndpointDsl() |
||||
.apply(logoutEndpointConfiguration).get() |
||||
} |
||||
|
||||
/** |
||||
* Configures the OpenID Connect Dynamic Client Registration 1.0 Endpoint. |
||||
* |
||||
* @param clientRegistrationEndpointConfiguration custom configuration to apply |
||||
*/ |
||||
fun clientRegistrationEndpoint(clientRegistrationEndpointConfiguration: OidcClientRegistrationEndpointDsl.() -> Unit) { |
||||
this.clientRegistrationEndpointConfig = OidcClientRegistrationEndpointDsl() |
||||
.apply(clientRegistrationEndpointConfiguration).get() |
||||
} |
||||
|
||||
/** |
||||
* Configures the OpenID Connect 1.0 UserInfo Endpoint. |
||||
* |
||||
* @param userInfoEndpointConfiguration custom configuration to apply |
||||
*/ |
||||
fun userInfoEndpoint(userInfoEndpointConfiguration: OidcUserInfoEndpointDsl.() -> Unit) { |
||||
this.userInfoEndpointConfig = OidcUserInfoEndpointDsl() |
||||
.apply(userInfoEndpointConfiguration).get() |
||||
} |
||||
|
||||
internal fun get(): (OidcConfigurer) -> Unit { |
||||
return { oidc -> |
||||
providerConfigurationEndpointConfig?.also { oidc.providerConfigurationEndpoint(it) } |
||||
logoutEndpointConfig?.also { oidc.logoutEndpoint(it) } |
||||
clientRegistrationEndpointConfig?.also { oidc.clientRegistrationEndpoint(it) } |
||||
userInfoEndpointConfig?.also { oidc.userInfoEndpoint(it) } |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,51 @@
@@ -0,0 +1,51 @@
|
||||
/* |
||||
* Copyright 2004-present 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.security.config.annotation.web.oauth2.server.authorization |
||||
|
||||
import org.springframework.security.authentication.AuthenticationProvider |
||||
import org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization.OidcLogoutEndpointConfigurer |
||||
import org.springframework.security.web.authentication.AuthenticationConverter |
||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler |
||||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler |
||||
import java.util.function.Consumer |
||||
|
||||
/** |
||||
* A Kotlin DSL to configure the OpenID Connect 1.0 RP-Initiated Logout Endpoint using idiomatic Kotlin code. |
||||
* |
||||
* @author Mehrdad Bozorgmehr |
||||
* @since 7.0 |
||||
*/ |
||||
@OAuth2AuthorizationServerSecurityMarker |
||||
class OidcLogoutEndpointDsl { |
||||
|
||||
var logoutRequestConverter: AuthenticationConverter? = null |
||||
var logoutRequestConverters: Consumer<MutableList<AuthenticationConverter>>? = null |
||||
var authenticationProviders: Consumer<MutableList<AuthenticationProvider>>? = null |
||||
var logoutResponseHandler: AuthenticationSuccessHandler? = null |
||||
var errorResponseHandler: AuthenticationFailureHandler? = null |
||||
|
||||
internal fun get(): (OidcLogoutEndpointConfigurer) -> Unit { |
||||
return { logoutEndpoint -> |
||||
logoutRequestConverter?.also { logoutEndpoint.logoutRequestConverter(it) } |
||||
logoutRequestConverters?.also { logoutEndpoint.logoutRequestConverters(it) } |
||||
authenticationProviders?.also { logoutEndpoint.authenticationProviders(it) } |
||||
logoutResponseHandler?.also { logoutEndpoint.logoutResponseHandler(it) } |
||||
errorResponseHandler?.also { logoutEndpoint.errorResponseHandler(it) } |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,42 @@
@@ -0,0 +1,42 @@
|
||||
/* |
||||
* Copyright 2004-present 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.security.config.annotation.web.oauth2.server.authorization |
||||
|
||||
import org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization.OidcProviderConfigurationEndpointConfigurer |
||||
import org.springframework.security.oauth2.server.authorization.oidc.OidcProviderConfiguration |
||||
import java.util.function.Consumer |
||||
|
||||
/** |
||||
* A Kotlin DSL to configure the OpenID Connect 1.0 Provider Configuration Endpoint using idiomatic Kotlin code. |
||||
* |
||||
* @author Mehrdad Bozorgmehr |
||||
* @since 7.0 |
||||
*/ |
||||
@OAuth2AuthorizationServerSecurityMarker |
||||
class OidcProviderConfigurationEndpointDsl { |
||||
|
||||
var providerConfigurationCustomizer: Consumer<OidcProviderConfiguration.Builder>? = null |
||||
|
||||
internal fun get(): (OidcProviderConfigurationEndpointConfigurer) -> Unit { |
||||
return { providerConfigurationEndpoint -> |
||||
providerConfigurationCustomizer?.also { |
||||
providerConfigurationEndpoint.providerConfigurationCustomizer(it) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,56 @@
@@ -0,0 +1,56 @@
|
||||
/* |
||||
* Copyright 2004-present 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.security.config.annotation.web.oauth2.server.authorization |
||||
|
||||
import org.springframework.security.authentication.AuthenticationProvider |
||||
import org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization.OidcUserInfoEndpointConfigurer |
||||
import org.springframework.security.oauth2.core.oidc.OidcUserInfo |
||||
import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcUserInfoAuthenticationContext |
||||
import org.springframework.security.web.authentication.AuthenticationConverter |
||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler |
||||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler |
||||
import java.util.function.Consumer |
||||
import java.util.function.Function |
||||
|
||||
/** |
||||
* A Kotlin DSL to configure the OpenID Connect 1.0 UserInfo Endpoint using idiomatic Kotlin code. |
||||
* |
||||
* @author Mehrdad Bozorgmehr |
||||
* @since 7.0 |
||||
*/ |
||||
@OAuth2AuthorizationServerSecurityMarker |
||||
class OidcUserInfoEndpointDsl { |
||||
|
||||
var userInfoRequestConverter: AuthenticationConverter? = null |
||||
var userInfoRequestConverters: Consumer<MutableList<AuthenticationConverter>>? = null |
||||
var authenticationProviders: Consumer<MutableList<AuthenticationProvider>>? = null |
||||
var userInfoResponseHandler: AuthenticationSuccessHandler? = null |
||||
var errorResponseHandler: AuthenticationFailureHandler? = null |
||||
var userInfoMapper: Function<OidcUserInfoAuthenticationContext, OidcUserInfo>? = null |
||||
|
||||
internal fun get(): (OidcUserInfoEndpointConfigurer) -> Unit { |
||||
return { userInfoEndpoint -> |
||||
userInfoRequestConverter?.also { userInfoEndpoint.userInfoRequestConverter(it) } |
||||
userInfoRequestConverters?.also { userInfoEndpoint.userInfoRequestConverters(it) } |
||||
authenticationProviders?.also { userInfoEndpoint.authenticationProviders(it) } |
||||
userInfoResponseHandler?.also { userInfoEndpoint.userInfoResponseHandler(it) } |
||||
errorResponseHandler?.also { userInfoEndpoint.errorResponseHandler(it) } |
||||
userInfoMapper?.also { userInfoEndpoint.userInfoMapper(it) } |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,161 @@
@@ -0,0 +1,161 @@
|
||||
/* |
||||
* Copyright 2004-present 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.security.config.annotation.web |
||||
|
||||
import com.nimbusds.jose.jwk.JWKSet |
||||
import com.nimbusds.jose.jwk.RSAKey |
||||
import com.nimbusds.jose.jwk.source.ImmutableJWKSet |
||||
import com.nimbusds.jose.jwk.source.JWKSource |
||||
import com.nimbusds.jose.proc.SecurityContext |
||||
import org.junit.jupiter.api.Test |
||||
import org.junit.jupiter.api.extension.ExtendWith |
||||
import org.springframework.beans.factory.annotation.Autowired |
||||
import org.springframework.context.annotation.Bean |
||||
import org.springframework.context.annotation.Configuration |
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity |
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity |
||||
import org.springframework.security.config.test.SpringTestContext |
||||
import org.springframework.security.config.test.SpringTestContextExtension |
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType |
||||
import org.springframework.security.oauth2.core.ClientAuthenticationMethod |
||||
import org.springframework.security.oauth2.jwt.JwtDecoder |
||||
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.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration |
||||
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings |
||||
import org.springframework.security.web.SecurityFilterChain |
||||
import org.springframework.test.web.servlet.MockMvc |
||||
import java.security.KeyPair |
||||
import java.security.KeyPairGenerator |
||||
import java.security.interfaces.RSAPublicKey |
||||
import java.util.UUID |
||||
|
||||
/** |
||||
* Tests for [OAuth2AuthorizationServerDsl] |
||||
* |
||||
* @author Mehrdad |
||||
*/ |
||||
@ExtendWith(SpringTestContextExtension::class) |
||||
class OAuth2AuthorizationServerDslTests { |
||||
@JvmField |
||||
val spring = SpringTestContext(this) |
||||
|
||||
@Autowired |
||||
lateinit var mockMvc: MockMvc |
||||
|
||||
@Test |
||||
fun `oauth2AuthorizationServer when custom registered client repository then configuration applies`() { |
||||
this.spring.register(AuthorizationServerConfig::class.java).autowire() |
||||
} |
||||
|
||||
@Configuration |
||||
@EnableWebSecurity |
||||
open class AuthorizationServerConfig { |
||||
@Bean |
||||
open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { |
||||
http { |
||||
oauth2AuthorizationServer { |
||||
registeredClientRepository = registeredClientRepository() |
||||
} |
||||
} |
||||
return http.build() |
||||
} |
||||
|
||||
@Bean |
||||
open fun registeredClientRepository(): RegisteredClientRepository { |
||||
val registeredClient = RegisteredClient.withId("test-client") |
||||
.clientId("test-client") |
||||
.clientSecret("{noop}secret") |
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC) |
||||
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) |
||||
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) |
||||
.redirectUri("http://localhost:8080/authorized") |
||||
.build() |
||||
return InMemoryRegisteredClientRepository(registeredClient) |
||||
} |
||||
|
||||
@Bean |
||||
open fun authorizationServerSettings(): AuthorizationServerSettings { |
||||
return AuthorizationServerSettings.builder().build() |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
fun `oauth2AuthorizationServer when oidc configured then oidc enabled`() { |
||||
this.spring.register(AuthorizationServerOidcConfig::class.java).autowire() |
||||
} |
||||
|
||||
@Configuration |
||||
@EnableWebSecurity |
||||
open class AuthorizationServerOidcConfig { |
||||
@Bean |
||||
open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { |
||||
http { |
||||
oauth2AuthorizationServer { |
||||
registeredClientRepository = registeredClientRepository() |
||||
oidc { |
||||
// Enable OIDC support |
||||
} |
||||
} |
||||
} |
||||
return http.build() |
||||
} |
||||
|
||||
@Bean |
||||
open fun registeredClientRepository(): RegisteredClientRepository { |
||||
val registeredClient = RegisteredClient.withId("test-client") |
||||
.clientId("test-client") |
||||
.clientSecret("{noop}secret") |
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC) |
||||
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) |
||||
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) |
||||
.redirectUri("http://localhost:8080/authorized") |
||||
.scope("openid") |
||||
.build() |
||||
return InMemoryRegisteredClientRepository(registeredClient) |
||||
} |
||||
|
||||
@Bean |
||||
open fun authorizationServerSettings(): AuthorizationServerSettings { |
||||
return AuthorizationServerSettings.builder().build() |
||||
} |
||||
|
||||
@Bean |
||||
open fun jwkSource(): JWKSource<SecurityContext> { |
||||
val keyPair = generateRsaKey() |
||||
val rsaKey = RSAKey.Builder(keyPair.public as RSAPublicKey) |
||||
.privateKey(keyPair.private) |
||||
.keyID(UUID.randomUUID().toString()) |
||||
.build() |
||||
val jwkSet = JWKSet(rsaKey) |
||||
return ImmutableJWKSet(jwkSet) |
||||
} |
||||
|
||||
@Bean |
||||
open fun jwtDecoder(jwkSource: JWKSource<SecurityContext>): JwtDecoder { |
||||
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource) |
||||
} |
||||
|
||||
private fun generateRsaKey(): KeyPair { |
||||
val keyPairGenerator = KeyPairGenerator.getInstance("RSA") |
||||
keyPairGenerator.initialize(2048) |
||||
return keyPairGenerator.generateKeyPair() |
||||
} |
||||
} |
||||
} |
||||
|
||||
Loading…
Reference in new issue