Reputation: 27
I'm having a hard time figuring a good way to implement Oauth 2.0 and OpenID Connect authentication alongside an existing internal email+password authentication for a B2B Web app's API using Spring security.
We have a backend REST API that is a Spring Boot servlet application which currently authenticates users with OAuth 1.0 and the password
grant. The front-end is an Angular single-page app through which users must log in with their username and password. The API's /oauth/token
endpoint then delivers an opaque access token to be used for fetching secured resources that are then displayed within the app.
We'd like to add the possibility to log in using external authentication with OpenID connect, which is a perfect opportunity for switching to OAuth 2.0 and JWT tokens. Our API would then accept JWT tokens it delivered as well as external JWT tokens emitted by accepted issuers. Reading and validating JWT tokens won't be a problem using Spring security's OAuth Resource Server. However things get complicated with how to make the classic username+password login flow work with JWT tokens.
We thought about delivering JWT access tokens the same way we used to with our old OAuth 1.0 tokens. The thing is, newer OAuth specifications advise against using the password
grant, plus it simply isn't supported in the Spring authorization server project we're planning to use. The authorization-code flow w/ PKCE seems like too much for this case as we do not want the back-end API to render a login form but use credentials entered in the existing login form that is part of the single-page app.
I've read a lot about not using OAuth for 1st party login since its primary use is for external authentication, but again, that doesn't apply since we also want 3rd party authentication.
What would be a secure way to implement a Spring boot authorization server that can deliver JWT access tokens to a 1st party client in exchange for a user's credentials, all this using the existing log in page, and given the password
grant type no longer being supported?
I thought about implementing a preliminary step that would be a POST request with Basic authentication to a /login
endpoint that just returns a 200 HTTP status, then proceeding to the /oauth2/authorize
request that would deliver the authorization code immediately without redirecting since my session is authenticated.
I'll be happy to provide more details if needed. Here are the resources I'm using for this project.
Upvotes: 0
Views: 386
Reputation: 12835
What about setting up an authorization-server capable of identity federation?
In such configuration, the authorization-server is responsible for providing with identities, proxying one or more sources (your existing user database for instance, plus maybe Google, Facebook, Github, etc.)
Keycloak does it for instance.
From the client point of view (your Angular app), the authorization-server is used to get:
Authorization
header of requests to secured resource-server(s) (can be a JWT or an opaque string, doesn't matter, clients should not try to extract data from access-tokens)You should have a look at https://github.com/damienbod/angular-auth-oidc-client for connecting an Angular app to an OIDC authorization-server.
From resource-server point of view, access-tokens are the source ofr setting-up security-context, either by decoding and validating a JWT locally or with token introspection on authorization-server.
Have a look at those tutorials for such resource-servers configuration.
Upvotes: 1