Quarkus Custom JWT Validation - security

I'm working on a migration from JHipster to Quarkus 2. In the current project, using JHispster, we have a custom way to build our JWT Token. Basically it's a kind of basic auth which give a JWT token we need to use on all our next http call. This token is sign by a phrasepass (not RSA or something like this just a plaintext). We have few api which use this token as authorization, we currently use exactly the same jhispster code to validate the token. Now we are moving on Quarkus one of those APIs I need to validate the JWT token.
I saw here: https://quarkus.io/guides/security-jwt#create-jsonwebtoken-with-jwtparser that there is a JWTParser which looks to do the job, but I don't know how to configure this phrasepass.
For example I tried this configuration:
smallrye.jwt.verify.key-format=JWK_BASE64URL
smallrye.jwt.verify.key.location=/secret.txt
(The secret.txt file is in my src/main/resources folder.)
When I call the API I have this issue:
org.jose4j.lang.UnresolvableKeyException: SRJWT07004: Failed to load a
key from the key content while resolving
Any suggestions?

I worked with Quarkus 2.0 a few months ago and also had some issues in regards to JWT. For some reason it doesn't actually load the JWT tokens from the files. Migrating to a newer version of Quarkus fixed my problem. I'm not sure if it's a bug, but try to migrate to Quarkus 2.2.2. If that doesn't work try an older version like 1.11 or 1.7.

Related

requests-oauthlib auto refresh Bearer token in client credentials flow?

I'm using the python requests-oauthlib package to connect to the Microsoft Graph. I am using the OAuth 2.0 Client Credentials flow.
The following simplified code works perfectly fine:
from oauthlib.oauth2 import BackendApplicationClient
from requests_oauthlib import OAuth2Session
client = BackendApplicationClient(client_id='myclientid')
token_url = "https://login.microsoftonline.com/mydomain.onmicrosoft.com/oauth2/v2.0/token"
msgraph = OAuth2Session(client=client)
msgraph.fetch_token(
token_url = token_url,
client_secret = 'myclientsecret',
scope='https://graph.microsoft.com/.default')
response = msgraph.get(
url="https://graph.microsoft.com/v1.0/users/user#mydomain.com/messages")
While this works, the Bearer access token in this case is only valid for 1 hour. The requests-oauthlib package has support for refreshing tokens but it seems limited to token types that come with separate refresh tokens. The client credentials flow as used with the Microsoft Graph only issues an access_token.
So my questions are:
Is there a way to make the requests-oauthlib refresh the token automatically in this use case or do I need to manually track the age of my token and explicitly refresh it as needed?
I'm not wedded to requests-oauthlib so if there is a better library that accomplishes the auto-refreshing I'd be interested in using it.
This behavior is by design (and aligns with the OAuth spec). The only OAuth grants that support Refresh Tokens are Authorization Code and Resource Owner Password Credentials. The Implicit and Client Credentials grants only return an Access Token.
More importantly, since the Client Credentials flow isn't interactive, there is no need for Refresh Tokens. You simply request a new token when the old one expires.
As far as I can tell, there is still no built-in way to do this automatically using requests-oauthlib. There is a ticket about it on their GitHub with a couple of different ideas on how to do it, but nothing out of the box: https://github.com/requests/requests-oauthlib/issues/260
I know this is an old question, but it seems unanswered, so please allow me to give it a try.
My initial answer was:
I dare make the hypothesis, reading your mention of lack of refresh token, that you did not add offline_access in your requested scope - if you want it to be part of the answer from the Microsoft authentication service, you have to (please refer to https://learn.microsoft.com/en-us/graph/auth-v2-user#token-response and the various pages around for more details).
which was indeed totally irrelevant for the scenario used, as commented by Mark, and also clearly stated in https://learn.microsoft.com/en-us/azure/active-directory/fundamentals/resilience-daemon-app#cache-and-store-tokens:
It is important that applications use the "expires_in" property to determine the lifespan of the token.
So as an answer to your question 2., the above link also suggests the use of MSAL (MS Authentication Library):
MSAL implements and follows [best practices for caching and storing tokens] automatically.
what the why use MSAL wiki page seems to confirm:
It also adds value by [...] maintaining a token cache and refreshes tokens for you when they are close to expire. You don't need to handle expiration on your own.
For your question 1., I indeed did not find a standard way in requests-oauthlib to do so, either.
In this kind of situation, I usually don't monitor the age of the token, but just catch the 401 return code and fetch a new token.
To do so, I found suitable to tweak the first example of the Requests-OAuthlib - OAuth 2 Workflow - refreshing tokens section, replacing their call to refresh_token(refresh_url, **extra) by a new call to fetch_token().
What I usually use in order to avoid repeating the try...except... code piece, is to put it in a wrapper decorator (got a good inspiration in https://realpython.com/primer-on-python-decorators/#a-few-real-world-examples ) around my API-calling functions / methods.
Hope this time it helps more...

Where I should store code_verifier (oauth 2.0 code authorization flow with PKCE)

I'm currently working on an oauth 2.0 code authorization grant with PKCE in an SSR page (working with React in the front and Express in the back).
Where I should store code_verifier when client request to authorization server code (when authorization server creates code_challenge and code_verifier for verify latter). I have the authorization server running in an independent stack/infrastructure.
I should store code_verifier in req.headers ?
(see Draft Campbell OAuth TBPKCE-00)
We are following RFC6749
I would suggest you to think about storing it in cookies, it is an easy way and it is not a really big deal if someone sees it. You can use the cookie-parser library for Node.js, which I personally really like and use almost daily, as it provides developer-friendly tools.
FYI: I am working on mainly on GraphQL APIs, and I find a good solution also to store the code_verifier in the context of the GraphQL Server, e.g. Apollo Server.

Curl Command throwing' invalid grant error' on Windows command line

I have generated the JWT Token for DocuSign through the https://jwt.io .The signature is verified.
Now to obtain the Access token I am using following Command in Curl,on Windows Command line tool.Rrefering the Document https://developers.docusign.com/esign-rest-api/guides/authentication/oauth2-jsonwebtoken.I am getting "invalid Grant".What is the problem with my request?I know my token is correct because the token verifies the signature.
curl --data "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=YOUR_JSON_WEB_TOKEN" --request POST https://account-d.docusign.com/oauth/token
invalid_grant is the the publicly facing version of several errors rolled together. If you've hit your limit of troubleshooting, I'd recommend opening a case with DocuSign Support, and provide your Demo Account ID, UserID, Integrator Key and the value of an x-DocuSign-TraceToken of a failing assertion. The plaintext version of your assertion would be helpful as well.
Here's a few things to check:
aud value - must be exactly account-d.docusign.com (for demo) or account.docusign.com for prod. Including https:// or any other value will fail.
sub value - must be an active userID (in GUID format) in the appropriate environment.
iss value - must be a valid client ID
Private Key used for signing - must be associated with the Client ID in the correct environment. If you're using a key generated in Production but the assertion is directed to account-d.docusign.com it will fail. In some cases it can take a few minutes for a newly generated keypair to be valid in the Account Server, so if you've just generated that key, wait a bit and try again.
Timestamps used - Your exp value must not have passed, and if you are using an nbf value, it must be in the past. Confirm your computer's clock is correctly configured - if it's dramatically off, your application could be generating invalid assertions because of that.
The pro-tip is to use a library to generate the JWT and convert it to an Access Token.
See the JWT examples for code examples in many languages. The examples use either a JWT method from a DocuSign SDK or a lower level JWT library.
C# .NET Core https://github.com/docusign/eg-01-csharp-jwt-core
C# .NET Framework https://github.com/docusign/eg-01-csharp-jwt-framework
PHP https://github.com/docusign/eg-01-php-jwt
Java https://github.com/docusign/eg-01-java-jwt
Node.js https://github.com/docusign/eg-01-node-jwt
Python. https://github.com/docusign/eg-01-python-jwt
Ruby https://github.com/docusign/eg-01-ruby-jwt
See the repositories’ Readme files for installation and configuration instructions.

Getting Swagger UI oauth2 work with oidc-provider

I am trying to get Swagger UI to successfully authorize to a oidc-provider instance.
I have set up a minimal (as possible) instance on glitch here: https://glitch.com/~copper-vise
What it does is:
have swagger UI on /doc serving the definition from the swagger.yaml file
run the oidc provider with minimal configuration and dev interactions.
The problem is that I don't seem to be able to get the two work together. It seems like it could be a Swagger UI bug, but considering my lack of experience with oidc it might simply be a configuration issue.
To try, click the "Authorize" button on the swagger interface, use foo and bar for the client_id and client_secret, check at least the openid scope and click "Authorize". At this point you should get a login prompt. Enter anything you like and login. At this point the swagger UI should be having a token, but I never got it that far.
What I'm getting instead is a invalid_client error, it seems like the oidc-provider expects an authorization request header that the Swagger UI is not providing. The "implicit" flow does not seem to work at all either. As far as I can tell, these are the two flows that the oidc-provider supports (with this configuration?).
I'm stuck, not sure where to go from here. It seems like the right combination of the openapi securitySchemes configuration in the swagger.yaml file and the oidc-provider and client options should get this running.
It seems swagger is sending client_secret_post client authentication, the default on the IdP is client_secret_basic. If you change the client configuration on the IdP to match the scheme the client is actually using it'll work.

How to read principals and encrypted keys from Kerboros keytab file on Node JS?

I need to intercept a specific request coming to my Node Server and introduce Kerberos Authentication right there.
Suppose if a request comes for /names/ ,I need to first Kerberos authenticate it and only if it authenticated successfully, I will proceed to fulfill the request.
I have one .keytab file which in my knowledge has the principals and encrypted keys which I need for authentication.
QUESTION: How can I read the .keytab encrypted file on Node JS?
I have looked into Node packages like node-krb5 and node-passport but couldn't find a way to read my keytab files
Please assist if you done something similar.
Thanks.
You should look at the node passport-negotiate module which implements server side kerberos ticket authentication checking. There's a sample "login" app in the module which demonstrates how to use the module, and if you look at the strategy.js you should see how to use the underlying kerberos support, should you want to bypass passport and do authentication directly.
The actual server-side kerberos functionality is part of npm kerberos module.
I looked at the source for node-krb5 and that's fairly useless. All it does
is more or less what kinit does.
My guess is that you would need a node implementation of SPNEGO which a web authentication protocol that uses kerberos. None of the things in your list
do that and it's not a trivial thing to write.
I'd suggest you look into putting a server that does support SPNEGO in front
of your node application.

Resources