Java OAuth2 Provider Implementation | Custom Errors - java

I have searched high and low for the answer to this question and now I'm reaching out to the community.
I'm trying to build an OAuth2 access token endpoint in Java.
I'll be implementing the resource owner credentials grant type to return an access token. (specifying end-user's username/password to get an access token)
During authentication of the user credentials, a number of rules could prevent the user from having access to my web service, such as the user account being locked.
The OAuth2 RFC says that errors must be returned as follows:
{ "error":"invalid_request", "error_description":"description", "error_uri":"some_link" }
It's also my understanding that the OAuth spec lists standard error codes and that you should avoid custom error codes in the response, like {"error":"account_locked"}; however, I've seen some API providers do this.
I need the clients of this API to be able to read an error code in the response to know when the account is locked. (or other specific scenarios)
Now my questions are:
Does anyone here have the experience to suggest how should this scenario be implemented?
Should I implement custom error codes?
Should I forget the OAuth2 spec and just build a /token endpoint that does the same thing: authenticates the user, generates the token, and returns my API's standard error response?

I don't have an exactly same senario. But I won't use custom error codes since it violates OAuth2. Instead, I may consider using the "error_description" as the error-code field in this case; Or I can add an biz_error_code field.
Yes, you can forget OAuth2, which is not flexible in terms of http status code and error_code. But you will end up building something very similar with OAuth2's 'password' grant_type, such as an access token and a refresh token.

Related

Keycloak JWT Validation using Java Spring Security + KC Adapter

I have gone through multiple blog posts and StackOverflow questions before writing my own. I have multiple queries and none of the posts answer them.
I am using Keycloak Spring Security Adapter to secure my legacy Spring application. I referred to the keycloak documentation here and was able to have OAuth flow running for me. I am using Client Id and Secret as Client Authenticator.
For eg: Access to localhost:8080/about.htm will redirect me to keycloak login screen and after successful authentication, I will be able to view my page. I am also using the below code to read the user details from the token,
KeycloakPrincipal<KeycloakSecurityContext> kp = (KeycloakPrincipal<KeycloakSecurityContext>) auth.getPrincipal();
IDToken idToken = kp.getKeycloakSecurityContext().getIdToken();
user.setUsername(idToken.getPreferredUsername());
Now when I test this application using postman and modify the generated access token, obviously the server gives an error. Ref : How to test application using postman.
However, this is the flow :
Client sends a request to the resource server, resource server checks for a token - if it exists, the client does the validation. If it doesn’t exist or is invalid, it redirects to the authorization server (KC).
My question is,
Who is validating this token? How does postman flow throw an error
if I fiddle with the token?
Do I really need to write a JwtTokenValidator in my application for
each request? Won't that be overkill?
If I use Client Authenticator as Signed Jwt with client secret, will this validation still be required? I am not using it as it introduces latency.
Please assist.
Answer to #1:
When you use any Keycloak adapters in your application (in your case the Spring adapter for Keycloak), that's the one who does the validation and redirects to the login if necessary. As part of the validation, it checks the signature of the token issued by Keycloak. So when you fiddle with the token, the signature doesn't match, hence it throws an error.
Answer to #2
No, you shouldn't need to implement a JwtTokenValidator. The adapter does it for you and a request should reach your endpoint/URL only if it has a valid token. You may only need to do that if you have a special requirements about validating the token (e.g. checking specific claim in the token against some service). Otherwise, you can safely use the claims in the token you received from the KeycloakSecurityContext. You can even setup authorization based on your URL patterns and Keycloak will enforce them too and allow the request to pass if user has necessary roles (like this example).
Answer to #3:
That option only changes the method used to authenticate your app to the Keycloak and has nothing to do with the user's token validation inside your app. In your current setup, when your app wants to communicate with Keycloak (e.g. to exchange auth code with auth token), it authenticate itself to Keycloak with a client-id/client-secret pair (otherwise Keycloak would not know it's your app and will reject the request).
If you choose the "Signed Jwt with Client Secret" option, your client can not just use a client-secret to authenticate to Keycloak. It should support the RFC7523 specification. So it's quite complex in compare with a simple clien-secret approach. In an environment in which you trust your clients (e.g. they're all known apps developed inside the company and you're not going to support public clients to join your Keycloak and use its services) it's quite common and safe to use client-secret approach.

How to implement Oauth2 in spring boot?

I'm learning Ouath2 implementation in spring boot below way.
I want user to authorize himself first and then get a token, once get a token I want user to send that token with its REST API request to get resources.
Then resource server will verify the token and once valid will release the resource back to user request.
I know there are many examples and studies are available, but what I have observed that, most of the example are using GOOGLE, FACEBOOK etc to authenticate their user, that's not gonna help to understand my learning to develop everything manually for better understanding.
My ask is, Is anyone can share any example or references where I have control over (user authentication process + release token) and once user has token, then on resource server (validate the token with authorization server + full fill user request) I could implement token validation and return result ?
I'm want to do this authentication mechanism by myself for b. Is there any open source example is available just for learning purpose ?
All suggestions are welcome
The name of the thing your are looking for is Keycloak or Okta (these two are most popular). There are a lot of tutorials of course.

How to get Authorization (permissions) in keycloak JWT?

Objective: I am trying to add authorization details to the JWT using a custom mapper for Keycloak, so that when a user logs in using the login page, his token will also contain all the permissions that are applicable.
As an example, here's the following code (decoded from the JWT):
"authorization": {
"permissions": [
{
"scopes": [
"edit",
"buy"
],
"rsid": "af23b104-1d7e-41ab-7600-6d5bb405ad8e",
"rsname": "Custom Resource"
}
]}
To be more specific, I'm trying to obtain a similar result as if using grant_type=urn:ietf:params:oauth:grant-type:uma-ticket, but directly from the default Keycloak login page.
What I tried: I tried making a custom mapper based on this example: https://github.com/mschwartau/keycloak-custom-protocol-mapper-example
I looked in the base code of Keycloak, but there doesn't seem to be any way to include authorization data in the tokens using the default behaviour. From what I could find, the data might be in the KeycloakPrincipal, but I am not sure if this is true, because there doesn't seem to be a way to obtain that. I might be mistaken, though, since I'm not very experienced with Keycloak.
As a side note, using the grant_type=urn:ietf:params:oauth:grant-type:uma-ticket in a rest call works, but it is not an acceptable solution, unfortunately.
TLDR; This can't be done, Keycloak doesn't let's you and/or doesn't have a mechanism implemented for this.
This can't be done as the token containing the permissions ie RPT token, is actually provisioned by Keycloak with invoking the authorization endpoints, and that in turn requires a user access token in the first place.
This is how it's currently done and implemented - so what you can actually do is, implement on your client app a mechanism for fetching that RPT upon login. You'll have to make two requests to Keycloak, one obtaining the JWT and the other one obtaining the RPT.
But all in all, this isn't encouraged, as the general idea is not to return all permissions when a user logs in, but to actually require allowed scoped and permissions for specific resources - for a specific user.
All this is documented on Keycloak Authorization
It's a bit vague I agree, so hopefully, you'll perhaps find some more useful info here
Obtain RPT without having to invoke Keycloak API twice
Please note again
you aren't supposed to require permissions for all available resources, for a user, but to request one by one and possibly extend your RPT. E.g. You would send a request per each required resource.
If for any technical reason, you cannot do it like this and you still want to require all permissions at once - the best yo can achieve, as already said, is getting the RPT token once a user logs in (obtains a JWT token). But this is still (minimum) two requests to Keycloak
In theory you could extend Keycloak in such a way, it returns permissions in the JWT right away, but this wasn't done by anyone so far as it would require a lot of work and keycloak tweaking, and would still be in question whether it's possible to do so.

REST API Allow access to a URL only for the Owner of the Resource

I am currently designing a REST API for a social networking application.
I am trying to decide how I can go about locking access to a specific resource for each user. For example I have the following URL's
https://social-network.com/api/user?id=2/someUpdateOrPostOp
(or https://social-network.com/api/user/id=2/someUpdateOrPostOp)
https://social-network.com/api/user?id=3/someUpdateOrPostOp
What I need of course is for a user with id=2 not to be able to change their id to 3 in the url and perfom an operation on the data of user with id 3.
Note: I am using JAX-RS with Tomcat and the Client consuming the API is an Android device.
What is the technique I need to research to achieve this? I feel like I am missing something with all this.
Thanks for any help you can offer, this is confusing me greatly!
You need two things:
logic that confirms the identity of the caller i.e. you know the caller is Alice. That can happen through OAuth, Open ID Connect or other protocols. You could use more basic authentication e.g. HTTP BASIC Auth but that leads to the password anti-pattern whereby you share your password with the API.
logic that given the user, determines what that user can do. This is referred to as authorization or access control. Given you are in JAX-RS, you could use a message interceptor to look at the user ID and then look at the requested object or the parameters of the call and then decide to deny access if the authenticated user doesn't correspond to the requested profile. You could even use externalized authorization with XACML. Given your simple use case, though, that would be too much.
You can read more on JAX-RS interceptors here.

grant_type in Spring-Security-OAuth2

I am new to OAuth2 concept.I ahve to implement this in my application. This application provides REST APIs. I follwed some tutorial ,done some research and kind of implemented it in working state in my application.
But while doing some search I read about different type of grant_type in OAuth2. I tried to learn about that but didn't get actual differences and which should I use for securing REST APIs.
So I want to know that for grant_type types "password","client_credential"etc which should be used and in which scenario, or which should be used for securing REST APIs?
Also at some places I found that the request for /oauth/token is different.
Some places the Authorization header is given as Basic 'some_encoded_string' .
And at some place it is Bearer 'some_encoded_string'. Whats the difference in these request?
Summarizing this I have 2 question -
For grant_type types "password","client_credential"etc which should be used and in which scenario, or which should be used for securing REST APIs?
What is the difference in ways of requesting token from /oauth/token .
Enlight my knowledge in implementing spring-security-oauth2.
The grant you need to use depends on your use case and the nature of the client application accessing your resources. There isn't a grant that applies a REST APIresource in general. You'd need to provide more information on what the APIs are and how you interact with them.
If a user has to give their permissions for a client to access an API, then you would normally use an "authorization code" grant. If the client accesses the resource directly without the intervention of an end user then it would normally use the "client credentials" grant.
You should avoid using the password grant in most cases, since it means the user has to provide their username and password to the client application. If the application can use another grant, such as authorization code, then that is preferable. A trusted application, such as a native application which the user installs on their computer, would be one situation where the password grant might be used.
A client would normally use "Basic" authentication to access the token endpoint. "Bearer" authentication is use to access a protected resource (such as your API), passing the access token it obtained from the authorization server.
Why do you think you need to use OAuth2 at all? I'm curious since you say you don't understand what the grant types are for. You really need to understand this before you can make a judgement about how you would use OAuth2 or why.

Categories

Resources