JAX-RS Jersey servlet JJWT - jax-rs

I have a couple of days following a few issues but I can not find the solution .
I have followed these issues: Custom JAX-RS authorization - using JWT in each request and
Best practice for REST token-based authentication with JAX-RS and Jersey
but I do not understand how to use filters.
I need to create a token for a android app Use the resources of my web service.
I can not just create a token and send it ?
I 'm using jjwt https://github.com/jwtk/jjwt but I think it right, a piece of code:
#POST
#Produces("application/json")
#Consumes("application/x-www-form-urlencoded")
public Response authenticateUser(#FormParam("username") String username,
#FormParam("password") String password) {
try {
// Authenticate the user using the credentials provided
// authenticate(username, password);
// Issue a token for the user
String compactJws = Jwts.builder().setSubject(username).signWith(SignatureAlgorithm.HS512, "pepe").compact();
// Return the token on the response
return Response.ok(compactJws).build();
} catch (Exception e) {
return Response.status(Response.Status.UNAUTHORIZED).build();
}
}
If anyone can help me , thanks ...
Si alguno me puede responder en castellano, mejor.
PD: Sorry if I asked the question wrong, I'm new in stackover... and sorry for my English

I am the author of the answer about token-based authentication in JAX-RS. This authentication method can be summarized in the following steps:
Exchanging hard credentials for a token
No filters are required to do it. You should have an endpoint (a JAX-RS resource method) to perform the authentication using hard credentials (like username and password). If the credentials are valid, the endpoint is going to issue a token that will be sent to the client in the response payload. The client must sent this token in the Authorization header of each request.
The endpoint that issues the tokens must not be protected, that is, no authentication must the required to access it. Once you have an Android application as client, I think you will find better consuming application/json instead of application/x-www-form-urlencoded. My answer provides details on how to do it.
Validating the token
Here the authentication filter comes into play. When using filters to validate the tokens, you can keep your endpoints lean and business focused.
The idea behind the filter is to intercept the requests to protected resources, extract the token from the Authorization header and validate it. If the token is valid, the request will proceed to the requested endpoint. If the token is invalid, the request will be aborted.
Besides the authentication filter, you can have other filters to perform authorization, for example. In the authentication filter, you must check if the token is valid and then find the user you issued the token for. In the authorization filter, you must ensure the user has enough permissions to access the requested resource. Other filters can be created according to your needs.

The code you have provided is valid to a issue a new token for a web application (uses application/x-www-form-urlencoded), but for android application It would probably be more appropriate send credentials as a json POST or in a Authorization header
After this, the client application receives the token, stores it and needs to include the JWT in every request to server. You can include the token in headers or in a request param. The server must validate the token signature, and other fields like sub (the userId) and exp (expiration time).
Using a filter, like the AuthenticationFilter provided in the example, simplifies the authentication process. It can intercept all the requests and perform the validation in a unique point. If not, you would have to validate the JWT in each method of your bussiness logic
If you have doubts about how to configure the filters I suggest to post in SO an specific question

Related

OAuth 2.0 token introspection questions

I'm trying to understand token introspection as I need to implement token introspection for OAuth 2.0. But authentication is so hard to understand... :-( So I've got a couple of questions:
(1) As far as I understand, a post-request (with the access token) is sent to the IP. This then returns whether the access token is valid or not, as well as further information such as the user name.
This looks like the official spec to me: https://www.rfc-editor.org/rfc/rfc7662 it says a post request is needed to validate the access token. Did I understand that correctly
(2) This looks like the corresponding dependency, is it? using using IdentityModel.AspNetCore.OAuth2Introspection
Whats the difference between Microsoft.AspNetCore.Authentication.JwtBearer?
(3) According to the spec only the access token is requied (https://www.rfc-editor.org/rfc/rfc7662#section-2.1)
This example does not pass it but the clientid and the clientsecret:
https://github.com/IdentityModel/IdentityModel.AspNetCore.OAuth2Introspection
services.AddAuthentication(OAuth2IntrospectionDefaults.AuthenticationScheme)
.AddOAuth2Introspection(options =>
{
options.Authority = "https://base_address_of_token_service";
options.ClientId = "client_id_for_introspection_endpoint";
options.ClientSecret = "client_secret_for_introspection_endpoint";
});
Why not?
(4) If I set the config right, .Net Core will do the post-request (for every incoming request to my api) for me automatically, right? (I also added the [Authorize]-Attribute)
(5) How can I get the user context?
(6) I implemented a small example but get a 500. I do not see any error output. How can I log the errors?
The following are some of my understanding and opinions:
(1) The token introspection endpoint needs to be able to return information about a token, so you will most likely build it in the same place that the token endpoint lives. The request will be a POST request containing just a parameter named "token".
(2) JWTs are typically validated locally on the resource server.
It's a technical detail that IdentityServer can also validate JWTs at the introspection endpoint. That could be used e.g. when the resource server does not have an appropriate JWT library (and you don't want to store reference tokens on the IS side).
(3) In my opinion, this appears to be a configuration requesting an access token. Access tokens are the thing that applications use to make API requests on behalf of a user. The access token represents the authorization of a specific application to access specific parts of a user’s data. The Client Credentials grant is used when applications request an access token to access their own resources, not on behalf of a user. Please check this link: Access Tokens.
(4) If you add the [Authorize] attribute to the method that requires authorization, if the configuration is correct, the .Net Core App will automatically request authorization from the authorization server with your information.
(5) Do you want to access end user context on resource server? Maybe this link can help you.
(6) For logging error messages, please refer to this link: How do I log authorization attempts in .net core.
Hope this can help you.

Getting refresh_token server-side (sessionToken) with Okta

We wish to use our own httponly strict cookie with access and refresh token in it for our microservices architectures.
We are primary using OKTA Authentication API to log users with our own custom Sign-in page.
We were able to get the access_token on the authorize endpoint using the responsetype=token with sessionToken and redirecting the result as a form_post on our back-end endpoint.
I was unable to retrieve the refresh_token despite adding the offline_access in the scope even if it is checked in my okta application setting.
I don’t want to use resource password flow since we prefer using sessionToken which will work with multi factor if needed in the future.
I also try using the code flow and redirecting the result on our back-end but since the code flow is client-side it’s return this error "PKCE code verifier is required when the token endpoint authentication method is ‘NONE’." This error occur even if we choose a .NET application
How can we retrieve the refresh_token server-side with Okta?
Responded to your post here https://devforum.okta.com/t/getting-refresh-token-server-side-sessiontoken/12419/3.
Aside from making a call directly to /token with your access token you can also check our Early Access feature called Refresh Token Rotation. Let us know if this helps!
I was able to use the CODE flow and redirect from server-side to the authorized endpoint like so:
https://{YOUROKTADOMAIN}/oauth2/default/v1/authorize?client_id={YOURCLIENTID}&response_type=code&scope=openid%20offline_access&response_mode=query&redirect_uri={YOURSERVERSIDEGETURI}&state={Guid.NewGuid()}&sessionToken={SessionToken From Auth API}
This call will post back to my same server, so i can handle token myself and create my own cookie.

Can back end server applications utilize the userinfo endpoint to retrive end-user claims in OpenID Connect?

I have 3 applications,
Client Application(RP)
OpenID Provider(OP)
Mediation Server(MS)
The client Application can authenticate and retrive id_token and authorization token, The authorization token is then used by RP to call OP by passing it in the header. This request will then be forwarded to the Mediation Server(MS) by OP. The MS requires acess to end-user information. Simply passing them as query params or in request body is not an option.But the authorization token sent by the RP can still be accessed by the MS. Is it wrong to use OP's userinfo endpoint by MS to retrive user claims, since openID Connect docs only mention userinfo endpoint to be used by Client Applications(RP)?
Simple answer is yes, it is a valid use case.
User info endpoint is OAuth 2.0 token protected endpoint defined by OpenID Connect. It more or less behaves similar to token introspection endpoint defined by OAuth 2.0 (OAuth 2.0 Token Introspection) providing token holder the ability to obtain authenticated end user information.
From your application perspective, you have two parts of the client. One the end user fronted part which actually obtain the access token and ID Token. Then you have a backend portion (MS as you defined) which rely on tokens to perform some validations (ex:- Email validation against a know DB). So basically MS being part of your application, this is still in scope for the term CLIENT.
An alternative to this is to use self contained access tokens. They will come in form of a JWT (similar to ID Token) and usually can be configured to have necesary user information. Advantage with that is you can possibly avoid MS to OP call for user information and rely on JWT integrity (note - of course you need public key from OP but this can be cached for sometime)

How to exchange OAuth2 authorization codes for access tokens received from a client (Ember) in Express?

I'm using ember-simple-auth and torii to handle client-side OAuth2 authentication against Facebook and Google in an Ember app I'm building. I receive an authorization code from that process.
I want to send that code from the client to my REST API and exchange them for access tokens to get their user ID so I can figure out what information they should have access to.
Then, I want to put the user ID into a JSON web token that the client can send me in subsequent requests for data from the BE app.
My Problem: All examples I've found of using Passport for OAuth2 authentication rely on redirecting the user on the server side and using callbacks rather than just exchanging an already-provided authorization code.
What am I missing? This seems like something many apps would need to do.
Assuming a compliant OAuth 2.0 implementation, exchanging an authorization code for an access token is accomplished by performing a POST request to the token endpoint URL and providing the following parameters using the application/x-www-form-urlencoded format:
grant_type - Must be set to authorization_code.
code - Will contain the value of the code you have.
redirect_uri - Must be included and the value match, if it was also included in the request to obtain the authorization code.
Additionally, depending on the client you'll have to either provide the client_id parameter if the client was not issued credentials or if the client has credentials you need to perform client authentication, which can be done by passing an HTTP Basic authentication header containing the identifier and the secret.
An example, using unirest, but easily adapted to other HTTP clients:
unirest.post(tokenEndpointUrl)
.headers({
'Accept': 'application/json',
'Content-type': 'application/x-www-form-urlencoded'
})
.auth({
user: clientId,
pass: clientSecret
})
.send(`redirect_uri=${redirectUrl}`)
.send(`code=${code}`)
.send('grant_type=authorization_code')
.end(function (response) {
// Handle response
});
Although the fundamentals will probably not change, check each provider documentation, because they may have extensions put in place or be more flexible in how you can provide the info. For example Auth0 and I think Google is the same will also allow you pass the parameters in a JSON encoded body instead of just in application/x-www-form-urlencoded format.
Update:
Specific authentication providers may implement additional libraries that simplify things for developers integrating with them. For example, Auth0 provides you with passport-auth0 that abstracts and simplifies the way you can integrate Auth0 authentication into your application.

Adding OAuth 2.0 authentication to a RESTful API

I have an API that requires authentication via OAuth 2.0. I originally anticipated using HWIOAuthBundle, however from investigation this is more to do with hooking up 3rd parties into Symfony's security/auth mechanism and does not provide the required mechanism for validating OAuth 2.0 Authorization headers.
I then found some information about FOSOAuthServerBundle which enables an application to become it's own OAuth 2.0 provider as well as providing the required security mechanisms to validate Authorization headers.
However the problem is that I would like integrate the OAuth 2.0 provider (authorisation server) in an external application (which contains the user base) and not include it within the API. Which will provide some mechanism for performing the token verification against this external app via (another) RESTful API.
Points:
RESTful API requires OAuth 2.0 authentication.
OAuth 2.0 authorisation server to be situated in a separate application.
I feel I should use Implicit grant and call the authorization server on each request to validate that the token is correct.
Is my thinking correct?
As far as I undesratnd your requirement, you require to authenticate your APIs via external OAuth Authorization Server:
Client needs to provide the access token retrieved in the above steps
along with the request to access the protected resource. Access token
will be sent as an authorization parameter in the request header.
Server will authenticate the request based on the token.
If token is valid then client will get an access to protected resource otherwise access is denied.
here is an example which might help you to achieve your requirement. Check this document .
Or simply, you can do with Jersey and Oauth
Also, you can check Apache Oltu and figure out the way to achieve your requirement.
A lot of the big companies like Google, Facebook etc have a separate authorization server from the API server. Check out Google's OAuth authorization flow below
You can also check Google's OAuth Documentation for the details.
So all you would need to do is implement a OAuth Provider so that you can authorize against that provider. There's a list of libraries available on the OAuth website: http://oauth.net/code. You can specifically look here; there is an example for running an OAuth Service Provider in Java.
oAuth can most definitely be a server other than your application server. Below is a picture of what the authentication sequence would look like:
-- Obviously, if the forum can't decode or validate the token, the forum would return a 401 status code instead of a 200 status code.
As long as your oAuth server & the Forum share the same public key, you're more than okay with splitting your oAuth Server & your application.
In fact, take a look at jwt.io. Paste the token you get from the oAuth server into there. It should be able to decode the token right away. Then, you can put your public key into the 'secret' text box to verify the token is verified.
Your application (Forum, in this example) should be able to do the same:
1) Grab the token from the Authorization header of the request
2) Decode the token
3) Check the expire date
4) Verify the token using the oAuth's public key
5) Return successful status code or a failure status code