Search code examples
javaspring-bootoauth-2.0spring-security-oauth2spring-security-rest

OAuth 2.0 with Implict Grant type Spring boot app


We are building an application with following tech specs decided.

  • Angular 4/5 [Front End]
  • SpringBoot Framework [BackEnd]
  • OAuth 2.0 [Authorization]
  • MySQL [Database]

Note : We ourselves are having Resource Server, Authorization Server


Flow

We provide a single instance application for multiple clients [our clients], who will have their own users. Every user will get an email to authorize some stuff for their respective clients via our application. The email link will contain client_id, record_id encrypted and encoded. When the user clicks on the link, it should go to AuthServer, authorize the client via its client_id, and pass back the token to the user agent, to make any further operations.

We went through this Github repo and implemented the same as the sample.

The AuthServer Configure code is as below:

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
       clients.inMemory().withClient("my-trusted-client")
             .authorizedGrantTypes("password", "authorization_code",
                            "refresh_token", "implicit")
             .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
             .scopes("read", "write", "trust").resourceIds("sparklr")
             .accessTokenValiditySeconds(60).and()
             .withClient("my-client-with-registered-redirect")
      .authorizedGrantTypes("authorization_code").authorities("ROLE_CLIENT")
             .scopes("read", "trust").resourceIds("sparklr")
             .redirectUris("http://anywhere?key=value").and()
             .withClient("my-client-with-secret")
             .authorizedGrantTypes("client_credentials", "password")
                    .authorities("ROLE_CLIENT").scopes("read").resourceIds("sparklr")
             .secret("secret");

}

We have some doubts on the values passed to the configure method.

  • What does .inMemory().withClient("my-trusted-client") represent here? Will this always be hardcoded? Since we would be validating each client based on the client_id received, where will we feed this to validate dynamically?
  • What is .withClient("my-client-with-registered-redirect") for? Even this remains constant for every client?
  • The author in the repo has also said that we can validate the setup via $ curl -H "Accept: application/json" my-client-with-secret:secret@localhost:8080/oauth/token -d grant_type=client_credentials and I see my-client-with-secret:secret passed here. If this is going to be changed for different clients how can I give this value to .withClient("my-client-with-secret") and .secret("secret")

We are totally tough time understanding these concepts. Our requirement is simple, We are going to validate every client with client_id and generate a token for that client. Do we need to have any other Grant_types for this type of requirements?

Someone please point us in the right direction.


Solution

  • First question: In your example, the clients are hardcoded (hence the clients.inMemory()). You can configure a datasource and use that:

    @Autowired
    DataSource dataSource;
    
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.jdbc(dataSource); // Get clients from database, table = oauth_client_details
    }
    

    You can find more info in the documentation

    Second question In the example, three clients are configured:

    1. my-trusted-client: this client can authorize using these OAuth2 flows: "password", "authorization_code", "refresh_token", "implicit"
    2. my-client-with-registered-redirect: this client can authorize using these OAuth2 flows: "authorization_code"
    3. my-client-with-secret: this client can authorize using these OAuth2 flows: "client_credentials"

    You need to understand the difference between these flows.

    Third question if you want to use other clients, you must add them in your code/database