Separating OAuth2 Authorization Server and Resource Server - spring-boot

I implementing OAuth2 Authorization Server and Resource Server.
and there are many documents told me
'Authorization Server and Resource Server can be Separated or not'
i like MSA, so i decided Separating these Servers.
i saw many documents in Internet about this issue, but i cant proceed anymore in practice.
i'm using SpringBoot2.
Scenario
User Connected to My Client Application.
Request to secured endpoint /client/me
in Client's Controller, if user has not authenticated, redirect to Authorization Server's login endpoint /auth/oauth/authorize.
if user comes in my Client App first, user will sign-up(not sign-in) in my Authorization Server.
in Authorization Server's sign-up page, user will input his username, realusername, password and email.
user's account has issued, and user will sign-in via my Authorization Server's login form.
if login succeed, Client will Request to Resource Server's /me endpoint with access-token, and Resource Server's Controller that mapped as /me will return Principal or Authentication Object as REST API.
Client will bind there REST API's results into DefaultOAuth2User
or CustomOAuth2User in my SecurityContext.
here is question.
As far as I know, Resource Server's /me endpoint will provide user's resources.
for example, realname or email etc.
but user has signed-up in Authorization Server, so all of information are saved in Authorization Server's Database.
my oauth2 servers are MSA. so DB has been separated too.
then, how can i setting email or realname to Principal or Authentication or CustomOAuth2User Object via Resource Server's /me endpoint?

Authorization Server is responsible for authenticating users or clients (other applications), checking if they are authorized to do what they want to do and on success, it issues a token. This means that a database it connects to should have all users credentials, clients IDs, clients secrets, roles, and other relevant information that helps in authentication and authorization.
Resource Server is responsible for handling all requests that came from frontend, be it authenticated requests or requests that are open (doesn't require authentication). Database it connects to should have information that is not relevant for authentication, like user's gender, height, weight, hobbies, etc.
To answer your question, you can create controllers in Resource Server that exposes registration, and other functionalities. This server will then make calls to Authorization Server. For registration, Resource Server will pass credentials to Auth Server to see if username is already claimed and if not register the user and based on the response of Auth Server, Resource Server will proceed with user registration. For login, frontend can make call to Auth Server directly to get token.
For all subsequent calls to protected resources (with access token) Resource Server would need to call Auth Server to verify tokens. For this Spring provides CheckTokenEndpoint (/oauth/check_token).
You can also check OAuth2RestTemplate. This can be used in Resource Server for making REST requests to Auth Server. Note that Resource Server (or any other internal application that you have like frontend) will be clients for Auth Server. They would also need to authenticate and authorize themselves.

Related

Should OAuth2 resource servers use Basic or Bearer token auth when communicating with the authorization server?

Given separate spring-security-oauth2 authorization and resource servers:
I expected the authorization server's /oauth/check_token endpoint to accept a Bearer token from a resource server in the Authorization header but it only accepts Basic auth. Note: I'm referring to the request auth token, not the token to be checked.
I think OAuth2AuthenticationProcessingFilter is responsible for extracting and validating Authorization: Bearer ..., but based on the javadoc it appears to be used only by resource servers to validate requests from users or other clients.
Should resource servers always provide Basic auth when communicating with the authorization server? What's the best practice? If Bearer tokens are acceptable, does the authorization server need to be configured as a resource server via #EnableResourceServer in order to get this functionality?
Note from the Javadoc for CheckTokenEndpoint:
Controller which decodes access tokens for clients who are not able to do so (or where opaque token values are used).
Since the client authenticates with the authorization server with Basic auth to grant access, it makes sense for the /oauth/check_token endpoint to require Basic auth as well.
Usually, the tokens the resource server receives are self-encoding (or backed by a token store), so it doesn't need to check the token by directly communicating with the authorization server anyway. Communication between the resource server and authorization server is not necessary.
If it does need to interact with the authorization server, it might be to obtain its public key if you're using JWTs. But there would be no real use in securing this endpoint, since it's a public key for a reason. Again, this would happen when the resource server starts up, and certainly not for every token it receives.

Which information gets sent in each API request using OIDC

I'm writing an API back-end that I want to use OpenID Connect (OIDC) to secure. I've been reading the documentation but I'm still a bit confused what process applies to each and every API request. The Open ID Connect code flow appears to be:
Which I'm fine with, as a one-time process. My back-end API sees an authorization code in the HTTP headers, and sends a request to the authorization server to get the id token. Assuming this validates OK, the data requested is returned in the API response.
But assuming the same user will then be making lots of requests to this API, what happens in subsequent requests? Is there some sort of session created in this mechanism? Do I continue to receive the same authorization code? Do I have to keep sending these back channel requests to the authorization server?
Or should I even output the JWT id token as a cookie? In this way I get the self contained id token coming back in future requests, with no need of a server side session, or further round trips.
I've been reading the documentation but I'm still a bit confused what
process applies to each and every API request
It is not the API that should follow OpenID connect protocol. It's the client that should do it.
My back-end API sees an authorization code in the HTTP headers, and
sends a request to the authorization server to get the id token.
Assuming this validates OK, the data requested is returned in the API
response.
Authorization code must be used by client application and not by the API endpoint. Also, authorization code must never be exposed to other entities.
You should use id token sent with OpenID Connect to authenticate the end user from your client application. To access API, you should use access tokens.
What to do in API endpoint ?
I think this is where you struggle. Your client application should send a valid access token to get access to API endpoint. From API endpoint, you can use OAuth 2.0 introspection endpoint to validate the tokens.
RFC7662 - OAuth 2.0 Token Introspection
This specification defines a protocol that allows authorized
protected resources to query the authorization server to determine
the set of metadata for a given token that was presented to them by
an OAuth 2.0 client.
Note that, OpenID Connect is built on top of OAuth 2.0. This means you can use anything defined in OAuth 2.0, including introspection endpoint. Use this endpoint to verify the access token validity.
What if you want end user details ?
OpenID Connect defines a user info endpoint
User info endpoint
The UserInfo Endpoint is an OAuth 2.0 Protected Resource that returns Claims about the authenticated End-User. To obtain the requested Claims about the End-User, the Client makes a request to the UserInfo Endpoint using an Access Token obtained through OpenID Connect Authentication. These Claims are normally represented by a JSON object that contains a collection of name and value pairs for the Claims.
Here also, you use access tokens to get user information from this endpoint. The response will let you know the end user to which this token was issued.
Depending on your specific API requirement, you can do a token introspection or obtain user information from user info endpoint. Once that is done you may go ahead and authenticate a session. You might use both endpoints if you need all available information.
Alternatively(instead of sessions) your API can maintain an access token cache. This will remove the need to validate tokens in each an every API call. But be aware that tokens have expiration time. You must consider about token expiration if you are choosing this solution.
p.s - Client vs Resource server
In OpenID Connect and OAuth 2.0 terms, a client could be a simple web page, desktop application or could be even server hosted application.
client
An application making protected resource requests on behalf of the
resource owner and with its authorization. The term "client" does
not imply any particular implementation characteristics (e.g.,
whether the application executes on a server, a desktop, or other
devices).
Obtaining tokens and using them is the duty of the client application.
On the other hand, resource server contains protected resources,
resource server
The server hosting the protected resources, capable of accepting
and responding to protected resource requests using access tokens.
Resource server exchange it's resources to access tokens. If we match the same scenario to basic authentication, access tokens replaces username/password sent with authentication headers.
Typically you'd secure a (pure) API with OAuth 2.0, not OpenID Connect. The Client accessing your API should obtain an OAuth 2.0 access token and in order to do that it may choose to use OpenID Connect to obtain that token. That is all independent of the API, which will only see the access token. The API (or Resource Server in OAuth 2.0 terminology) is not depicted in your diagram.

OAuth2 Provider with custom authentication

I am trying to implement a OAuth2 Provider, that authenticates users with a custom login.
For understanding I looked at the Spring Boot OAuth2 Tutorial.
I don't quite get, how I can implement my own Authentication meachnism to work with the OAuth2 SSO from my Server.
I want to add custom authentication mechanisms (like "user has to answer a question for authentication" or "user has to enter id and click button for authentication") instead of the Facebook and Github examples.
I read about implementing my own AuthenticationProvider, but I am stuck how to combine all the puzzle parts.
Let's go one step at a time. OAuth is only authz provider so not talk about authentication. Now for your usecase specifically, if you want user to be authenticated then OAuth authz code based flow makes sense (You can even go for implicit flow, check rfc 6749). Now how will this work for you. I am picking up the implicit flow for simplicity, Authz flow is just extension of it where end client gets a temporary code which it exchanges with Identity Server later to get the access token. Here are the steps:
Client App hits the /authorization uri with data as per rfc 6749
After validating the submitted data, server forwards user to Login page (or other page for authentication). After authentication, cookie is set in the browser or data is stored in server to mark a user as authenticated.
After authentication server redirects user to user consent page (You can even skip this if needed depending on need, But OAuth 2 spec contains this) where user specifies which all permissions (scopes) are allowed, here user can allow either allow or deny.
if user allows then these permissions are submitted to server and then server stores the data and redirects the user to client URI with access token in # fragement of client redirect URI (callback URI submitted during actual request)

How do /oauth/authorize and /oauth/token interact in Spring OAuth?

I am doing an in-depth study of Spring OAuth, and I found some conflicting information.
Specifically, this tutorial states that the /oauth/token endpoint handles the username and password before granting a refresh token to the client app. By contrast, the Spring OAuth Developer Guide mentions the /oauth/authorize and /oauth/token endpoints, but yet does not get specific about how they work.
Does the /oauth/authorize do 100% of the username/password/nOtherFactors check and then signal the /oauth/token endpoint to send a refresh token to the client, so that the client then sends the refresh token to the /oauth/token endpoint?
Or is all of it handled by the /oauth/token endpoint?
Is the relationship between /oauth/authorize and /oauth/token different for different grant types? How?
Per the OAuth 2.0 specification the authorize and token endpoints have different purposes.
Authorization endpoint is where the resource owner (user) logs in and grants authorization to the client (ex: web application running in the browser or an app running on a mobile device). This is typically used in scenarios where the resource owner's user agent (ex: browser) is redirected to the identity server (authorization server) for authentication. The resource owner's user agent will have direct access to the access token.
Token endpoint is where the client (ex: Server side API or mobile app) calls to exchange the Authorization Code, Client Id and Client Secret for an access token. In this scenario, the user agent is provided with an Authorization code only, no direct access to the access token. The client is a trusted party with access to client Id and Client secret from the authorization server (That is why I mentioned Server side API as the client).
Please read this article that has even better explanation.

How does OAuth handle authorization?

We have implemented a RESTful API using RestEasy. Now we are planning to build our own OAuth implementation and will integrate it with our Rest API.
I do not fully understand how OAuth handles authorization of every request to the API. My understanding is as follows:
User is authenticated by the OAuth server before any REST API calls are made.
Every REST API call will contain a token. The REST API server validates this token with the OAuth server. If the token is valid then the server will return a response.
This should have an impact on performance as we are validating the token for each and every API request with the second server. Is this understanding correct?
This will depend on how you will define your REST API. Basically OAUTH call has following components.
User: Who makes a request.
Provider: Who holds user information and provide apis to access them.
Consumer: Who asks the user to authorize the consumer to make request to the apis.
The basic workflow is as follows,
User tries to access restricted resource from Consumer.
Consumer asks user to share some information about him.(scope)
User selects his identity provider.
Consumer should be known to the Provider.(Usually consumer register itself as an application/website in provider's portal)
Consumer redirects to the provider with his consumer_key and scopes.
User authorize the application and grants access to some of his resource.
Provider creates a token and redirects back to consumer.
Consumer exchanges this token and its identity to get a access_token for user.
Consumer uses the access_token to make authorize request to provider and asks few information about user.
Provider sends those information to consumer.
Consumer verifies the information and user is logged into the system.
Now each token is generated against the scope and will be valid for some days. Token validation will be part of response from Provider.
In your system, you can store user data against token, so that we need not request Provider to send those information. But if you dont want to store user information certainly there will be additional calls.

Resources