From 009830f7bdac9641fe13f8830ee389be67aa4aac Mon Sep 17 00:00:00 2001 From: fangchongde <632083030@qq.com> Date: Wed, 4 Oct 2023 11:57:49 +0800 Subject: [PATCH] init --- demo-authorizationserver/pom.xml | 10 +- .../CustomAuthenticationProvider.java | 49 +++++++++ .../DeviceClientAuthenticationProvider.java | 103 ------------------ .../DeviceClientAuthenticationToken.java | 44 -------- .../Oauth2BasicUserService.java | 25 +++++ .../config/AuthorizationServerConfig.java | 26 +---- .../sample/config/DefaultSecurityConfig.java | 33 ++++-- ...dIdentityAuthenticationSuccessHandler.java | 72 ------------ .../FederatedIdentityIdTokenCustomizer.java | 95 ---------------- .../UserRepositoryOAuth2UserHandler.java | 61 ----------- .../DeviceClientAuthenticationConverter.java | 76 ------------- .../src/main/resources/templates/index.html | 12 ++ .../src/main/resources/application.yml | 2 +- .../src/main/resources/application.yml | 2 +- 14 files changed, 117 insertions(+), 493 deletions(-) create mode 100644 demo-authorizationserver/src/main/java/sample/authentication/CustomAuthenticationProvider.java delete mode 100644 demo-authorizationserver/src/main/java/sample/authentication/DeviceClientAuthenticationProvider.java delete mode 100644 demo-authorizationserver/src/main/java/sample/authentication/DeviceClientAuthenticationToken.java create mode 100644 demo-authorizationserver/src/main/java/sample/authentication/Oauth2BasicUserService.java delete mode 100644 demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityAuthenticationSuccessHandler.java delete mode 100644 demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityIdTokenCustomizer.java delete mode 100644 demo-authorizationserver/src/main/java/sample/federation/UserRepositoryOAuth2UserHandler.java delete mode 100644 demo-authorizationserver/src/main/java/sample/web/authentication/DeviceClientAuthenticationConverter.java create mode 100644 demo-authorizationserver/src/main/resources/templates/index.html diff --git a/demo-authorizationserver/pom.xml b/demo-authorizationserver/pom.xml index 574932c..e5e8915 100644 --- a/demo-authorizationserver/pom.xml +++ b/demo-authorizationserver/pom.xml @@ -18,10 +18,6 @@ spring-security-oauth2-authorization-server - - org.springframework.boot - spring-boot-starter-oauth2-client - org.springframework.boot @@ -37,7 +33,11 @@ org.springframework.boot spring-boot-starter-jdbc - + + org.projectlombok + lombok + true + org.webjars webjars-locator-core diff --git a/demo-authorizationserver/src/main/java/sample/authentication/CustomAuthenticationProvider.java b/demo-authorizationserver/src/main/java/sample/authentication/CustomAuthenticationProvider.java new file mode 100644 index 0000000..eeac1be --- /dev/null +++ b/demo-authorizationserver/src/main/java/sample/authentication/CustomAuthenticationProvider.java @@ -0,0 +1,49 @@ +package sample.authentication; + +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +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.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + + +public class CustomAuthenticationProvider extends DaoAuthenticationProvider { + + + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + String name = authentication.getName(); + String password = authentication.getCredentials().toString(); + final List grantedAuths = new ArrayList<>(); + grantedAuths.add(new SimpleGrantedAuthority("USER")); + final UserDetails principal = getUserDetailsService().loadUserByUsername(name); + if(principal==null){ + throw new UsernameNotFoundException("用户名或密码错误"); + } + boolean passwordValid = getPasswordEncoder().matches(password, principal.getPassword()); + if (!passwordValid) { + throw new BadCredentialsException("用户名或密码错误"); + } + final Authentication auth = new UsernamePasswordAuthenticationToken(principal, password, grantedAuths); + return auth; + } + + @Override + public boolean supports(Class authentication) { + + return authentication.equals(UsernamePasswordAuthenticationToken.class); + } + +} \ No newline at end of file diff --git a/demo-authorizationserver/src/main/java/sample/authentication/DeviceClientAuthenticationProvider.java b/demo-authorizationserver/src/main/java/sample/authentication/DeviceClientAuthenticationProvider.java deleted file mode 100644 index 2ba2668..0000000 --- a/demo-authorizationserver/src/main/java/sample/authentication/DeviceClientAuthenticationProvider.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2020-2023 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 sample.authentication; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import sample.web.authentication.DeviceClientAuthenticationConverter; - -import org.springframework.security.authentication.AuthenticationProvider; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.oauth2.core.ClientAuthenticationMethod; -import org.springframework.security.oauth2.core.OAuth2AuthenticationException; -import org.springframework.security.oauth2.core.OAuth2Error; -import org.springframework.security.oauth2.core.OAuth2ErrorCodes; -import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; -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.web.OAuth2ClientAuthenticationFilter; -import org.springframework.util.Assert; - -/** - * @author Joe Grandja - * @author Steve Riesenberg - * @since 1.1 - * @see DeviceClientAuthenticationToken - * @see DeviceClientAuthenticationConverter - * @see OAuth2ClientAuthenticationFilter - */ -public final class DeviceClientAuthenticationProvider implements AuthenticationProvider { - private static final String ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-3.2.1"; - private final Log logger = LogFactory.getLog(getClass()); - private final RegisteredClientRepository registeredClientRepository; - - public DeviceClientAuthenticationProvider(RegisteredClientRepository registeredClientRepository) { - Assert.notNull(registeredClientRepository, "registeredClientRepository cannot be null"); - this.registeredClientRepository = registeredClientRepository; - } - - @Override - public Authentication authenticate(Authentication authentication) throws AuthenticationException { - DeviceClientAuthenticationToken deviceClientAuthentication = - (DeviceClientAuthenticationToken) authentication; - - if (!ClientAuthenticationMethod.NONE.equals(deviceClientAuthentication.getClientAuthenticationMethod())) { - return null; - } - - String clientId = deviceClientAuthentication.getPrincipal().toString(); - RegisteredClient registeredClient = this.registeredClientRepository.findByClientId(clientId); - if (registeredClient == null) { - throwInvalidClient(OAuth2ParameterNames.CLIENT_ID); - } - - if (this.logger.isTraceEnabled()) { - this.logger.trace("Retrieved registered client"); - } - - if (!registeredClient.getClientAuthenticationMethods().contains( - deviceClientAuthentication.getClientAuthenticationMethod())) { - throwInvalidClient("authentication_method"); - } - - if (this.logger.isTraceEnabled()) { - this.logger.trace("Validated device client authentication parameters"); - } - - if (this.logger.isTraceEnabled()) { - this.logger.trace("Authenticated device client"); - } - - return new DeviceClientAuthenticationToken(registeredClient, - deviceClientAuthentication.getClientAuthenticationMethod(), null); - } - - @Override - public boolean supports(Class authentication) { - return DeviceClientAuthenticationToken.class.isAssignableFrom(authentication); - } - - private static void throwInvalidClient(String parameterName) { - OAuth2Error error = new OAuth2Error( - OAuth2ErrorCodes.INVALID_CLIENT, - "Device client authentication failed: " + parameterName, - ERROR_URI - ); - throw new OAuth2AuthenticationException(error); - } - -} diff --git a/demo-authorizationserver/src/main/java/sample/authentication/DeviceClientAuthenticationToken.java b/demo-authorizationserver/src/main/java/sample/authentication/DeviceClientAuthenticationToken.java deleted file mode 100644 index 4e9a3d2..0000000 --- a/demo-authorizationserver/src/main/java/sample/authentication/DeviceClientAuthenticationToken.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2020-2023 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 sample.authentication; - -import java.util.Map; - -import org.springframework.lang.Nullable; -import org.springframework.security.core.Transient; -import org.springframework.security.oauth2.core.ClientAuthenticationMethod; -import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken; -import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; - -/** - * @author Joe Grandja - * @author Steve Riesenberg - * @since 1.1 - */ -@Transient -public class DeviceClientAuthenticationToken extends OAuth2ClientAuthenticationToken { - - public DeviceClientAuthenticationToken(String clientId, ClientAuthenticationMethod clientAuthenticationMethod, - @Nullable Object credentials, @Nullable Map additionalParameters) { - super(clientId, clientAuthenticationMethod, credentials, additionalParameters); - } - - public DeviceClientAuthenticationToken(RegisteredClient registeredClient, ClientAuthenticationMethod clientAuthenticationMethod, - @Nullable Object credentials) { - super(registeredClient, clientAuthenticationMethod, credentials); - } - -} diff --git a/demo-authorizationserver/src/main/java/sample/authentication/Oauth2BasicUserService.java b/demo-authorizationserver/src/main/java/sample/authentication/Oauth2BasicUserService.java new file mode 100644 index 0000000..02421a2 --- /dev/null +++ b/demo-authorizationserver/src/main/java/sample/authentication/Oauth2BasicUserService.java @@ -0,0 +1,25 @@ +package sample.authentication; + +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +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.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.factory.PasswordEncoderFactories; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; + +@Service("userDetailsService") +@RequiredArgsConstructor +public class Oauth2BasicUserService implements UserDetailsService { + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); + return User.builder().username(username).password(encoder.encode("passw0rd")).roles("USER").build(); + } + +} diff --git a/demo-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java b/demo-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java index c2d04f7..5f792b8 100644 --- a/demo-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java +++ b/demo-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java @@ -21,10 +21,7 @@ import com.nimbusds.jose.jwk.JWKSet; import com.nimbusds.jose.jwk.RSAKey; import com.nimbusds.jose.jwk.source.JWKSource; import com.nimbusds.jose.proc.SecurityContext; -import sample.authentication.DeviceClientAuthenticationProvider; -import sample.federation.FederatedIdentityIdTokenCustomizer; import sample.jose.Jwks; -import sample.web.authentication.DeviceClientAuthenticationConverter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -80,25 +77,10 @@ public class AuthorizationServerConfig { OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); - DeviceClientAuthenticationConverter deviceClientAuthenticationConverter = - new DeviceClientAuthenticationConverter( - authorizationServerSettings.getDeviceAuthorizationEndpoint()); - DeviceClientAuthenticationProvider deviceClientAuthenticationProvider = - new DeviceClientAuthenticationProvider(registeredClientRepository); + // @formatter:off http.getConfigurer(OAuth2AuthorizationServerConfigurer.class) - .deviceAuthorizationEndpoint(deviceAuthorizationEndpoint -> - deviceAuthorizationEndpoint.verificationUri("/activate") - ) - .deviceVerificationEndpoint(deviceVerificationEndpoint -> - deviceVerificationEndpoint.consentPage(CUSTOM_CONSENT_PAGE_URI) - ) - .clientAuthentication(clientAuthentication -> - clientAuthentication - .authenticationConverter(deviceClientAuthenticationConverter) - .authenticationProvider(deviceClientAuthenticationProvider) - ) .authorizationEndpoint(authorizationEndpoint -> authorizationEndpoint.consentPage(CUSTOM_CONSENT_PAGE_URI)) .oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0 @@ -136,7 +118,7 @@ public class AuthorizationServerConfig { .scope(OidcScopes.PROFILE) .scope("message.read") .scope("message.write") - .clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())//requireAuthorizationConsent(true) 授权页是有的 如果是false是没有的 + .clientSettings(ClientSettings.builder().requireAuthorizationConsent(false).build())//requireAuthorizationConsent(true) 授权页是有的 如果是false是没有的 .build(); RegisteredClient deviceClient = RegisteredClient.withId(UUID.randomUUID().toString()) @@ -172,10 +154,6 @@ public class AuthorizationServerConfig { return new JdbcOAuth2AuthorizationConsentService(jdbcTemplate, registeredClientRepository); } - @Bean - public OAuth2TokenCustomizer idTokenCustomizer() { - return new FederatedIdentityIdTokenCustomizer(); - } @Bean public JWKSource jwkSource() { diff --git a/demo-authorizationserver/src/main/java/sample/config/DefaultSecurityConfig.java b/demo-authorizationserver/src/main/java/sample/config/DefaultSecurityConfig.java index f22680a..bb89d37 100644 --- a/demo-authorizationserver/src/main/java/sample/config/DefaultSecurityConfig.java +++ b/demo-authorizationserver/src/main/java/sample/config/DefaultSecurityConfig.java @@ -15,11 +15,14 @@ */ package sample.config; +import lombok.RequiredArgsConstructor; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; -import sample.federation.FederatedIdentityAuthenticationSuccessHandler; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -34,6 +37,7 @@ import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.session.HttpSessionEventPublisher; +import sample.authentication.CustomAuthenticationProvider; /** * @author Joe Grandja @@ -41,9 +45,12 @@ import org.springframework.security.web.session.HttpSessionEventPublisher; * @since 1.1 */ @EnableWebSecurity -@Configuration(proxyBeanMethods = false) +@Configuration +@RequiredArgsConstructor public class DefaultSecurityConfig { + private final UserDetailsService userDetailsService; + // 过滤器链 @Bean public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { @@ -57,23 +64,27 @@ public class DefaultSecurityConfig { .formLogin(formLogin -> formLogin .loginPage("/login")//④ 授权服务认证页面(可以配置相对和绝对地址,前后端分离的情况下填前端的url) - ) - .oauth2Login(oauth2Login -> - oauth2Login - .loginPage("/login")//⑤ oauth2的认证页面(也可配置绝对地址) - .successHandler(authenticationSuccessHandler())//⑥ 登录成功后的处理 ); return http.build(); } - - private AuthenticationSuccessHandler authenticationSuccessHandler() { - return new FederatedIdentityAuthenticationSuccessHandler(); + @Bean + public AuthenticationManager authManager(HttpSecurity http) throws Exception { + return http.getSharedObject(AuthenticationManagerBuilder.class) + .authenticationProvider(authProvider()) + .build(); + } + @Bean + public DaoAuthenticationProvider authProvider() { + final CustomAuthenticationProvider authProvider = new CustomAuthenticationProvider(); + authProvider.setUserDetailsService(userDetailsService); + //authProvider.setPasswordEncoder(passwordEncoder()); + return authProvider; } // 初始化了一个用户在内存里面(这样就不会每次启动就再去生成密码了) - @Bean + //@Bean public UserDetailsService users() { UserDetails user = User.withDefaultPasswordEncoder() .username("user1") diff --git a/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityAuthenticationSuccessHandler.java b/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityAuthenticationSuccessHandler.java deleted file mode 100644 index ed4c240..0000000 --- a/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityAuthenticationSuccessHandler.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2020-2023 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 sample.federation; - -// tag::imports[] -import java.io.IOException; -import java.util.function.Consumer; - -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - -import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; -import org.springframework.security.oauth2.core.oidc.user.OidcUser; -import org.springframework.security.oauth2.core.user.OAuth2User; -import org.springframework.security.web.authentication.AuthenticationSuccessHandler; -import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; -// end::imports[] - -/** - * An {@link AuthenticationSuccessHandler} for capturing the {@link OidcUser} or - * {@link OAuth2User} for Federated Account Linking or JIT Account Provisioning. - * - * @author Steve Riesenberg - * @since 1.1 - */ -// tag::class[] -public final class FederatedIdentityAuthenticationSuccessHandler implements AuthenticationSuccessHandler { - - private final AuthenticationSuccessHandler delegate = new SavedRequestAwareAuthenticationSuccessHandler(); - - private Consumer oauth2UserHandler = (user) -> {}; - - private Consumer oidcUserHandler = (user) -> this.oauth2UserHandler.accept(user); - - @Override - public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { - if (authentication instanceof OAuth2AuthenticationToken) { - if (authentication.getPrincipal() instanceof OidcUser) { - this.oidcUserHandler.accept((OidcUser) authentication.getPrincipal()); - } else if (authentication.getPrincipal() instanceof OAuth2User) { - this.oauth2UserHandler.accept((OAuth2User) authentication.getPrincipal()); - } - } - - this.delegate.onAuthenticationSuccess(request, response, authentication); - } - - public void setOAuth2UserHandler(Consumer oauth2UserHandler) { - this.oauth2UserHandler = oauth2UserHandler; - } - - public void setOidcUserHandler(Consumer oidcUserHandler) { - this.oidcUserHandler = oidcUserHandler; - } - -} -// end::class[] diff --git a/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityIdTokenCustomizer.java b/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityIdTokenCustomizer.java deleted file mode 100644 index 0929ed4..0000000 --- a/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityIdTokenCustomizer.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2020-2023 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 sample.federation; - -// tag::imports[] -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames; -import org.springframework.security.oauth2.core.oidc.OidcIdToken; -import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames; -import org.springframework.security.oauth2.core.oidc.user.OidcUser; -import org.springframework.security.oauth2.core.user.OAuth2User; -import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext; -import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer; -// end::imports[] - -/** - * An {@link OAuth2TokenCustomizer} to map claims from a federated identity to - * the {@code id_token} produced by this authorization server. - * - * @author Steve Riesenberg - * @since 1.1 - */ -// tag::class[] -public final class FederatedIdentityIdTokenCustomizer implements OAuth2TokenCustomizer { - - private static final Set ID_TOKEN_CLAIMS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList( - IdTokenClaimNames.ISS, - IdTokenClaimNames.SUB, - IdTokenClaimNames.AUD, - IdTokenClaimNames.EXP, - IdTokenClaimNames.IAT, - IdTokenClaimNames.AUTH_TIME, - IdTokenClaimNames.NONCE, - IdTokenClaimNames.ACR, - IdTokenClaimNames.AMR, - IdTokenClaimNames.AZP, - IdTokenClaimNames.AT_HASH, - IdTokenClaimNames.C_HASH - ))); - - @Override - public void customize(JwtEncodingContext context) { - if (OidcParameterNames.ID_TOKEN.equals(context.getTokenType().getValue())) { - Map thirdPartyClaims = extractClaims(context.getPrincipal()); - context.getClaims().claims(existingClaims -> { - // Remove conflicting claims set by this authorization server - existingClaims.keySet().forEach(thirdPartyClaims::remove); - - // Remove standard id_token claims that could cause problems with clients - ID_TOKEN_CLAIMS.forEach(thirdPartyClaims::remove); - - // Add all other claims directly to id_token - existingClaims.putAll(thirdPartyClaims); - }); - } - } - - private Map extractClaims(Authentication principal) { - Map claims; - if (principal.getPrincipal() instanceof OidcUser) { - OidcUser oidcUser = (OidcUser) principal.getPrincipal(); - OidcIdToken idToken = oidcUser.getIdToken(); - claims = idToken.getClaims(); - } else if (principal.getPrincipal() instanceof OAuth2User) { - OAuth2User oauth2User = (OAuth2User) principal.getPrincipal(); - claims = oauth2User.getAttributes(); - } else { - claims = Collections.emptyMap(); - } - - return new HashMap<>(claims); - } - -} -// end::class[] diff --git a/demo-authorizationserver/src/main/java/sample/federation/UserRepositoryOAuth2UserHandler.java b/demo-authorizationserver/src/main/java/sample/federation/UserRepositoryOAuth2UserHandler.java deleted file mode 100644 index 95030de..0000000 --- a/demo-authorizationserver/src/main/java/sample/federation/UserRepositoryOAuth2UserHandler.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2020-2023 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 sample.federation; - -// tag::imports[] -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; - -import org.springframework.security.oauth2.core.user.OAuth2User; -// end::imports[] - -/** - * Example {@link Consumer} to perform JIT provisioning of an {@link OAuth2User}. - * - * @author Steve Riesenberg - * @since 1.1 - */ -// tag::class[] -public final class UserRepositoryOAuth2UserHandler implements Consumer { - - private final UserRepository userRepository = new UserRepository(); - - @Override - public void accept(OAuth2User user) { - // Capture user in a local data store on first authentication - if (this.userRepository.findByName(user.getName()) == null) { - System.out.println("Saving first-time user: name=" + user.getName() + ", claims=" + user.getAttributes() + ", authorities=" + user.getAuthorities()); - this.userRepository.save(user); - } - } - - static class UserRepository { - - private final Map userCache = new ConcurrentHashMap<>(); - - public OAuth2User findByName(String name) { - return this.userCache.get(name); - } - - public void save(OAuth2User oauth2User) { - this.userCache.put(oauth2User.getName(), oauth2User); - } - - } - -} -// end::class[] diff --git a/demo-authorizationserver/src/main/java/sample/web/authentication/DeviceClientAuthenticationConverter.java b/demo-authorizationserver/src/main/java/sample/web/authentication/DeviceClientAuthenticationConverter.java deleted file mode 100644 index aa1cbfe..0000000 --- a/demo-authorizationserver/src/main/java/sample/web/authentication/DeviceClientAuthenticationConverter.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2020-2023 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 sample.web.authentication; - -import jakarta.servlet.http.HttpServletRequest; - -import sample.authentication.DeviceClientAuthenticationToken; - -import org.springframework.http.HttpMethod; -import org.springframework.lang.Nullable; -import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.core.AuthorizationGrantType; -import org.springframework.security.oauth2.core.ClientAuthenticationMethod; -import org.springframework.security.oauth2.core.OAuth2AuthenticationException; -import org.springframework.security.oauth2.core.OAuth2ErrorCodes; -import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; -import org.springframework.security.web.authentication.AuthenticationConverter; -import org.springframework.security.web.util.matcher.AndRequestMatcher; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; -import org.springframework.security.web.util.matcher.RequestMatcher; -import org.springframework.util.StringUtils; - -/** - * @author Joe Grandja - * @author Steve Riesenberg - * @since 1.1 - */ -public final class DeviceClientAuthenticationConverter implements AuthenticationConverter { - private final RequestMatcher deviceAuthorizationRequestMatcher; - private final RequestMatcher deviceAccessTokenRequestMatcher; - - public DeviceClientAuthenticationConverter(String deviceAuthorizationEndpointUri) { - RequestMatcher clientIdParameterMatcher = request -> - request.getParameter(OAuth2ParameterNames.CLIENT_ID) != null; - this.deviceAuthorizationRequestMatcher = new AndRequestMatcher( - new AntPathRequestMatcher( - deviceAuthorizationEndpointUri, HttpMethod.POST.name()), - clientIdParameterMatcher); - this.deviceAccessTokenRequestMatcher = request -> - AuthorizationGrantType.DEVICE_CODE.getValue().equals(request.getParameter(OAuth2ParameterNames.GRANT_TYPE)) && - request.getParameter(OAuth2ParameterNames.DEVICE_CODE) != null && - request.getParameter(OAuth2ParameterNames.CLIENT_ID) != null; - } - - @Nullable - @Override - public Authentication convert(HttpServletRequest request) { - if (!this.deviceAuthorizationRequestMatcher.matches(request) && - !this.deviceAccessTokenRequestMatcher.matches(request)) { - return null; - } - - // client_id (REQUIRED) - String clientId = request.getParameter(OAuth2ParameterNames.CLIENT_ID); - if (!StringUtils.hasText(clientId) || - request.getParameterValues(OAuth2ParameterNames.CLIENT_ID).length != 1) { - throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_REQUEST); - } - - return new DeviceClientAuthenticationToken(clientId, ClientAuthenticationMethod.NONE, null, null); - } - -} diff --git a/demo-authorizationserver/src/main/resources/templates/index.html b/demo-authorizationserver/src/main/resources/templates/index.html new file mode 100644 index 0000000..b8a73a6 --- /dev/null +++ b/demo-authorizationserver/src/main/resources/templates/index.html @@ -0,0 +1,12 @@ + + + + + + Spring Authorization Server sample + + + + +欢迎, Name + \ No newline at end of file diff --git a/demo-client/src/main/resources/application.yml b/demo-client/src/main/resources/application.yml index 34d022a..d73e805 100644 --- a/demo-client/src/main/resources/application.yml +++ b/demo-client/src/main/resources/application.yml @@ -48,7 +48,7 @@ spring: client-name: messaging-client-device-code provider: spring: - issuer-uri: http://127.0.0.1:9000 + issuer-uri: http://10.0.0.104:9000 messages: base-uri: http://127.0.0.1:8090/messages diff --git a/messages-resource/src/main/resources/application.yml b/messages-resource/src/main/resources/application.yml index 3926f4f..0ba2410 100644 --- a/messages-resource/src/main/resources/application.yml +++ b/messages-resource/src/main/resources/application.yml @@ -14,4 +14,4 @@ spring: oauth2: resourceserver: jwt: - issuer-uri: http://127.0.0.1:9000 + issuer-uri: http://10.0.0.103:9000