A couple weeks ago I needed to develop an application using “state of the art” technologies working with OAuth support. I was thinking that I had a good understanding of the OAuth standard, because I had read a couple of documentation about it and the most important part is that Spring Framework has OAuth support. That gave me relief. I started developing my application and had lots of trouble as I always have. I will write about the problems that I faced during the development phase. This is not a “how to do oauth auhentication using Spring Framwork” article. It is about the problems that I faced and how I solved them.
You can have a look from here if you want to know about OAuth .
Let’s start with the definition of the problem (the aim of application). There would be an application that connects to a public API using OAuth authentication. Then it should retrieve an access token and call other endpoints using this access token. I have drawn a basic architecture diagram:
Here I am planning to develop two applications. The first is a UI application for which I think VueJS application will be sufficient. The second is a backend application for which Spring Framework is a good candidate for developing because it has good support of OAuth and has Spring Security for us to make things easier. At least, I thought it would make things easier.
Between UI and backend I thought that JWT token is a good approach to make the application stateless.
The Flow
- When user opens the application he/she needs to click login button.
- Application is being redirected to OAuth server.
- After the user logs in and gives the consent approval
- Oauth server redirects the user back to my application.
- Starting from this point, the user is free to use the application since the user has logged in.
What’s happening under the hood
First let’s list all steps to install an OAuth provided application.
- Need to sign up to a OAuth provider. Google, Facebook, Github etc.
- Need to create an application in the admin(developer) panel of provider and produces public and private keys binded with the application.
- Need to create a Spring application with security and oauth extension.
- Configure the application using application.properties file.
Until this point there is no problem. You can find lots of tutorials to reach this point. The most known source is Spring Framework’s official page
The first problem: UserInfo Uri
When I completed the Spring Framework tutorial and tons of similar tutorials, I kept getting the same error again and again:
Missing required UserInfo Uri in UserInfoEndpoint for Client Registration
When I tried to find a solution for this, I got some information using this discussion. In short, people say that spring needs to know who signed into the application to construct the pricipal (Spring security concept) object. The OAuth provider I used did not provide UserInfoURI because of security concerns. I think it is not a good approach. The company advised me to bypass this operation which I didn’t know how to do. There are lots of Spring documents and tutorials which do the same thing again and again. I might say I found maybe 10 different Spring and OAuth tuturials, they all do the same thing which is my second problem.
The second problem: JWT/Oauth/Spring Security
I successfully created a principal object of spring using a dummy user. When spring user and oauth are being used together, the application creates HTTP session but I don’t want it because I want it to be stateless. To make a separation of how to handle JWT tokens and OAuth, I developed another application as an example of stateless spring security application backed by JWT token.
Now I have two backend applications, the first one is a non-complete spring security application which is not able to get user info and leads us fail on auth. The second one is a stateless spring application that uses a JWT token for security. In addition, I have a customer which does not want to give me a link that provides a mandatory info for Spring.
Conclusion
I spent so much time to overcome the issue.
Eventually I decided on dropping spring oauth integration part and developed my own OAuth code base to get the token in the end.
I redirected my application to OAuth server, get the consent and the code to get the access code manually. Then I retrieve access code using required HTTP methods. I created Spring’s principal using a dummy data if application gathers the access code successfully. I encrypted the access code into JWT token.
Since oauth provider does not want to share userinfo, it is a complete problem from Spring Oauth perspective. I might have another options but removing Oauth part from application and handling it manually made my progress much more efficient.
Now it is working.