Keycloak : authenticating a Rest API written in JAVA - java

I'd like to authenticate a Rest service (RS) against a Keycloak server (KS).
RS is accessed via an application (APP) and not a browser for example.
So far, I've understood the way to proceed is as following:
APP is authenticating against KS and get an ACCESS_TOKEN.
APP is sending a request to the RS passing somehow the ACCESS_TOKEN.
RS is extracting the ACCESS_TOKEN and validate / decode it to get the required information associated with the user.
I've hard time finding the right JAVA API to perform the step (3).
So far, I've "verified" the token using a TokenVerifier (setup using the RSA public key of the KS) => TokenVerifier.verify(). Once verified, I'm parsing it to decode it using. So far so good.
One extra step I'd like to achieve is ensuring the ACCESS_TOKEN is still valid in KS. But I did not find any JAVA API for that purpose. So instead, I've issued a regular HTTP request to the UserInfo endpoint using the ACCESS_TOKEN.
So is there any JAVA API to check the validity of the ACCESS_TOKEN ?
Am I doing the thing right for this kind of scenario ?

You can either validate access token by calling the Introspection Endpoint or locally validate it by using auth0 library.
More information in keycloak docs

Related

Quarkus Rest Client with Client Credentials Access Token

My quarkus backend is calling a rest web service which requires an access token. The access token is generated using client id, client secret and grant type client credentials. The token is valid for a couple of days.
This quarkus backend then propagates the data to an angular frontend.
I have a couple of questions:
Is there an out of the box implementation from Quarkus framework?
If not, please guide me if I should use httpclient or any other library for getting the access token.
How to check for refresh token?
How to save the access token, so that it can be used for other requests by other users?
Otherwise I end up generating an access token every time a user calls the rest service.
Since there is no answer, I will write here how I implemented this:
I use a java.net.http.httpclient to call the oauth server for getting the token with the client id and secret.
I cache the token using quarkus-cache and when the token expires, the quarkus-cache is invalidated and rebuilt with the new token.
Suggestions or better solutions are welcome.

Parse ADFS token in Java

I set up login in web application with ADFS.
Authorization request looks like:
https://sso.company.net/adfs/oauth2/authorize?response_type=code&client_id=ruleman&resource=urn:ruleman:1&redirect_uri=http://ruleman.net/authorize
ADFS performs authorization and redirects to the app:
http://ruleman.net/authorize?code=aaaaaaaa.bbbbbbbbb.ccccccccc
One knows that the token from code parameter contains claims such as username etc. How to decode the token and extract the claims?
The Postman flow for this - refer Postman : Authorisation Code Grant on Server 2016 - ADFS 4.0.
This code grant is the flow you have described.
As per the other answers:
Use the authorize endpoint
Get the code
Send the code to the token endpoint
Get the JWT
Use jwt.io to examine the JWT.
The flow follows the OAuth 2.0 standard. Please note I am not expert in ADFS, however I know OAuth 2.0 well.
The authorization flow consists of multiple options with different steps. In your case you are using the code profile (specifying response_type=code). The authorization step you did is only first step, there are a few steps to follow
you can search on "OAuth 2.0 with ADFS" e.g. http://blog.scottlogic.com/2015/03/09/OAUTH2-Authentication-with-ADFS-3.0.html
Authorization request
../authorize?response_type=code&client_id=ruleman
&resource=urn:ruleman:1&redirect_uri=http://ruleman.net/authorize
you will receive an OAuth code (usually not aving any information value, it is only a code)
http://ruleman.net/authorize?code=aaaaaaaa.bbbbbbbbb.ccccccccc
code parameter contains claims such as username etc
This is wrong assumption
Using this code you need to call a token service from backend to receive an access token (e.g. using HttpClient).
POST /adfs/oauth2/token HTTP/1.1
grant_type=authorization_code&client_id=some-uid-or-
other&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2FgetAToken&code=thecode
you will receive an access token. This step ensures you application is really authenticated with the identity provider it knows.
According to the post linked above:
The interesting bit is the itself, it is in fact a JSON Web Token (JWT). That’s to say a signed representation of the user’s identity and other grants.
I am unable to confirm that, but you can try. Usually (with other identity providers) the token is only a token and the client neeeds to call a "user information" service to get any user identity claims, however seems the ADFS gives you some shortcut.
Then you can use any JWT library to decode/validate the jwt token (com.auth0/java-jwt/3.0.1)
com.auth0.jwt.interfaces.DecodedJWT jwt = com.auth0.jwt.JWT.decode(token);

Java Rest API secured by Azure AD

I've an angular app which calls a java rest api to get the data. We need to secure these apps by azure AD.
I'm using ADAL.js library for angular app and trying to find any library which can be used for rest api but haven't found any on the internet. All the samples are provided for webAPi which is using Microsoft's OWIN framework.
Currently my understanding is that, our angular app will call to Azure AD to get the access token and will send that to java rest api.
Its a JWT token signed by RSA private key.
I can get the public key from JWKs uri and validate whether the JWT token and its signature is valid or not. If it's valid, the rest api will send the response back to angular app
- Is it enough on rest api side? Don't we need any communication between Rest api and Azure AD ? What if someone steals the access token and use that (within its expiration period ?)
I was under impression that resource server ( java rest api) also needs to talk to Authorization server (Azure AD) but not sure if it's really required for JWT tokens.
#Deb,I found your reqirement matched this scenarios----Web application to Web API.I recommend you refer to this document(
https://azure.microsoft.com/en-us/documentation/articles/active-directory-authentication-scenarios/#web-application-to-web-api). If your front-end used the Angular App, you could use passportjs to pass Azure AD authorization. Please refer to documnet(
https://azure.microsoft.com/en-us/documentation/articles/active-directory-devquickstarts-webapi-nodejs/#6-install-passportjs-in-to-your-web-api).
Its a JWT token signed by RSA private key. I can get the public key
from JWKs uri and validate whether the JWT token and its signature is
valid or not. If it's valid, the rest api will send the response back
to angular app - Is it enough on rest api side? Don't we need any
communication between Rest api and Azure AD ?
If you got the access_token,you could call your REST API with this token in your request. You need not any communication between REST API and AAD. But please note, you need make your API application trust another application
What if someone steals the access token and use that (within its
expiration period ?) I was under impression that resource server (
java rest api) also needs to talk to Authorization server (Azure AD)
but not sure if it's really required for JWT tokens.
You also can set the expiration time in your application for the tokens. See the part 'Token Expiration' in this document(https://azure.microsoft.com/en-us/documentation/articles/active-directory-authentication-scenarios/#application-types-and-scenarios)

What OAuth protocol is this API using and is there a standard OAuth Library I can use to authenticate with it?

I have come across this private API that authenticates using OAuth API (Not sure what version or flavor of OAuth it is). My working knowledge of OAuth isn't that great so I need some directions to sort this out.
Here's how I was able to to test it manually using Postman/Advance Rest controller Chrome extensions and make a successful query to access a protected resource.
Step 1. Made a POST request to the OAuth Service URL with specific headers. The response includes the OAuth token
Authorization:OAuth oauth_consumer_key="<<key>>",oauth_signature_method="PLAINTEXT",oauth_signature="<<secret>>%26"
Here's an example response format. The response includes the OAuth token and the Oauth token secret (Both of which I need to use to access the protected resource in the next step)
oauth_token=<<token>>&oauth_token_secret=<<secret>>&oauth_session_handle=JN-eMMx1z_Tpy3sFrgzVsssF9Y_pyJaE&oauth_expires_in=3600&oauth_authorization_expires_in=86400
Step 2. Make a POST/GET request to the protected resource after setting the Authorization header with Key, Secret and OAuth token
Authorization:OAuth oauth_consumer_key="<consumerKey>",oauth_signature_method="PLAINTEXT",oauth_signature="<consumerSecret>%26<oauth_token_secret>",oauth_token="<oauth_token>"
Now, Here are my questions:
What version of OAuth is this API using?
Is there a standard OAuth client library that does the authentication and lets me query for protected data without me having to manually construct the POST call with headers like above, get the token (by parsing the response and extracting the token), make another POST/GET manual call with another formatted header to access the protected resource? If so how?
I tried scribe-java and extended the DefaultApi20.java but I can't get it to work. Then I wondered if I understand the API version properly. Because this private API gives me just one URL to get the token. Not sure what Authorization URL, Request Token URL & Access Token URL are in this context.
I even tried looking at the Google oauth client library for Java but I can't find an example using it that fits my context. Any help understanding this is appreciated.
You're using OAuth 1.0. The Scribe library is the way to go with Java: https://github.com/fernandezpablo85/scribe-java. In your case so-called 2-legged authorization is what it needs to do. Here's sample code for 2-legged OAuth 1.0 with Scribe: http://enrico.sartorello.org/blog/2013/08/2-legged-oauth-java-client-made-easy/

android sign in button and remote web login in PHP ZF2

I googled and I only found documents on how to create a sign in button on your android application, or how to create a sign in button on your web application.
My scenario is that the android application retrieves information from my website using get/post http requests and getting json data.
I have a working android sign in button on my android application.
the question is that when i want to retrieve information from my website using get/post request, what information should I send in order for the website to know which user is retrieving that information and that the user is logged in ?
I know that I can't just send the google user id because that's not secured and easly hacked. I'm guessing I need to send some kind of access token and on the web site to parse that access token in order to know which user it is. but what exactly do I need to do?
My client side is PHP with ZendFramework 2 and ZfcUser with scn-social-auth for google login.
any information regarding the issue would be greatly appreciated.
thanks
In my previous staff project, i've implemented our Api modules for Zend Framework (it was version 1 but it is the same for version 2).
Basically, i've implemented the OAuth protocol 1.0 ( rfc at https://www.rfc-editor.org/rfc/rfc5849 ), that is a really strong way to improve the connection security between a generic client ( Android, iOS, Mac OSX, Windows Phone ,... ) and web service.
Shortly it consits into enforce the https protocol ( i hope you are working in httpS ) signing all the client get/post requests with the base OAuth parameters ( such as oauth_version,oauth_token,... all explained in rfc) in order to avoid MITM and proxy to alter the request. Using this method i've make a specific table into which store Request and Access Tokens.
So:
Client has consumer key and consumer secret
Server has same consumer key and consumer secret
OAuth will use that keypair to authenticate the connection
Client obtain "Request Token" from server
Client perform common username and password login through OAuth workflow to the server
Client obtain Access Token ( if login with success ) that will be stored on the token db table, and wil be used to check if that user on that device is logged in and so authorized to use the service (so you'll probably need a device guid also )
You can find good guidelines and good github projects on how implement your own OAuth protocol ( see also service like Dropbox or Twitter developer sections, about how they use OAuth for their service ). Consider that you can obviously customize your OAuth protocol once implemented, with additional controls and tokens ( i've used AES-256 encryption and RSA 2048 bit for some custom tokens, and also to encrypt username and password for the login with a received key combination in the previous step expected by OAuth workflow ).
In the end, you can connect the clients to your web service with your custom tokens so, once authenticated, you make you web service to interact with google service and return information to client always through your website
Hope it helps
If the user login server is the same with the one that you want to retrieve information,you can use the sessionId as the token.
1.After authentication,server store userId in the session
2.Server use session_id() to get sessionId ,return it to android client
3.add ?PHPSESSID=sessionId param to the android client http request.
4.Server get userId from the session
session_start() creates a session or resumes the current one based on a session identifier passed via a GET or POST request, or passed via a cookie.
You can add GET parameter PHPSESSID to any requested url.
$manager = \Zend\Session\Container::getDefaultManager();
//$manager = new \Zend\Session\SessionManager();
$PHPSESSID = $manager->getId();

Categories

Resources