As you might have noticed in my previous blog posts, I am a big fan of Spring + Java and Spring + Kotlin. Consequently, whenever I need to implement an OAuth 2.0 authentication, spring-security-oauth2 lib is a natural choice.

However, there are next to nothing articles out there showing how to connect spring-security-oauth2 with different data sources other than inMemory and JDBC. As we have to configure a lot of stuff, I will divide this tutorial into 3 parts: How to authenticate a user, how to configure a token store and how to configure dynamic clients. So, let’s get started!

First, I am assuming that you are using one of the latest versions of spring-security-oauth2:

Second, I am using Couchbase with Spring Data. If you are using any other data source, you can still reuse a lot of code from this blog series.

Additionally, I have added Lombok as a dependency to reduce Java’s boilerplate:

Let’s configure our Resource Server, according to spring-security-oauth2 docs: “A Resource Server (can be the same as the Authorization Server or a separate application) serves resources that are protected by the OAuth2 token. Spring OAuth provides a Spring Security authentication filter that implements this protection. You can switch it on with @EnableResourceServer on an @Configuration class, and configure it (as necessary) using a ResourceServerConfigurer”

 

Now, let’s implement an interface called UserDetailsService. It is the interface responsible to be the bridge between your data source and Spring Security:

In the code above, we are returning a class of the type UserDetails, which is also from Spring. Here is its implementation:

I could have just made the User class implement the UserDetails directly. However, as my use case also requires the list of groups in which the user is in, I have added the implementation above.

Here are how the User, SecurityGroup and their respective repositories look like:

The BasicEntity class is also a small hack to better work with Spring Data and Couchbase:

 

Finally, here is the implementation of our SecurityConfig class:

 

We can’t inject directly the AuthenticationManager bean anymore in Spring-Boot 2.0, but it still is required by Spring Security. Therefore, we need to implement a small hack in order to gain access to this object:

Let’s break this class into small pieces to understand what is going on:

My user’s password is in plain text, so I just return a new instance of NoOpPasswordEncoder. A common standard is to return an instance of the BCryptPasswordEncoder class.

For now, we are going to use an in-memory token store, we will see in the part 2 how to also use Couchbase as a token store.

Here is where the magic happens, as we are telling Spring to use our CustomUserDetailsService to search for users. This block of code is the core part of what we have done so far.

This block will allow us to make requests using CORS (Cross-Origin Resource Sharing)

And finally, if you need to call your API via JQuery, you also need to add the code above. Otherwise, you will get a “Response for preflight does not have HTTP ok status.” Error.

There is just one thing left now, we need to add an Authorization Server:

Well done!, now you can  start your app and call it via Postman or Jquery:

 

Boosting performance

If you are using Couchbase, I suggest you use the username as the key of your document. It will allow you to use the Key-Value Store instead of executing N1QL queries, which will increase significantly the performance of your login.

 

If you have any questions, just tweet me at @deniswsrosa

Posted by Denis Rosa, Developer Advocate, Couchbase

Denis Rosa is a Developer Advocate for Couchbase and lives in Munich - Germany. He has a solid experience as a software engineer and speaks fluently Java, Python, Scala and Javascript. Denis likes to write about search, Big Data, AI, Microservices and everything else that would help developers to make a beautiful, faster, stable and scalable app.

One Comment

  1. Very nice article. Could you please share the code for this post?

Leave a reply