How one can use other oauth2 providers like FB, Google in an existing jwt authentication system - spring-boot

I am new to spring boot and trying to implement oauth2 client with facebook as oauth2 provider.
I already have a traditional JWT token authentication in place which is configured with in #EnableWebSecurity with default authentication manager and custome JWT token generator.
is it really required to configure AuthorizationServer and
ResourceServer in above scenario?
if not then why my code always returns me only Code and state from facebook to call back URL.
Please have a look into the code here

Oauth2 = Authorization delegation protocol NOT an authentication one.
If you want to use FaceBook and Google as identity provider then you must go with an identity federation protocol, ie OpenId Connect (OIDC).
This last add an authentication layer (using JWT id token) above oauth2 authorization layer.
Regarding more specifically your question (which is not very clear) about the spring security configuration part , it seems that the current oauth2 server implementation (AuthorizationServer and ResourceServer you're talking about are part of it) is not suitable as it is to implement an OIDC identity provider)
Regarding the code and state returned to the callback URL, it's part of the oauth2 authorization code flow and it's perfectly normal, you then have to exchange the retrieved code against an access token using the authorization server token endpoint.
(state is just here to allow to transmit an information for example a tenant id, across the oauth2 whole flow).
Here is really well written oauth2 vulgarization article.

Related

Use OAuth2 for authorization of session-authenticated users

I'm developing a microservices application that has to authenticate users against an external Identity Provider using SAML2 protocol.
The architecture
The idea is to use a SPA running in the browser which only talks to the API Gateway and uses Cookies for authentication.
The gateway delegates the Authorization Server to check if each request is authenticated and initialize the SAML2 login if not.
Once the user authenticates, the Authorization server initializes a session and sends back the cookie straight to the browser.
The Authorization Server is actually an OAuth2 Auth Server as well as a SAML2 Service Provider.
For every request coming after the user authenticated, I want internal communications to use OAuth2.
Frameworks used
For the authorization server I'm using the Spring Authorization Server package as well as SAML2 Service Provider libraries of Spring Security.
Resource services would use Spring Boot OAuth2 Server library.
What's working
I managed to set up the SAML2 client so that the Authorization Server is already generating a Session for the user after IdP authentication and I'm capable of reading the authenticated principal.
The problem
For the upcoming requests I want the API Gateway to perform a token replacement by exchanging the Cookie for an OAuth2 access token before forwarding these requests to resource services. Each resource service will then validate these tokens against the authorization server.
What I'm trying to achieve here is to make the API Gateway as a Backend-for-Frontend but the I'm struggling to figure out which authorization flow to use given that:
the client is the API Gateway, so it can be considered confidential
user credentials are missing as they are provided to an external IdP and the principal comes from a SAML Response
the authorization server has already estabilished a session for the user
Basically I can't figure out how to exchange the JSessionID for an authorization code.
Any ideas?
You should not bother about the authentication-code, the BFF (gateway configured as OAuth2 client) should receive it and exchange it for tokens (access, ID and refresh) during login process and store those in session (which should be activated along with CSRF protection).
When requests land on the gateway, session is replaced with Bearer access-token (kept in session) before being forwarded to resource-server. This behavior is activated with the tokenRelay filter in route properties (if I remember well...)

Spring Cloud - Micoservice Authentication propagation

I am building an application using microservice architecture. I am using Eureka for service discovery with Spring Cloud Gateway for request routing. For authentication mechanism I am issuing JWT tokens (in auth service). What is the best practice when it comes to propagating Authentication so I can get logged user information in each service which is after the gateway?
So far I've came up/found couple of possible solutions:
In gateway add headers for relevant user information, and in each service create filter which would take said headers and create Authentication object and store it into SecurityContextHolder. The downside of this approach is I can't just plug and play services outside my application.
Pass the token coming from the client through the gateway to the each service, where I would have JWTFilter which would validate token and extract the user information. Downside I see with this approach is I have to have jwt secret shared between each service or stored on each service, and I would have to implement JWT logic, producing duplicate code.
Final solution is having something like oAuth token introspection endpoint in auth service which would be called from each service (filter) once the request reaches it.
I implemented the filter logic for validating the user token in the gateway service, but I would like to use role based authorization on each endpoint (service) differently (ie. user service has endpoint for creating users (ADMIN), and for fetching user information (ANY ROLE)).
I opted for something like your option 2 and use spring-boot to configure JWT decoder from an OIDC authorization-server (Keycloak).
Configuring OpenID resource-servers is super easy (more options in parent folder), and authorization-server JWT public signing key is retrieved automatically by spring JWT decoder.
All that is required is ensuring that Authorization header with JWT bearer is correctly propagated between services.

custom oidc in keycloak

I have a spring based application which does authentication and authorization(oauth2 based) for a client app.I want to now use keycloak to manage my authorizations, but i want to keep my spring code. Basically i want to use my existing auth code as an external identity provider in keycloak.
I am thinking of adding changes in client app such that it receives token from my existing oauth code(which does the authentication) and then exchange this token with keycloak(for session and authorization management). How can i do this? What configurations need to be done in keycloak?
I read about token exchange in keycloak here, but i am not clear about the kind of token i need to send from my existing auth code.
https://www.keycloak.org/docs/latest/securing_apps/
Here is how OAuth2 roles are usually spread:
Keycloak is authorization-server
Spring service is resource-server
front-end is client
user is resource-owner
I have a doubt of you wanting your Spring service to be "authorization-server" as well (serve user identity). If so, I think you should not.
Keycloak (or any other OpenID provider) should be the only authorization-server. Both Spring and client(s) should be configured to use it as so.
To write it differently, Keycloak is responsible for users login and emitting tokens with user ID (subject) and rights (roles or whatever). Other tiers in the architecture (clients & resource servers) get user info from the token and apply relevant security checks (spring security annotations, Angular guards, etc.).
I published a mono-repo for a meetup with minimal sample involving a Spring resource-server and Angular (with Ionic) client talking to a Keycloak OpenID authorization-server. You might find some inspiration browsing it.

Authorization Server Endpoints

As we know the Spring Security OAuth 2.0 project has bee depreciated and now it's Spring Security 5.
My question is related with Authorisation Server for grant_type: authorization_code. Spring team is also working on standalone project for Authorization Server. So most of the codebase in Spring Security project is depreciated for Authorization Server.
Still, I've couple of questions for endpoints with authorization_code flow in Spring Security 2.0/5.
OAuth 2.0:
Can you please let me know, which endpoints are supported for below use cases in Authorization Flow:
Login Button: ask the customised authorization url from Authorization Server.
User logged-in: once end-user logged-in (authenticate), need to authorise with registered client application and provide the code in the callback URI.
Request For Access Token: once the code has been received in previous step, it should use the code to get the access token.
Please let me know which endpoints are meant to be used in Spring Security OAuth 2.0/5 for above use cases. Based on my research, I've found these endpoints:
/oauth/token: get the access token
/oauth/token_key: produces JWT encoded token values
/oauth/check_token: validate the access token
Can you please let me know which endpoint dedicated for authorisation before end-user authenticate in use case #1. And after end-user authentication in use case #2.
Any help would be appreciated.
Many Thanks,
Adnan

ASP.NET Web API 2.2 OWIN with mixed authentication JWT and SAML

We have a WebAPI that needs to service different client apps, each one using different authentication mechanisms. One web app client will authenticate using SAML and then pass a SAML based token to the WebAPI. Another one will be using an OpenID Connect token for authentication.
We need to be able to digest both types of tokens in our WebAPI, validate them and authenticate them. Could anyone shed some light on how this could possibly be achieved? Any advice would be much appreciated.
What IDP are you using?
Some IDP e.g. ADFS can be configured to pass JWT tokens on a SAML connection.
SAML wasn't really meant for web API. You could e.g. authenticate using SAML / OIDC and then use the client credential flow to the web API which simply relies on a secret key. That would not have user context though.

Resources