diff --git a/xs-server/src/main/resources/application-local.yml b/xs-server/src/main/resources/application-local.yml index fdab7e5..d0d654e 100644 --- a/xs-server/src/main/resources/application-local.yml +++ b/xs-server/src/main/resources/application-local.yml @@ -24,4 +24,11 @@ spring: user: auth: - issuer: http://127.0.0.1:38011 \ No newline at end of file + issuer: http://127.0.0.1:38011 + # Web 应用前端回调地址: + # http://localhost:8080/login/oauth2/code/oauth-client-init + # Postman 测试用: + # https://oauth.pstmn.io/v1/callback + # 移动端 APP 自定义 Scheme: + # myapp://callback + redirectUrl: http://localhost:8080/login/oauth2/code/oauth-client-init \ No newline at end of file diff --git a/xs-server/src/main/resources/application-test.yml b/xs-server/src/main/resources/application-test.yml new file mode 100644 index 0000000..d0d654e --- /dev/null +++ b/xs-server/src/main/resources/application-test.yml @@ -0,0 +1,34 @@ +spring: + datasource: + dynamic: + primary: master + datasource: + master: + url: jdbc:mysql://rm-bp15t34gqx62jm069ro.mysql.rds.aliyuncs.com:3306/xservice-user?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowMultiQueries=true + username: root + password: xb#UWqnhH24&XpX + driver-class-name: com.mysql.cj.jdbc.Driver + sshConnect: false + redis: + host: r-bp1wt59a6nfyt4e3ltpd.redis.rds.aliyuncs.com + port: 6379 + password: Admin@123 # 如果无密码可以省略 + database: 0 + timeout: 5000 + lettuce: + pool: + max-active: 8 + max-idle: 8 + min-idle: 0 + max-wait: 1000 + +user: + auth: + issuer: http://127.0.0.1:38011 + # Web 应用前端回调地址: + # http://localhost:8080/login/oauth2/code/oauth-client-init + # Postman 测试用: + # https://oauth.pstmn.io/v1/callback + # 移动端 APP 自定义 Scheme: + # myapp://callback + redirectUrl: http://localhost:8080/login/oauth2/code/oauth-client-init \ No newline at end of file diff --git a/xs-service/src/main/java/com/xiang/xservice/auth/service/config/AuthorizationServerConfig.java b/xs-service/src/main/java/com/xiang/xservice/auth/service/config/AuthorizationServerConfig.java index 629b4c3..bda77aa 100644 --- a/xs-service/src/main/java/com/xiang/xservice/auth/service/config/AuthorizationServerConfig.java +++ b/xs-service/src/main/java/com/xiang/xservice/auth/service/config/AuthorizationServerConfig.java @@ -5,10 +5,12 @@ import com.nimbusds.jose.jwk.RSAKey; import com.nimbusds.jose.jwk.source.JWKSource; import com.nimbusds.jose.proc.SecurityContext; import com.xiang.xservice.basic.utils.JwkUtils; +import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.ProviderManager; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; @@ -21,22 +23,28 @@ import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.core.ClientAuthenticationMethod; import org.springframework.security.oauth2.jwt.JwtEncoder; import org.springframework.security.oauth2.jwt.NimbusJwtEncoder; -import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository; +import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository; 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.settings.AuthorizationServerSettings; import org.springframework.security.oauth2.server.authorization.settings.ClientSettings; +import org.springframework.security.oauth2.server.authorization.settings.TokenSettings; import org.springframework.security.web.SecurityFilterChain; - +import java.time.Duration; +import java.util.Objects; import java.util.UUID; @Configuration(proxyBeanMethods = false) +@RequiredArgsConstructor public class AuthorizationServerConfig { @Value("${user.auth.issuer}") private String issuer; + @Value("${user.auth.redirectUrl}") + private String redirectUrl; + private final JdbcTemplate jdbcTemplate; @Bean @Order(1) @@ -54,7 +62,6 @@ public class AuthorizationServerConfig { .authorizeRequests(authorizeRequests -> authorizeRequests .antMatchers("/public/**").permitAll() .antMatchers("/open/**").permitAll() - .antMatchers("/private/**").permitAll() .anyRequest().authenticated() ) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)); @@ -77,18 +84,33 @@ public class AuthorizationServerConfig { @Bean public RegisteredClientRepository registeredClientRepository(PasswordEncoder passwordEncoder) { - RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString()) - .clientId("messaging-client") - .clientSecret(passwordEncoder.encode("secret")) // 演示用,生产请加密 - .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC) - .authorizationGrantType(AuthorizationGrantType.PASSWORD) - .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) - .scope("message.read") - .scope("message.write") - .clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build()) - .build(); - // todo 暂时内存保存,后续需要配合数据库保存 - return new InMemoryRegisteredClientRepository(registeredClient); + JdbcRegisteredClientRepository repository = new JdbcRegisteredClientRepository(jdbcTemplate); + + String clientId = "oauth-client-init"; + RegisteredClient existingClient = repository.findByClientId(clientId); + if (Objects.isNull(existingClient)) { + RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString()) + .clientId(clientId) + .clientSecret(passwordEncoder.encode("xxCompany-xx")) + .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC) + .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) // 已过时, 建议自己实现扩展 + .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) + .redirectUri(redirectUrl) + .scope("message.read") + .scope("message.write") + .clientSettings(ClientSettings.builder() + .requireAuthorizationConsent(true) + .build()) + .tokenSettings(TokenSettings.builder() + .accessTokenTimeToLive(Duration.ofHours(1)) + .refreshTokenTimeToLive(Duration.ofDays(30)) + .reuseRefreshTokens(true) + .build()) + .build(); + + repository.save(registeredClient); + } + return repository; } @Bean