【问题标题】:How to dynamically change client_secret in Spring Security with Spring boot如何使用 Spring Boot 在 Spring Security 中动态更改 client_secret
【发布时间】:2021-05-20 13:50:46
【问题描述】:

现在我有了这个配置:

spring:
  security:
    oauth2:
      client:
        registration:
          sbbol:
            client-id: zdcffffff
            client-secret: ffffffffff
            scope:
              - openid
            client-authentication-method: post
            authorization-grant-type: authorization_code
            redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
            client-authentication-scheme: form
        provider:
          sbbol:
            authorization-uri: ${SBBOL_AUTH_URI}
            token-uri: ${SBBOL_AUTH_URI}
            user-info-uri: ${SBBOL_AUTH_URI}
            user-name-attribute: sub
@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic().disable();
        http.cors().disable();
        http.csrf().disable();
        http.requestMatchers()
            .antMatchers("/login", "/oauth2/authorization/sbbol", "/login/oauth2/code/sbbol")
            .and()
            .authorizeRequests().anyRequest().authenticated();
        http.oauth2Login()
            .defaultSuccessUrl("/user")
            .permitAll();
    }
}

这可行,但我的提供商要求我每 30 天通过一次休息 api 调用更改客户端密码。我有一个问题,如何在 Spring Security 中设置新的客户端密码?也许我可以将配置存储在数据库中?

【问题讨论】:

  • 是的,您需要将这些详细信息保存在数据库中。您可以使用oauth_client_details 表和以下类似类型的列来保存详细信息,稍后您可以使用其余界面更改它。 client_id, client_secret, scope, authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove
  • @harry 在我的情况下这完全可能吗?我认为这只有在 OAuth 2.0 服务器上才有可能。就我而言,我是客户。我正在尝试连接到与 Google 或 Okta 相同的 SSO 提供商
  • 上述情况适用于当您的应用也充当 OAuth 提供者时,在同一服务或单独的独立服务器中运行 OAuth 服务器。由于您的提供商是第 3 方服务器,因此在这种情况下,正如您所提到的,他们正在公开一个端点来更改它,因此您需要使用自定义解决方案。

标签: java spring spring-boot spring-security


【解决方案1】:

我为 org.springframework.security.oauth2.client.registration.ClientRegistrationRepository 创建了自己的实现。我可以将设置存储在数据库中并进行更改。

@Component
@RequiredArgsConstructor
public class JdbcClientRegistrationRepository implements ClientRegistrationRepository {

    private final SsoProviderConfigurationRepository ssoProviderConfigurationRepository;

    @Override
    public ClientRegistration findByRegistrationId(String registrationId) {
        Assert.hasText(registrationId, "registrationId cannot be empty");
        SsoProviderConfiguration providerConfiguration = ssoProviderConfigurationRepository.findByRegistrationId(registrationId)
            .orElseThrow(() -> new RuntimeException("ClientRegistration not found by id=" + registrationId));

        String[] scopes = providerConfiguration.getScope().split(",");
        return ClientRegistration.withRegistrationId(providerConfiguration.getRegistrationId())
            .clientId(providerConfiguration.getClientId())
            .clientSecret(providerConfiguration.getClientSecret())
            .clientName(providerConfiguration.getClientName())
            .authorizationGrantType(new AuthorizationGrantType(providerConfiguration.getAuthorizationGrantType()))
            .authorizationUri(providerConfiguration.getAuthorizationUri())
            .clientAuthenticationMethod(new ClientAuthenticationMethod(providerConfiguration.getClientAuthenticationMethod()))
            .scope(scopes)
            .tokenUri(providerConfiguration.getTokenUri())
            .userInfoAuthenticationMethod(new AuthenticationMethod(providerConfiguration.getAuthenticationMethod()))
            .userInfoUri(providerConfiguration.getUserInfoUri())
            .userNameAttributeName(providerConfiguration.getUserNameAttributeName())
            .redirectUri(providerConfiguration.getRedirectUri())
            .build();
    }
}

我的实体

@Entity
@Table(name = "sso_provider_configuration")
@Getter
@Setter
@NoArgsConstructor
public class SsoProviderConfiguration implements Serializable {

    private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", unique = true, nullable = false)
    private Long id;

    private String registrationId;

    private String clientId;

    private String clientSecret;

    private String clientAuthenticationMethod;

    private String authorizationGrantType;

    private String redirectUri;

    private String scope;

    private String clientName;

    private String authorizationUri;

    private String tokenUri;

    private String jwkSetUri;

    private String issuerUri;

    private String authenticationMethod;

    private String userNameAttributeName;

    private String UserInfoUri;
}

存储库

public interface SsoProviderConfigurationRepository extends JpaRepository<SsoProviderConfiguration, Long> {

    Optional<SsoProviderConfiguration> findByRegistrationId(String code);
}

【讨论】:

    【解决方案2】:

    我有这个可能有用,它不是动态的,但你可以解决

    @Value("${security.oauth.client.id}")
    private String clientId;
    
    @Value("${security.oauth.client.password}")
    private String clientPassword;
    
    
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    
        
        
        clients.inMemory()
        .withClient(clientId)
        .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
        .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
        .scopes("read", "write", "trust")
        .secret(clientPassword)
        .resourceIds("resource_id")
        .accessTokenValiditySeconds(accessTokenTimeOut)
        .refreshTokenValiditySeconds(refreshTokenTimeOut)
       ;
    
        
    }
    

    【讨论】:

      猜你喜欢
      • 2019-12-18
      • 2020-05-29
      • 2014-08-02
      • 2018-04-06
      • 1970-01-01
      • 2023-03-06
      • 2016-05-04
      • 1970-01-01
      • 2021-06-26
      相关资源
      最近更新 更多