diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5e497ae..d82eb71 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,7 +5,6 @@ org-springframework-boot = "3.4.0-SNAPSHOT" org-springframework-spring-framework-bom = "org.springframework:spring-framework-bom:6.1.11" org-springframework-security-spring-security-bom = "org.springframework.security:spring-security-bom:6.4.0-SNAPSHOT" org-springframework-data-spring-data-bom = "org.springframework.data:spring-data-bom:2024.0.2" -org-springframework-security-spring-security-oauth2-authorization-server = "org.springframework.security:spring-security-oauth2-authorization-server:1.2.4" [plugins] io-spring-dependency-management = { id = "io.spring.dependency-management", version = "1.1.6" } diff --git a/servlet/spring-boot/java/oauth2/authorization-server/build.gradle b/servlet/spring-boot/java/oauth2/authorization-server/build.gradle index 556f25e..61ed947 100644 --- a/servlet/spring-boot/java/oauth2/authorization-server/build.gradle +++ b/servlet/spring-boot/java/oauth2/authorization-server/build.gradle @@ -15,7 +15,7 @@ ext["micrometer.version"] = "1.10.0-SNAPSHOT" dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' - implementation libs.org.springframework.security.spring.security.oauth2.authorization.server + implementation 'org.springframework.boot:spring-boot-starter-oauth2-authorization-server' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test' @@ -25,5 +25,4 @@ dependencies { tasks.withType(Test).configureEach { useJUnitPlatform() - } diff --git a/servlet/spring-boot/java/oauth2/authorization-server/src/main/java/example/OAuth2AuthorizationServerSecurityConfiguration.java b/servlet/spring-boot/java/oauth2/authorization-server/src/main/java/example/OAuth2AuthorizationServerSecurityConfiguration.java deleted file mode 100644 index fe63cdb..0000000 --- a/servlet/spring-boot/java/oauth2/authorization-server/src/main/java/example/OAuth2AuthorizationServerSecurityConfiguration.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2021 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 example; - -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.interfaces.RSAPrivateKey; -import java.security.interfaces.RSAPublicKey; -import java.util.UUID; - -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.springframework.beans.factory.config.BeanDefinition; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Role; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.security.config.Customizer; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -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.jwt.NimbusJwtDecoder; -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.AuthorizationServerSettings; -import org.springframework.security.oauth2.server.authorization.settings.ClientSettings; -import org.springframework.security.provisioning.InMemoryUserDetailsManager; -import org.springframework.security.web.SecurityFilterChain; -import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; - -/** - * OAuth Authorization Server Configuration. - * - * @author Steve Riesenberg - */ -@Configuration -@EnableWebSecurity -public class OAuth2AuthorizationServerSecurityConfiguration { - - @Bean - @Order(Ordered.HIGHEST_PRECEDENCE) - public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { - // @formatter:off - OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); - http.getConfigurer(OAuth2AuthorizationServerConfigurer.class).oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0 - http - .exceptionHandling((exceptions) -> exceptions - .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login")) - ) - .oauth2ResourceServer((resourceServer) -> resourceServer.jwt(Customizer.withDefaults())); - // @formatter:on - return http.build(); - } - - @Bean - @Order(2) - public SecurityFilterChain standardSecurityFilterChain(HttpSecurity http) throws Exception { - // @formatter:off - http - .authorizeHttpRequests((authorize) -> authorize - .anyRequest().authenticated() - ) - .formLogin(Customizer.withDefaults()); - // @formatter:on - - return http.build(); - } - - @Bean - public RegisteredClientRepository registeredClientRepository() { - // @formatter:off - RegisteredClient loginClient = RegisteredClient.withId(UUID.randomUUID().toString()) - .clientId("login-client") - .clientSecret("{noop}openid-connect") - .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC) - .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) - .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) - .redirectUri("http://127.0.0.1:8080/login/oauth2/code/login-client") - .redirectUri("http://127.0.0.1:8080/authorized") - .scope(OidcScopes.OPENID) - .scope(OidcScopes.PROFILE) - .clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build()) - .build(); - RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString()) - .clientId("messaging-client") - .clientSecret("{noop}secret") - .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC) - .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) - .scope("message:read") - .scope("message:write") - .build(); - // @formatter:on - - return new InMemoryRegisteredClientRepository(loginClient, registeredClient); - } - - @Bean - public JWKSource jwkSource(KeyPair keyPair) { - RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); - RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); - // @formatter:off - RSAKey rsaKey = new RSAKey.Builder(publicKey) - .privateKey(privateKey) - .keyID(UUID.randomUUID().toString()) - .build(); - // @formatter:on - JWKSet jwkSet = new JWKSet(rsaKey); - return new ImmutableJWKSet<>(jwkSet); - } - - @Bean - public JwtDecoder jwtDecoder(KeyPair keyPair) { - return NimbusJwtDecoder.withPublicKey((RSAPublicKey) keyPair.getPublic()).build(); - } - - @Bean - public AuthorizationServerSettings providerSettings() { - return AuthorizationServerSettings.builder().issuer("http://localhost:9000").build(); - } - - @Bean - public UserDetailsService userDetailsService() { - // @formatter:off - UserDetails userDetails = User.withDefaultPasswordEncoder() - .username("user") - .password("password") - .roles("USER") - .build(); - // @formatter:on - - return new InMemoryUserDetailsManager(userDetails); - } - - @Bean - @Role(BeanDefinition.ROLE_INFRASTRUCTURE) - KeyPair generateRsaKey() { - KeyPair keyPair; - try { - KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); - keyPairGenerator.initialize(2048); - keyPair = keyPairGenerator.generateKeyPair(); - } - catch (Exception ex) { - throw new IllegalStateException(ex); - } - return keyPair; - } - -} diff --git a/servlet/spring-boot/java/oauth2/authorization-server/src/main/resources/application.yml b/servlet/spring-boot/java/oauth2/authorization-server/src/main/resources/application.yml index e346b3d..0a8596b 100644 --- a/servlet/spring-boot/java/oauth2/authorization-server/src/main/resources/application.yml +++ b/servlet/spring-boot/java/oauth2/authorization-server/src/main/resources/application.yml @@ -1,2 +1,41 @@ server: - port: 9000 \ No newline at end of file + port: 9000 + +spring: + security: + user: + name: "user" + password: "password" + roles: + - "USER" + oauth2: + authorizationserver: + issuer: http://localhost:9000 + client: + login-client: + registration: + client-id: "login-client" + client-secret: "{noop}openid-connect" + client-authentication-methods: + - "client_secret_basic" + authorization-grant-types: + - "authorization_code" + - "refresh_token" + redirect-uris: + - "http://127.0.0.1:8080/login/oauth2/code/login-client" + - "http://127.0.0.1:8080/authorized" + scopes: + - "openid" + - "profile" + require-authorization-consent: true + messaging-client: + registration: + client-id: "messaging-client" + client-secret: "{noop}secret" + client-authentication-methods: + - "client_secret_basic" + authorization-grant-types: + - "client_credentials" + scopes: + - "message:read" + - "message:write" \ No newline at end of file