How to validate Json Web Token (JWT) via Java-Jwt API? - jwt

I am new to oauth and JSON Web Token (jwt). I am trying to validate an authorization token (jwt) via Java JWT api (https://github.com/auth0/java-jwt). I was able to decode the header and payload via that API but having trouble to validate the token.
Little I know of this area, I thought I had to add jwks-rs-java api (https://github.com/auth0/jwks-rsa-java) to my test project in order to handle validation part so I imported and ran following statements based on the documentation I read.
The "oauth_server_domain" is Oracle Access Manager (oam).
JwkProvider provider = new UrlJwkProvider("oauth_server_domain");
Jwk jwk = provider.get("keyId_name");
Then I got following exceptions:
com.auth0.jwk.SigningKeyNotFoundException: Cannot obtain jwks from url https://<oauth_server_domain>/.well-known/jwks.json
Caused by javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
I am trying to understand the problem itself and how to rectify it.
Did I provide wrong key id?
Do I need to import a certificate of the remote "oauth_server_domain" into my local box in where I build/execute project in IDE?
How to add ./well-known/jwks.json into oauth server (e.g. OAM)?
Update:
I do have a certificate (in *.der format) with a public key from the authorization server (oam). It seems like I need to manually create ./well-known/jwks.json file by following this guide (https://auth0.com/blog/navigating-rs256-and-jwks/). I think I should be able to convert binary encoded cert to base64 based cert (*.pem format?).
But how can I expose that relative path from authorization server (e.g. https://auth_server_domain:port/.well-known/jwks.json)?
I'd appreciate your advice and input on this matter. Thank you!

Related

Public key Required to verify the JWT issued by AzDO

I have a JWT issued by app.vstoken.visualstudio.com.
When I tried to do validate that token using
System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.Validate();
its throwing following exception
An unhandled exception of type 'Microsoft.IdentityModel.Tokens.SecurityTokenSignatureKeyNotFoundException' occurred in System.IdentityModel.Tokens.Jwt.dll
IDX10500: Signature validation failed. No security keys were provided to validate the signature.
I suspect its because its not able to locate the public key for the issuer having
thumbprint = x5t attribute value present in the JWT header
How to get that public certificate or how to tell JwtSecurityTokenHandler.Validate() to fetch the required certificate to validate the JWT signature.
My first approach was to validate token issued by remote website locally.
To validate locally I needed to validate signature of the token using public key of the remote website (since it has used its private key to sign the token).
But instead of doing that I found out that the remote website exposes set of rest apis accessing which requires user to provide valid token as part of "bearer" header in the http request.
Currently I am using that api to determine authenticity of the user.
The remote website was dev.azure.com and it exposes set of apis and sdk to authenticate the token.
Library used : Microsoft.VisualStudio.Services.WebApi

Generating an API Client with Swagger OpenAPI 3 with OAuth2 Client Credentials

I am using the Swagger OpenAPI 3.0.2 version for describing my API.
I built swagger-codegen 3.0.5 snapshot from the Swagger gihub repo.
I want a Java client that will obtain the OAUTH2 token for a grant type of client_credentials. I want client credentials because this is one machine talking to another, I am not asking a user for their credentials. I have the following bit in my spec file:
securitySchemes:
oAuth2ClientCredentials:
type: oauth2
description: Standard OAUTH2
flows:
clientCredentials:
tokenUrl: my_token_url
scopes: {}
security:
- oAuth2ClientCredentials: []
I want a Basic Authentication header with the client ID and the client secret in the standard base64 encoding with the grant_type as a URL encoded form. This is pretty standard OAuth2 authentication.
I seem to sometimes get code for the OAuth authentication and sometimes not. The python library has nothing for OAuth other than me proving the access token by hand. The Java library doesn't have it unless I ask for retrofit as the base library, but it generates a Bearer Authentication header, rather than a Basic Authentication Header. Retrofit2 doesn't even work, the handlebars template has an illegal character in it that handlebars barfs on.
So what do people do to get their access tokens when they have a client ID and a client secret? Do you craft the code to get the access token by yourself? Or is there some magic way of getting swagger-codegen-cli to generate the code for me, depending on the libraries that I use?
If anyone has managed to get swagger-codegen-cli to generate everything they need for OAuth 2 client credentials with an OpenAPI 3.0 specification, please let me know.

Generate Access Token for Simple_Oauth authentication in Drupal 8

My motive is to generate an access token for the client (through simple_oauth module of Drupal) with the help of which the client can access the content of Drupal 8 site via REST API. But the Generate token tab is not available on the screen, also I have tried generating the token through Postman by using OAuth2.0 authentication, but failed to understand what to write in the Authorization URL and token URL field.
Any suggestion will be appreciated. Thanks in advance.
Quick demo (Password Grant)
Install the module using Composer: composer config repositories.drupal composer https://packages.drupal.org/8 && composer require drupal/simple_oauth:^3. You can use any other installation method, as long as you install the OAuth2 Server composer package.
Generate a pair of keys to encrypt the tokens. And store them outside of your document root for security reasons.
openssl genrsa -out private.key 2048
openssl rsa -in private.key -pubout > public.key
Save the path to your keys in: /admin/config/people/simple_oauth.
Go to REST UI and enable the oauth2 authentication in your resource.
Create a Client Application by going to: /admin/config/services/consumer/add.
Create a token with your credentials by making a POST request to /oauth/token. See the documentation about what fields your request should contain.
(Not shown) Permissions are set to only allow to view nodes via REST with the authenticated user.
Request a node via REST without authentication and watch it fail.
Request a node via REST with the header Authorization: Bearer {YOUR_TOKEN} and watch it succeed.**

JMeter : SOAP Message Signer Plugin

I am trying to send a SOAP request(signed) using HTTP Request Sampler along with SOAP Message Signer plugin. Request works fine with SOAPUI. It seems to fail through JMeter if i use same parameters(for SOAP Message Signer).
As a part of SOAP Request, Header needs to be signed. I am getting the below error while Signing. Could anyone please let me know the reason for failure?
n.c.b.j.m.AbstractWSSecurityPreProcessor: Building WSS header
o.a.w.d.m.WSSecSignature: Beginning signing... ERROR
n.c.b.j.m.AbstractWSSecurityPreProcessor:
org.apache.wss4j.common.ext.WSSecurityException: No certificates for
user "cert_alias" were found for signature
Did you add in jmeter keystore the certificate under alias cert_alias?
That's what message is saying:
No certificates for user "cert_alias" were found for signature
Keystore is located in jmeter/bin folder
You may want to try this plugin:
https://github.com/tilln/jmeter-wssecurity/blob/master/README.md
Finally i was able to send a successful request using the plugin.
I was using the Signed Header as a part of SOAP request.
Plugin Config:
Keystore File : Path to .jks file
Keystore Password : password
Cert Alias - cert_alias
Cert Password - cert password
After removing the Signed Header from the SOAP request, it worked. Thanks you.
If your SOAP endpoint expects the message to be encrypted with a client-side certificate you can configure JMeter to use it by adding the next lines to system.properties file:
javax.net.ssl.keyStoreType=pkcs12 or jks
javax.net.ssl.keyStore=/path/to/your/jsk keystore or .p12 certificate
javax.net.ssl.keyStorePassword=your certificate or keystore password
JMeter restart will be required to pick the properties up.
You can also pass them via -D command line argument like:
jmeter -Djavax.net.ssl.keyStoreType=pkcs12 -Djavax.net.ssl.keyStore=your-certificate.p12 -Djavax.net.ssl.keyStorePassword=secret
More information:
Customizing the Default Key and Trust Stores, Store Types, and Store Passwords
How to Set Your JMeter Load Test to Use Client Side Certificates

How pkix profile works in Spring Security SAML

I was reading the spring security saml doc site: http://docs.spring.io/autorepo/docs/spring-security-saml/1.0.x-SNAPSHOT/reference/htmlsingle/#configuration-security-profiles-pkix
I am just having a hard time to understand how the pkix profile works.
From my understanding, when idp sends back saml response, it will sign the response to show the validity of the message.
In metaiop, the SP will use the key from idp's metadata to verfiy signature on response.
Pkix seems like an extension of metaiop, it will do metaiop's check and also this:
All keys specified in trustedKeys set of extended metadata of a remote
entity, or all keys available in the key store when the property is
null (default value)
I just don't understand the above statement, what is the key store referred to in here? the local keystore?
I hope someone can clearify for me.
Keystore referenced in the documentation is the samlKeystore.jks of the sample application.
While MetaIOP needs to have the exact version of the certificate which will be used for signatures, PKIX uses verification based on trusted certification authorities (just like e.g. web browsers do) - which means you don't need to have the exact certificate used for signature in advance - as long as it's issued by one of the CAs you trust. PKIX also verifies e.g. certificate validity period (and other checks in certification path validation of RFC 5280 - https://en.wikipedia.org/wiki/Certification_path_validation_algorithm). Those are the key differences.