I need an OAUTH2 authentication server for my single page webapps. I was able to build OAuth2 authentication server that supports grant type PASSWORD using Spring Boot. But Spring requires a client secret for basic authentication on the /auth/token endpoint. I red it's not safe, anyone could extract the client secret from the JS code. So I'm trying to find out how to do it without revealing the client secret. Also I wish each my SPA don't have it's own login page but there's one login page within the auth server to which users of my SPAs would be redirected and they would be redirected back after login. I know this is common scenario but I was unable to find a tutorial how to do that using Spring Boot. I'll be thankful for an advice.
For a public client like a web application, you can put an empty password in your basic authentication header. For example if the mobile app client_id is abcd
(use a long random string in production), then you can use abcd:
encoded in Base64. The header will be Authorization: Basic YWJjZDo=
where YWJjZDo=
-> Base64("abcd:").
In fact, you could put anything as a basic auth password, the authorization server won't check it if you don't assign a client_secret
to your client.
You should use the password grant only for your own applications (never give your partners the right to collect your own users' credentials) and when the implicit grant does not offer a good enough user experience for you -- for example if you don't want your mobile app to switch back and forth from native UI to browser.
Single page web apps are the perfect use case for the implicit grant.
In your authorization server, make sure your web application Client details have an authorized_grant_type
that contain implicit
, and a redirect_uri
equal to the endpoint that will receive the token at the end of the process. In a single page app, you should have some handler that can pick up the access token in the URL when the authorization server redirects the user back to your page.
From your web page, you have to redirect users to https://your-authz-server/oauth/authorize?response_type=token&client_id=$CLIENT_ID_YOU_JUST_CONFIGURED&redirect_uri=$YOUR_APPLICATION_PAGE
.
Once the user has granted access to your app, he is sent back to your redirect URI with an access_token
parameter that you can pick up in the URL.
Note : In production you should always set fixed redirect_uri
s (you can have many separated by commas) for clients that use the implicit
or authorization_code
grant. For the implicit
grant, that's your only way to make it harder on attackers to obtain tokens from your users.
If you don't want your own users to see the list of scopes (permissions) that your own site requires, you can set up your client to have pre-validated scopes. That way your user can log in and get redirected straight to your app page with a token, without having to see the OAuth 2.0 plumbering.
Note that the authorization server provides default login pages, but you can customize them with a classic Spring MVC @Controller
mapped on /oauth/authorize
, and implement the view using the template engine you like (thymeleaf, velocity, jsp...). You can also customize the login page with classic Spring Security, make sure you only handle requests on the /oauth/authorize
path.
Check out this excellent tutorial by the developer of Spring Security OAuth 2.0 : https://spring.io/guides/tutorials/spring-security-and-angular-js/
And the long version here with explanations : https://spring.io/blog/2015/01/12/spring-and-angular-js-a-secure-single-page-application