From 950c65ba1db7df81e663d80b51ba74ba2972bcc0 Mon Sep 17 00:00:00 2001 From: fuhouyu Date: Tue, 5 Nov 2024 22:06:58 +0800 Subject: [PATCH] fix: oidc bug --- .../{main => test}/resources/application.yaml | 0 .../security/AuthenticationConfiguration.java | 102 ++++++++++++++++++ .../AuthenticationProviderConfiguration.java | 65 ----------- .../security/SecurityAutoConfiguration.java | 37 +------ .../oidc/OidcAuthenticationProvider.java | 37 +++++-- .../oidc/OidcAuthenticationToken.java | 15 ++- .../framework/security/BaseComponent.java | 73 ------------- .../fuhouyu/framework/security/BaseTest.java | 92 ++++++++++++++++ .../framework/security/OidcProviderTest.java | 27 ++--- .../framework/security/RefreshTokenTest.java | 13 +-- .../security/Sm3PasswordEncoderTest.java | 13 +-- .../framework/security/TokenStoreTest.java | 18 +--- .../src/test/resources/application.yaml | 22 +--- 13 files changed, 247 insertions(+), 267 deletions(-) rename base-framework-cache-starter/src/{main => test}/resources/application.yaml (100%) create mode 100644 base-framework-security-starter/src/main/java/com/fuhouyu/framework/security/AuthenticationConfiguration.java delete mode 100644 base-framework-security-starter/src/main/java/com/fuhouyu/framework/security/AuthenticationProviderConfiguration.java delete mode 100644 base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/BaseComponent.java create mode 100644 base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/BaseTest.java diff --git a/base-framework-cache-starter/src/main/resources/application.yaml b/base-framework-cache-starter/src/test/resources/application.yaml similarity index 100% rename from base-framework-cache-starter/src/main/resources/application.yaml rename to base-framework-cache-starter/src/test/resources/application.yaml diff --git a/base-framework-security-starter/src/main/java/com/fuhouyu/framework/security/AuthenticationConfiguration.java b/base-framework-security-starter/src/main/java/com/fuhouyu/framework/security/AuthenticationConfiguration.java new file mode 100644 index 0000000..0c8d509 --- /dev/null +++ b/base-framework-security-starter/src/main/java/com/fuhouyu/framework/security/AuthenticationConfiguration.java @@ -0,0 +1,102 @@ +/* + * Copyright 2024-2024 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 com.fuhouyu.framework.security; + +import com.fuhouyu.framework.security.core.passwordencoder.PasswordEncoderFactory; +import com.fuhouyu.framework.security.core.provider.oidc.OidcAuthenticationProvider; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; +import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; + +import java.util.List; + +/** + *

+ * oidc配置 + *

+ * + * @author fuhouyu + * @since 2024/11/4 22:06 + */ +@Configuration +public class AuthenticationConfiguration { + + /** + * dao层实现 + * + * @param passwordEncoder 密码管理器 + * @param userDetailsService 用户详情接口 + * @return dao默认实现 + */ + @Bean + public AuthenticationProvider daoAuthenticationProvider(UserDetailsService userDetailsService, + PasswordEncoder passwordEncoder) { + DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider(passwordEncoder); + daoAuthenticationProvider.setUserDetailsService(userDetailsService); + return daoAuthenticationProvider; + } + + /** + * oidc provider + * + * @param userDetailsService 用户详情service + * @param clientRegistrationRepository 客户端仓库信息 + * @return oidcProvider + */ + @Bean + @ConditionalOnBean({UserDetailsService.class, ClientRegistrationRepository.class}) + public AuthenticationProvider oidcAuthenticationProvider(UserDetailsService userDetailsService, + ClientRegistrationRepository clientRegistrationRepository) { + return new OidcAuthenticationProvider(new DefaultOAuth2UserService(), userDetailsService, clientRegistrationRepository); + } + + + /** + * 认证管理器配置这里可以进行除其他登录模式的扩展,需要实现{@link AuthenticationProvider} + * + * @param authenticationProviders 认证提供者集合 + * @return 认证管理器 + */ + @Bean + @Primary + @ConditionalOnBean({AuthenticationProvider.class}) + public AuthenticationManager authenticationManager(List authenticationProviders) { + return new ProviderManager(authenticationProviders); + } + + /** + * 返回sm3 密码编码器的bean,当passwordEncoder不存在时,则会创建。 + * + * @return sm3 密码编码器bean + */ + @Bean + @ConditionalOnMissingBean(PasswordEncoder.class) + public PasswordEncoder passwordEncoder() { + return PasswordEncoderFactory.createDelegatingPasswordEncoder("sm3"); + } + + +} diff --git a/base-framework-security-starter/src/main/java/com/fuhouyu/framework/security/AuthenticationProviderConfiguration.java b/base-framework-security-starter/src/main/java/com/fuhouyu/framework/security/AuthenticationProviderConfiguration.java deleted file mode 100644 index e4a99a4..0000000 --- a/base-framework-security-starter/src/main/java/com/fuhouyu/framework/security/AuthenticationProviderConfiguration.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2024-2024 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 com.fuhouyu.framework.security; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.authentication.AuthenticationProvider; -import org.springframework.security.authentication.dao.DaoAuthenticationProvider; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.crypto.password.PasswordEncoder; - -/** - *

- * oidc配置 - *

- * - * @author fuhouyu - * @since 2024/11/4 22:06 - */ -@Configuration(proxyBeanMethods = false) -public class AuthenticationProviderConfiguration { - - /** - * dao层实现 - * - * @param passwordEncoder 密码管理器 - * @param userDetailsService 用户详情接口 - * @return dao默认实现 - */ - @Bean - public AuthenticationProvider daoAuthenticationProvider(UserDetailsService userDetailsService, - PasswordEncoder passwordEncoder) { - DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider(passwordEncoder); - daoAuthenticationProvider.setUserDetailsService(userDetailsService); - return daoAuthenticationProvider; - } - -// /** -// * oidc provider -// * -// * @param userDetailsService 用户详情service -// * @param clientRegistrationRepository 客户端仓库信息 -// * @return oidcProvider -// */ -// @Bean -// public AuthenticationProvider oidcAuthenticationProvider(UserDetailsService userDetailsService, -// ClientRegistrationRepository clientRegistrationRepository) { -// return new OidcAuthenticationProvider(new DefaultOAuth2UserService(), userDetailsService, clientRegistrationRepository); -// } - - -} diff --git a/base-framework-security-starter/src/main/java/com/fuhouyu/framework/security/SecurityAutoConfiguration.java b/base-framework-security-starter/src/main/java/com/fuhouyu/framework/security/SecurityAutoConfiguration.java index 17f6efe..47e9756 100644 --- a/base-framework-security-starter/src/main/java/com/fuhouyu/framework/security/SecurityAutoConfiguration.java +++ b/base-framework-security-starter/src/main/java/com/fuhouyu/framework/security/SecurityAutoConfiguration.java @@ -18,22 +18,15 @@ import com.fuhouyu.framework.cache.CacheAutoConfiguration; import com.fuhouyu.framework.cache.service.CacheService; -import com.fuhouyu.framework.security.core.passwordencoder.PasswordEncoderFactory; import com.fuhouyu.framework.security.token.TokenStore; import com.fuhouyu.framework.security.token.TokenStoreCache; import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.Primary; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.AuthenticationProvider; -import org.springframework.security.authentication.ProviderManager; -import org.springframework.security.crypto.password.PasswordEncoder; - -import java.util.List; /** *

@@ -48,7 +41,7 @@ CacheAutoConfiguration.class, OAuth2ClientAutoConfiguration.class }) -@Import({AuthenticationProviderConfiguration.class}) +@Import({AuthenticationConfiguration.class}) public class SecurityAutoConfiguration { /** @@ -59,33 +52,9 @@ public class SecurityAutoConfiguration { */ @Bean @ConditionalOnMissingBean(TokenStore.class) + @ConditionalOnBean(CacheService.class) public TokenStore tokenStore(CacheService cacheService) { return new TokenStoreCache("user", cacheService); } - - /** - * 认证管理器配置这里可以进行除其他登录模式的扩展,需要实现{@link AuthenticationProvider} - * - * @param authenticationProviders 认证提供者集合 - * @return 认证管理器 - */ - @Bean - @Primary - public AuthenticationManager authenticationManager(List authenticationProviders) { - return new ProviderManager(authenticationProviders); - } - - /** - * 返回sm3 密码编码器的bean,当passwordEncoder不存在时,则会创建。 - * - * @return sm3 密码编码器bean - */ - @Bean - @ConditionalOnMissingBean(PasswordEncoder.class) - public PasswordEncoder passwordEncoder() { - return PasswordEncoderFactory.createDelegatingPasswordEncoder("sm3"); - } - - } diff --git a/base-framework-security-starter/src/main/java/com/fuhouyu/framework/security/core/provider/oidc/OidcAuthenticationProvider.java b/base-framework-security-starter/src/main/java/com/fuhouyu/framework/security/core/provider/oidc/OidcAuthenticationProvider.java index 048b92f..4400ebc 100644 --- a/base-framework-security-starter/src/main/java/com/fuhouyu/framework/security/core/provider/oidc/OidcAuthenticationProvider.java +++ b/base-framework-security-starter/src/main/java/com/fuhouyu/framework/security/core/provider/oidc/OidcAuthenticationProvider.java @@ -15,6 +15,7 @@ */ package com.fuhouyu.framework.security.core.provider.oidc; +import com.fuhouyu.framework.common.utils.LoggerUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.http.*; import org.springframework.http.converter.FormHttpMessageConverter; @@ -76,13 +77,20 @@ public class OidcAuthenticationProvider implements AuthenticationProvider { private static final String INVALID_ID_TOKEN_ERROR_CODE = "invalid_id_token"; private static final String INVALID_NONCE_ERROR_CODE = "invalid_nonce"; + private static final MediaType APPLICATION_FORM_URLENCODED_UTF8 = new MediaType( MediaType.APPLICATION_FORM_URLENCODED, StandardCharsets.UTF_8); - private final GrantedAuthoritiesMapper authoritiesMapper = ((authorities) -> authorities); + + private final GrantedAuthoritiesMapper authoritiesMapper = authorities -> authorities; + private final UserDetailsService userDetailsService; + private final OAuth2UserService userService; + private final ClientRegistrationRepository clientRegistrationRepository; + private final JwtDecoderFactory jwtDecoderFactory = new OidcIdTokenDecoderFactory(); + private final RestOperations restOperations; public OidcAuthenticationProvider(OAuth2UserService userService, @@ -110,7 +118,7 @@ public Authentication authenticate(Authentication authentication) throws Authent if (Objects.isNull(clientRegistration)) { throw new IllegalArgumentException("invalid client id " + oidcAuthenticationToken.getClientId()); } - RequestEntity requestEntity = this.createRequestEntity(clientRegistration); + RequestEntity requestEntity = this.createRequestEntity(clientRegistration, oidcAuthenticationToken); OAuth2AccessTokenResponse accessTokenResponse = this.getResponse(requestEntity); Map additionalParameters = this.getAdditionalParameters(accessTokenResponse, clientRegistration); OidcIdToken idToken = createOidcToken(clientRegistration, accessTokenResponse); @@ -118,9 +126,6 @@ public Authentication authenticate(Authentication authentication) throws Authent OAuth2User oidcUser = this.userService.loadUser(new OidcUserRequest(clientRegistration, accessTokenResponse.getAccessToken(), idToken, additionalParameters)); UserDetails userDetails = this.userDetailsService.loadUserByUsername(oidcUser.getName()); - if (Objects.isNull(userDetails)) { - throw new IllegalArgumentException("系统中的用户不存在"); - } Collection mappedAuthorities = this.authoritiesMapper .mapAuthorities(oidcUser.getAuthorities()); OidcAuthenticationToken result = new OidcAuthenticationToken( @@ -215,13 +220,19 @@ private OAuth2AccessTokenResponse getResponse(RequestEntity request) { ResponseEntity tokenResponse = this.restOperations.exchange(request, OAuth2AccessTokenResponse.class); Assert.notNull(tokenResponse, "The authorization server responded to this Authorization Code grant request with an empty body; as such, it cannot be materialized into an OAuth2AccessTokenResponse instance. Please check the HTTP response code in your server logs for more details."); - return tokenResponse.getBody(); + OAuth2AccessTokenResponse responseBody = tokenResponse.getBody(); + Assert.notNull(responseBody, "Response Body is null"); + return responseBody; } catch (RestClientException ex) { OAuth2Error oauth2Error = new OAuth2Error(INVALID_TOKEN_RESPONSE_ERROR_CODE, "An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: " + ex.getMessage(), null); throw new OAuth2AuthorizationException(oauth2Error, ex); + } catch (OAuth2AuthorizationException e) { + LoggerUtil.error(log, "第三方平台使用失败,entity:{} , 失败原因:{}", + request, e.getError()); + throw new IllegalArgumentException("第三方平台登录失败"); } } @@ -229,14 +240,16 @@ private OAuth2AccessTokenResponse getResponse(RequestEntity request) { * 创建请求实体 * * @param clientRegistration 客户端注册信息 + * @param oidcAuthenticationToken oidc 认证token * @return 请求实体 */ - private RequestEntity createRequestEntity(ClientRegistration clientRegistration) { + private RequestEntity createRequestEntity(ClientRegistration clientRegistration, + OidcAuthenticationToken oidcAuthenticationToken) { URI uri = UriComponentsBuilder .fromUriString(clientRegistration.getProviderDetails().getTokenUri()) .build() .toUri(); - return new RequestEntity<>(this.createParameters(clientRegistration), + return new RequestEntity<>(this.createParameters(clientRegistration, oidcAuthenticationToken), this.createHttpHeaders(clientRegistration), HttpMethod.POST, uri); } @@ -250,6 +263,7 @@ private HttpHeaders createHttpHeaders(ClientRegistration clientRegistration) { HttpHeaders headers = new HttpHeaders(); headers.setAccept(List.of(APPLICATION_JSON)); headers.setContentType(APPLICATION_FORM_URLENCODED_UTF8); + if (ClientAuthenticationMethod.CLIENT_SECRET_BASIC.equals(clientRegistration.getClientAuthenticationMethod())) { String clientId = URLEncoder.encode(clientRegistration.getClientId(), StandardCharsets.UTF_8); String clientSecret = URLEncoder.encode(clientRegistration.getClientSecret(), StandardCharsets.UTF_8); @@ -262,11 +276,14 @@ private HttpHeaders createHttpHeaders(ClientRegistration clientRegistration) { * 设置参数 * * @param clientRegistration 客户端注册信息 + * @param oidcAuthenticationToken oidc token * @return 参数对象 */ - private MultiValueMap createParameters(ClientRegistration clientRegistration) { + private MultiValueMap createParameters(ClientRegistration clientRegistration, + OidcAuthenticationToken oidcAuthenticationToken) { MultiValueMap parameters = new LinkedMultiValueMap<>(); - parameters.set(OAuth2ParameterNames.GRANT_TYPE, AuthorizationGrantType.CLIENT_CREDENTIALS.getValue()); + parameters.set(OAuth2ParameterNames.GRANT_TYPE, AuthorizationGrantType.AUTHORIZATION_CODE.getValue()); + parameters.set(OAuth2ParameterNames.CODE, oidcAuthenticationToken.getCode()); if (!ClientAuthenticationMethod.CLIENT_SECRET_BASIC .equals(clientRegistration.getClientAuthenticationMethod())) { parameters.set(OAuth2ParameterNames.CLIENT_ID, clientRegistration.getClientId()); diff --git a/base-framework-security-starter/src/main/java/com/fuhouyu/framework/security/core/provider/oidc/OidcAuthenticationToken.java b/base-framework-security-starter/src/main/java/com/fuhouyu/framework/security/core/provider/oidc/OidcAuthenticationToken.java index ab4a513..c89ddb4 100644 --- a/base-framework-security-starter/src/main/java/com/fuhouyu/framework/security/core/provider/oidc/OidcAuthenticationToken.java +++ b/base-framework-security-starter/src/main/java/com/fuhouyu/framework/security/core/provider/oidc/OidcAuthenticationToken.java @@ -15,6 +15,7 @@ */ package com.fuhouyu.framework.security.core.provider.oidc; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -39,6 +40,7 @@ @Getter @Setter @ToString +@EqualsAndHashCode(callSuper = true) public class OidcAuthenticationToken extends AbstractAuthenticationToken { private final String code; @@ -47,11 +49,11 @@ public class OidcAuthenticationToken extends AbstractAuthenticationToken { private final String clientId; - private final transient OAuth2User principal; + private transient OAuth2User principal; - private final OAuth2AccessToken accessToken; + private OAuth2AccessToken accessToken; - private final OAuth2RefreshToken refreshToken; + private OAuth2RefreshToken refreshToken; private String nonce; @@ -68,11 +70,16 @@ public OidcAuthenticationToken(String code, String state, this.principal = principal; this.accessToken = accessToken; this.refreshToken = refreshToken; + this.setAuthenticated(true); } public OidcAuthenticationToken(String code, String state, String clientId) { - this(code, state, clientId, null, Collections.emptyList(), null, null); + super(Collections.emptyList()); + this.code = code; + this.state = state; + this.clientId = clientId; + this.setAuthenticated(false); } @Override diff --git a/base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/BaseComponent.java b/base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/BaseComponent.java deleted file mode 100644 index 87e6512..0000000 --- a/base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/BaseComponent.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2024-2024 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 com.fuhouyu.framework.security; - -import com.fuhouyu.framework.security.core.provider.refreshtoken.RefreshAuthenticationProvider; -import com.fuhouyu.framework.security.token.TokenStore; -import org.springframework.boot.test.context.TestComponent; -import org.springframework.context.annotation.Bean; -import org.springframework.security.authentication.AuthenticationProvider; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.provisioning.InMemoryUserDetailsManager; -import org.springframework.web.client.RestTemplate; - -import java.util.Collection; -import java.util.List; - -/** - *

- * - *

- * - * @author fuhouyu - * @since 2024/10/28 21:21 - */ -@TestComponent -class BaseComponent { - - @Bean - public AuthenticationProvider refreshTokenAuthenticationProvider(TokenStore tokenStore) { - return new RefreshAuthenticationProvider(tokenStore); - } - - @Bean - public RestTemplate restTemplate() { - return new RestTemplate(); - } - - @Bean - public UserDetailsService userDetailsService() { - UserDetails userDetails = new UserDetails() { - @Override - public Collection getAuthorities() { - return List.of(); - } - - @Override - public String getPassword() { - return "{noop}admin"; - } - - @Override - public String getUsername() { - return "admin"; - } - }; - return new InMemoryUserDetailsManager(userDetails); - } -} diff --git a/base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/BaseTest.java b/base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/BaseTest.java new file mode 100644 index 0000000..2cda060 --- /dev/null +++ b/base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/BaseTest.java @@ -0,0 +1,92 @@ +/* + * Copyright 2024-2024 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 com.fuhouyu.framework.security; + +import com.fuhouyu.framework.cache.CacheAutoConfiguration; +import com.fuhouyu.framework.cache.CaffeineCacheConfiguration; +import com.fuhouyu.framework.security.core.provider.refreshtoken.RefreshAuthenticationProvider; +import com.fuhouyu.framework.security.token.TokenStore; +import org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.TestComponent; +import org.springframework.context.annotation.Bean; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.test.context.TestPropertySource; +import org.springframework.web.client.RestTemplate; + +import java.util.Collection; +import java.util.List; + +/** + *

+ * 基类测试类 + *

+ * + * @author fuhouyu + * @since 2024/11/5 20:51 + */ +@SpringBootTest(classes = { + BaseTest.BaseComponent.class, + CacheAutoConfiguration.class, + CaffeineCacheConfiguration.class, + OAuth2ClientAutoConfiguration.class, + SecurityAutoConfiguration.class, +}) +@TestPropertySource(locations = {"classpath:application.yaml"}) +@EnableWebSecurity +abstract class BaseTest { + + + @TestComponent + static class BaseComponent { + + @Bean + public AuthenticationProvider refreshTokenAuthenticationProvider(TokenStore tokenStore) { + return new RefreshAuthenticationProvider(tokenStore); + } + + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } + + @Bean + public UserDetailsService userDetailsService() { + UserDetails userDetails = new UserDetails() { + @Override + public Collection getAuthorities() { + return List.of(); + } + + @Override + public String getPassword() { + return "{noop}admin"; + } + + @Override + public String getUsername() { + return "admin"; + } + }; + return new InMemoryUserDetailsManager(userDetails); + } + } +} diff --git a/base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/OidcProviderTest.java b/base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/OidcProviderTest.java index 0569f01..7d4b46d 100644 --- a/base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/OidcProviderTest.java +++ b/base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/OidcProviderTest.java @@ -15,17 +15,13 @@ */ package com.fuhouyu.framework.security; -import com.fuhouyu.framework.cache.CacheAutoConfiguration; -import com.fuhouyu.framework.cache.CaffeineCacheConfiguration; import com.fuhouyu.framework.security.core.provider.oidc.OidcAuthenticationToken; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.test.context.TestPropertySource; +import org.springframework.security.core.Authentication; /** *

@@ -35,21 +31,12 @@ * @author fuhouyu * @since 2024/11/4 22:12 */ -@SpringBootTest(classes = { - OAuth2ClientAutoConfiguration.class, - CacheAutoConfiguration.class, - CaffeineCacheConfiguration.class, - SecurityAutoConfiguration.class, - BaseComponent.class -}) -@SpringBootApplication @Disabled -@TestPropertySource(locations = {"classpath:application.yaml"}) -class OidcProviderTest { +class OidcProviderTest extends BaseTest { - private static final String CODE = "code"; + private static final String CODE = "17896f8f71b37868e2e399d814f53ca06e3c4f6a94dc3132d688f0b8b767c907"; - private static final String STATE = "state"; + private static final String STATE = "-02_gJnVuE_n-rsQilIWRM82bBBXxO9z5VdIfSDlfAU="; @Autowired private AuthenticationManager authenticationManager; @@ -57,6 +44,8 @@ class OidcProviderTest { @Test void testOidc() { OidcAuthenticationToken oidcAuthenticationToken = new OidcAuthenticationToken(CODE, STATE, "gitlab"); - authenticationManager.authenticate(oidcAuthenticationToken); + Authentication authenticate = authenticationManager.authenticate(oidcAuthenticationToken); + Assertions.assertNotNull(authenticate); + Assertions.assertTrue(authenticate.isAuthenticated()); } } diff --git a/base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/RefreshTokenTest.java b/base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/RefreshTokenTest.java index e6c4079..f88fab8 100644 --- a/base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/RefreshTokenTest.java +++ b/base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/RefreshTokenTest.java @@ -15,8 +15,6 @@ */ package com.fuhouyu.framework.security; -import com.fuhouyu.framework.cache.CacheAutoConfiguration; -import com.fuhouyu.framework.cache.CaffeineCacheConfiguration; import com.fuhouyu.framework.security.core.GrantTypeAuthenticationTokenEnum; import com.fuhouyu.framework.security.entity.GrantTypeAuthenticationEntity; import com.fuhouyu.framework.security.entity.TokenEntity; @@ -24,12 +22,10 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; -import org.springframework.test.context.TestPropertySource; /** *

@@ -39,14 +35,7 @@ * @author fuhouyu * @since 2024/10/22 22:21 */ -@SpringBootTest(classes = { - CacheAutoConfiguration.class, - CaffeineCacheConfiguration.class, - SecurityAutoConfiguration.class, - BaseComponent.class -}) -@TestPropertySource(locations = {"classpath:application.yaml"}) -class RefreshTokenTest { +class RefreshTokenTest extends BaseTest { @Autowired private TokenStore tokenStore; diff --git a/base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/Sm3PasswordEncoderTest.java b/base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/Sm3PasswordEncoderTest.java index 04441ab..596f39e 100644 --- a/base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/Sm3PasswordEncoderTest.java +++ b/base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/Sm3PasswordEncoderTest.java @@ -16,14 +16,10 @@ package com.fuhouyu.framework.security; -import com.fuhouyu.framework.cache.CacheAutoConfiguration; -import com.fuhouyu.framework.cache.CaffeineCacheConfiguration; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.test.context.TestPropertySource; /** *

@@ -33,14 +29,7 @@ * @author fuhouyu * @since 2024/9/7 22:32 */ -@SpringBootTest(classes = { - CacheAutoConfiguration.class, - CaffeineCacheConfiguration.class, - SecurityAutoConfiguration.class, - BaseComponent.class -}) -@TestPropertySource(locations = {"classpath:application.yaml"}) -class Sm3PasswordEncoderTest { +class Sm3PasswordEncoderTest extends BaseTest { @Autowired private PasswordEncoder passwordEncoder; diff --git a/base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/TokenStoreTest.java b/base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/TokenStoreTest.java index f14a5e9..9cb845b 100644 --- a/base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/TokenStoreTest.java +++ b/base-framework-security-starter/src/test/java/com/fuhouyu/framework/security/TokenStoreTest.java @@ -16,21 +16,16 @@ package com.fuhouyu.framework.security; -import com.fuhouyu.framework.cache.CacheAutoConfiguration; -import com.fuhouyu.framework.cache.CaffeineCacheConfiguration; -import com.fuhouyu.framework.cache.service.CacheService; import com.fuhouyu.framework.security.entity.TokenEntity; import com.fuhouyu.framework.security.token.TokenStore; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.User; import org.springframework.security.oauth2.core.OAuth2RefreshToken; -import org.springframework.test.context.TestPropertySource; import java.util.Collections; @@ -42,18 +37,7 @@ * @author fuhouyu * @since 2024/8/14 22:35 */ -@SpringBootTest(classes = { - CacheAutoConfiguration.class, - CaffeineCacheConfiguration.class, - SecurityAutoConfiguration.class, - BaseComponent.class -}) -@TestPropertySource(locations = {"classpath:application.yaml"}) -class TokenStoreTest { - - - @Autowired - private CacheService cacheService; +class TokenStoreTest extends BaseTest { @Autowired private TokenStore tokenStore; diff --git a/base-framework-security-starter/src/test/resources/application.yaml b/base-framework-security-starter/src/test/resources/application.yaml index d700ca3..46912ea 100644 --- a/base-framework-security-starter/src/test/resources/application.yaml +++ b/base-framework-security-starter/src/test/resources/application.yaml @@ -2,24 +2,4 @@ base: framework: cache: service: - cache-service-type: caffeine -spring: - security: - oauth2: - client: - registration: - gitlab: - provider: gitlab - client-id: b8cfade18e2d4a264c768076e0fdb0492bcb35802a85e1ff6c73ebe16043a268 - client-secret: gloas-1f0346b92b61a5d04f3a98df8abbe79ad380c500817011a9f06b3a47f6e0980c - authorization-grant-type: authorization_code - redirect-uri: http://127.0.0.1:8080/login/oauth2/code/login-client - scope: openid,profile - client-name: gitlab - provider: - gitlab: - authorization-uri: https://gitlab.com/oauth/authorize - token-uri: https://gitlab.com/oauth/token - user-info-uri: https://gitlab.com/oauth/userinfo - jwk-set-uri: https://gitlab.com/oauth/discovery/keys - user-name-attribute: email \ No newline at end of file + cache-service-type: caffeine \ No newline at end of file