Skip to main content

Angular 5, SpringBoot 2, Oauth2 and IMPLICIT flow - silent token refresh

Recently I've been working on simple web application for managing students and users. Application will be published on the internet, so it needs proper access control. I wanted to learn some new stuff, so I decided to use Angular5 with Oauth2 authentication. I didn't want to use any options as "Login with Facebook", or "Login with Google". I wanted my Spring Boot app to work as the authentication server and the resource server.
I read a little abouth Oauth2 and different flows possible, and it turns out, that preffered flow to use with web application is IMPLICIT flow.

Implicit flow uses only one token. It doesn't have a refresh token, as it could be overtaken by an attacker.
Access token has defined validity period. In other flows, where refresh token exists it is used to get another access token when the first one expires.
In theory in implicit flow user should just log again, but forcing a user to log in during active session is not an option.

There is a method called "silent token refresh", when there is invisible iframe present on a web page. When access token validity period is finishing, it automaticaly make request to authentication server for a new token with parameter "prompt=none".

In Spring default path to get Oauth2 token is:

/oauth/authorize?response_type=token&client_id=your-client-id&prompt=none
On angular5 frontend I use angular-oauth2-oidc library for authorization.
It supports silent token refresh by default. It is very well described in documentation:

When I tried to use that method with SpringBoot as authentication server, I discovered that it doesn't work by default. When I send request to backend for new token, DefaultTokenServices.createAccessToken method is called.
It checks if existing token is valid. When a token is valid,  it just returns existing token, instead of generating new one. 

I was looking for any good solution on the internet, but I didn't find any, so I decided to override default behaviour of DefaultTokenServices class, to support "prompt=none" param.
Here is a code of my CustomTokenServicess class:



When my CustomTokenServices class discovers there is "prompt=none" param presents, it assumes, that app wants to silently refresh token, so it removes current token and generates new one, otherwise it just uses DefaultTokenServices functionality.

It might not be a perfect solution, but it works very well.

On my github You can find complete working applicaction with sample usage of this method:

https://github.com/aogorek/springboot-oauth2-angular2

It uses SpringBoot2, Spring Security 5, Angular5, Material Design, custom login page, and few other interesting things.

so go, clone the repository, test it, and feel free to comment. I'm curious of Your opinion about this solution. Maybe You have better idea to solve this scenario?







Comments

  1. How do you configure resource service with a individual project? Please

    ReplyDelete
  2. thanks for this project , but i think there is a problem with the silent refresh token because i get a token expired error . in the session storage the token is refreshed .

    ReplyDelete
  3. In line 60, the refresh token will always be null and it is never initialized with a value. What is the point of that? Also implicit flow doesn't support refresh tokens, so there seems to be no need for creating one anyway.

    ReplyDelete
  4. Nice articel, This article help me very well. Thank you. Also please check my article on my site about What Is Angular?.

    ReplyDelete

Post a Comment

Popular posts from this blog

Control OpenHab using Telegram Messenger

Recently, I've been trying to discover a way to control my OpenHab instance using Google Assistant. It is rather easy to do this using  IFTTT , but only when You use OpenHab in a cloud. I prefer using private instalation of OpenHab in my LAN, so that was not an option for me. I was searching for another solution, but only app supported by IFTTT which might be usefull form me was Telegram messenger. The only problem is, that OpenHab does not support Telegram controling by default. I google'd a little and it turned out that Telegram has a great public API with good Java support, so I decided to write a simple Spring Boot application as a bridge between Telegram Bot and OpenHab instance. You can find source code of my application on my GitHub account: https://github.com/aogorek/openhabtelegrambot In order to run it there are few steps required: 1. Create Bot in Telegram Messenger First You have to create Your own bot to communicate with. You need to contact @BotFather...

Raspberry PI and additional GPIO pins on several mcp23017 chips and a transistor switch

Some time ago I came to the conclusion that the home automation control system I made before was too complicated. I've been using a Raspberry PI + arduino + ethernet shield + additional connector board.  Arduino together with ethernet shield sometimes causes problems, especially after power outages. It has problems with restarting and requires manual restart. So this was the element I wanted to get rid of. It seems that the raspberry PI itself should definitely be enough. The only limitation is the number of GPIO pins and current efficiency. To avoid that problem I have already started designing the PCB which, when connected to raspberry, will provide us with additional pins and the ability use more power consumng devices. The easiest way to gain additional pins is to use the mcp23017 chip. It uses I2C bus to connect to the raspberry PI. Each chip will provide us with 16 additional pins. The chips can be connected together in chain, so you can have even more pins. I calculated t...