Archives

Category: Spring Framework

How can we implement OAuth2 with Spring Boot?

This blog post assumes that you know what is the OAuth2 protocol and how it works. If you do not know, I advise you to do some research and come back later as you may not fully understand it from reading this blog post.

There are several examples online but most of them are using some sort of in memory database. If your system is going to production you, most likely, do not want to use an in memory database to store the user tokens when you have multiple server instances. You want some sort of a central location (or distributed with some level of consistency) where you’ll be storing the OAuth data for each user account. The easiest is using a SQL database and this is going to be our example.

First, it’s time to setup the database tables for the OAuth2, therefore we need the following tables:

oauth_client_details

oauth_client_token

oauth_access_token

oauth_refresh_token

oauth_code

oauth_approvals

ClientDetails

As we are using Spring Boot we can create a file named
schema.sql in the resources folder with our schema definition. On boot time, Spring Boot will detect the file and will run it against our selected database – quite handy isn’t it?

When the database schema is all set, we need to populate the
oauth_client_details table. Again, Spring Boot helps making our life easier. To do so, we just need to create a file named
data.sql and, as with the
schema.sql , Spring Boot on boot time will pick the file and run in against our database.

At this point we have everything related with the SQL database ready to go.

Now, to the coding. We need to add the
@EnableResourceServer annotation to our Spring application, and we do it as easy as:

1

2

3

4

5

6

7

8

@EnableResourceServer

@SpringBootApplication

publicclassOauthExampleApplication{

publicstaticvoidmain(String[]args){

SpringApplication.run(OauthExampleApplication.class,args);

}

}

The next step is to configure our
DataStore and our
TokenStore . To do so we create an
AppConfig.class (wich is a configuration class) and define it there (you can define it somewhere else as long as you set the
@Bean annotation to both methods).

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

@Configuration

publicclassAppConfig{

@Value("${spring.datasource.url}")

privateStringdatasourceUrl;

@Value("${spring.database.driverClassName}")

privateStringdbDriverClassName;

@Value("${spring.datasource.username}")

privateStringdbUsername;

@Value("${spring.datasource.password}")

privateStringdbPassword;

@Bean

publicDataSource dataSource(){

finalDriverManagerDataSource dataSource=newDriverManagerDataSource();

dataSource.setDriverClassName(dbDriverClassName);

dataSource.setUrl(datasourceUrl);

dataSource.setUsername(dbUsername);

dataSource.setPassword(dbPassword);

returndataSource;

}

@Bean

publicTokenStore tokenStore(){

returnnewJdbcTokenStore(dataSource());

}

}

As we can see above, our
TokenStore is defined by a
JdbcTokenStore which extends
TokenStore . We also pass the
DataSource to the
JdbcTokenStore and therefore we let the application know we are using the specified
DataSource to store all our OAuth2 data. On the other hand, the
DataSource specifies that we are using a SQL database. See how it all interconnects here? Perfect.

But this is not enough. Now we need to wired everything up, the database – the authorization server – Spring Boot application. The authorization server will be the bridge here. So, lets start with it. We create a class (
AuthServerOAuth2Config) to extend
AuthorizationServerConfigurerAdapter . Then we need to override
configure(ClientDetailsServiceConfigurer clients), configure(AuthorizationServerSecurityConfigurer security) and
configure(AuthorizationServerEndpointsConfigurer endpoints) methods to wire everything up.

.tokenStore(appConfig.tokenStore());// Persist the tokens in the database

}

}

And now we have OAuth2 with JDBC implemented. We can start generating some tokens by making POST requests to our server at /oauth/token with the Authorization type, headers and body (form data) properly set up.

Optionally we may want to create an endpoint that will return all information for the user calling it. To do so, we create the
PrincipalResource.class as shown below