Search code examples
javaspring-bootspring-securityoauth-2.0spring-security-oauth2

How to generate client-id & client-secret in spring-boot and store in database?


I know questions similar to this already exist on stackoverflow. When I went through them, it didn't solved the problem I'm looking for.

I've a spring-boot web service as Oaut2ClientManagement, in which I've creating an API which will basically register a new client. When new company is getting registered, the companyId(it is predefined in some company_details table, yes the company is added in list but not registered to access APIs) is sent so based on that I've to generate client-id & client-secret which I'll store in CLIENT_KEY_MANAGEMENT table. Based on this I write a java code to generating accessToken.

So my question here is how can I generate client-id & client-secret based on companyId I've received in request ? I've went through this answer. But is there any pre-defined way in spring-boot oauth which can do this job ? As next step is to generate access token based on it.

I also went through oAuth tutorial. But, in this the client-id & client-secret are stored in properties file not in Database/other source. Also seems like it's single pair.

It will be great if someone can guide me to achieve above scenario using spring-boot.


Solution

  • There is a JdbcClientDetailsService for this specific purpose.

    You need to define the following table in your database

    create table oauth_client_details (
      client_id VARCHAR(256) PRIMARY KEY,
      resource_ids VARCHAR(256),
      client_secret VARCHAR(256),
      scope VARCHAR(256),
      authorized_grant_types VARCHAR(256),
      web_server_redirect_uri VARCHAR(256),
      authorities VARCHAR(256),
      access_token_validity INTEGER,
      refresh_token_validity INTEGER,
      additional_information VARCHAR(4096),
      autoapprove VARCHAR(256)
    );
    

    and configure your Oauth2 authorization server as following

    @Configuration
    @EnableAuthorizationServer
    public class OAuth2AuthorizationServerConfigurer extends AuthorizationServerConfigurerAdapter {
    
        @Autowired
        private DataSource dataSource;
    
        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            clients.jdbc(dataSource);
        }
    
    }
    

    And finally you can inject JdbcClientDetailsService bean in the location you are registering a companyId.

    @Autowired
    JdbcClientDetailsService jdbcClientDetailsService;
    
    ...
    BaseClientDetails clientDetails = new BaseClientDetails(companyId, resourceIds, scopes, grantTypes, authorities);
    clientDetails.setClientSecret("generatedpassword");
    jdbcClientDetailsService.addClientDetails(clientDetails);
    

    Finally you can login using those client credentials.

    UPDATE

    If you want your passwords to be hashed you can set a PasswordEncoder as below.

    clients.jdbc(dataSource)
                    .passwordEncoder(new BCryptPasswordEncoder())
    

    BaseClientDetails is available in package org.springframework.security.oauth2.provider.client.

    The client secret will not be generated by the service. You need to generate it and set it to BaseClientDetails.