Azure Api Management ValidateJWT With Rs256 PrivateKey - azure

I can understand that we can do JWT validation easily by using symmetric keys(HS256) and open id for the RS256.
In my case I want to validate the JWT using existing private key that I already have. Payload will be encoded by public key, and at the API Management side I want to validate that token with my own predefined private key. Is there a way to do that?

It should be possible to decrypt it manually if needed. But perhaps using output-token-variable-name attribute of validate-jwt policy will be a simpler way out.

Well I can't decrypt the payload but we managed to make it pass di validate-jwt set open id url to a mock openid-configuration file, and convert our *.pem key into jwt key, and then refer the jwtk-url in the mock openid-configuration to that jwtkey json.

Related

Azure Data Factory - Storing Inline Passwords

I have a pipeline in Azure Data Factory that starts by going to a REST API to obtain an authorization token. In order to obtain this token, the initial POST request needs to contain a username, password, and private key in the request body. It looks like this:
{
"Username": "<myusername>",
"Password": "<mypassword>",
"PrivateKey":"<privatekey>"
}
Currently I just have this stored as plain text in the Web activity in ADF
To me this doesn't seem very secure and I'm wondering if there is a better way to store this JSON string. I've looked into Azure Key Vault, but that seems to be for storing "data store" credentials.... What is the best practice for storing credentials like this to be used by ADF?
You can save the individual values as Secrets in Key vault and fetch them individually via Web activity from KeyVault with masked output thereby making your ADF secure.
Below GITHUb location contains the Pipeline JSON :
https://github.com/NandanHegde15/Azure-DataFactory-Generic-Pipelines/blob/main/Get%20Secret%20From%20KeyVault/Pipeline/GetSecretFromKeyVault.json
Other way would be to use SecureString Parameter
But would say to avoid using the parameter and leverage the Key Vault
the credentials can be saved in the key vault secret
The secret can be called for authentication in the linked service that connects to the required base url
Refer https://learn.microsoft.com/en-us/azure/data-factory/connector-http?tabs=data-factory#create-a-linked-service-to-an-http-source-using-ui

Access AWS session token from profile with DefaultCredentialsProvider

My AWS profile in ~/.aws/credentials contains session credentials created by STS.
[default]
aws_session_token=XXX
aws_access_key_id=XXX
aws_secret_access_key=XXX
I am trying to access these credentials using the AWS SDK Java v2
Using the DefaultCredentialsProvider or ProfileCredentialsProvider finds them, but the returned object is of type AwsCredentials rather than AwsSessionCredentials which doesn't include the session token, only the access key ID and secret access key.
Is there any way to retrieve the full session credentials?
AwsCredentials is an interface.
public interface AwsCredentials {
String accessKeyId();
String secretAccessKey();
}
and its implemented by AwsBasicCredentials and AwsSessionCredentials.
Based on whether session token is set or not, proper class will be returned to you when one calls resolveCredentials() API.
instead of using AwsCredentials/AwsSessionCredentials why dont you like to use Aws4PresignerParams it will gives you all three params (aws_session_token,aws_access_key_id and aws_secret_access_key).

JWT Issue with Docusign API

We generated JWT using docusign given private key and validated by Docusign public key in jwt.io site. It generated valid signature.
Using same signature we called Docusign demo server for access token
POST https://account-d.docusign.com/oauth/token
with
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
assertion=Signature generated
but getting error "Invalid Grant".
What could be the possible reason? If signature is already verified in jwt.io with public key, Docusign should accept the assertion value.
As documented, you also need to supply the following claims:
iss--The integration key (also known as client ID) of the application.
sub--The user ID of the user to be impersonated.
iat--The DateTime when the JWT was issued, in Unix epoch format.
exp--The DateTime when the JWT assertion will expire, in Unix epoch format. Use 1 hour after iat or less.
aud--domain name of the authentication service instance to be used. For demo environments, use account-d.docusign.com For production environments, use account.docusign.com. Note: Do not include https:// in the aud value!
scope--The scopes being requested. For the JWT bearer grant, the requested scope should be signature.
See the docs and also see the DocuSign JWT code examples, the repos named eg-01-*
Ask a new question if you'd like further help.

Node.js authentication server for Firebase Admin SDK - JWT validation issue

I am working on a project where we are going to be using different services in a microservice architecture, and we would like to also use some Firebase services. I am working on an auth server that is going to mint custom JWT's for use in both Firebase, as well as the other API projects.
We would like to use the Firebase Auth SDK to easily integrate with FB, Google, Twitter etc, but we need to enrich the user's token with more data. Therefore, my thought process is that I'd create a Node.JS auth server that uses the Firebase Admin SDK to do this. The flow would be as follows:
User logs in with favourite provider on client
If login is succesful, the user receives a JWT from Firebase. This is sent to the auth server for validation
If the auth server can validate the token using the admin SDK, create a new custom token enriched with more data, and return this new custom token to the client
Have client re-authenticate with the new custom token, and use it for communication with both Firebase as well as our other API projects (which will mainly be in .NET Core)
Step 1-3 works fine. The problem arises when trying to verify the custom token on the other services.
TL;DR : There are two questions inhere:
When validating custom tokens issued using the Firebase Node.JS Admin SDK, what should I use as the public key? A key extracted from Google's exposed JWK's, or a key extracted from the private key that is used to sign?
In case of the JWK approach, how should I construct the custom token with a kid header?
First, I am in doubt of the proper way to verify it. (Please excuse me, I'm not that experienced creating OAuth flows.) The algorithm used is RS256, so I should be able to verify the token using a public key. As I see it, there are two ways to get this key:
Extract the public key from the private key and verify using this. I can do this and verify successfully on a test endpoint on my auth server, however I feel this is the incorrect way to do it
The other, and more correct way I think, is to use the values from the token to find the JWK's on Google's "/.well-known/openid-configuration/" endpoint for my project, , i.e.
https: //securetoken.google.com/[PROJECT ID]/.well-known/openid-configuration
to retrieve the exponent and modulus for the correct kid (key ID) and create the public key from those.
The token generated from the admin SDK by doing
admin.auth().createCustomToken(uid, additionalClaims).then(function(customToken)
with some custom claims looks something like this:
headers:
{
"alg": "RS256",
"typ": "JWT"
}
payload:
{
"claims": {
"premiumAccount": true,
"someRandomInnerObject": {
"something": "somethingRandom"
}
},
"uid": "<uid for the user>",
"iat": 1488454663,
"exp": 1488458263,
"aud": "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
"iss": "firebase-adminsdk-le7ge#<PROJECT ID>.iam.gserviceaccount.com",
"sub": "firebase-adminsdk-le7ge#<PROJECT ID>.iam.gserviceaccount.com"
}
I can't seem to get method 2 to work, though. One problem is that the generated token does not have a kid header, and so does not conform to the OpenID spec (AFAIK), which leads to one of two options:
Go with the first approach above. This leads to problems though - if I for some reason need to revoke or reset the private key on the auth server, I need to do it and deploy the changes on all the other services too, making the solution less dynamic and more error-prone.
Generate a similar token manually using one of the libs mentioned at jwt.io, and add the kid from the original Firebase ID token to it's headers.
Problems with number 2:
What should I put as iss, aud and sub, then? The same values as the admin SDK does? If so, isn't that 'cheating', as they are no longer the issuer?
I've tried it (generating a similar copy of the token, but adding the kid of the original token), and I can't seem to verify the generated token using the created PEM key for the kid.
The way I do the latter is this (following a blog guide on the subject):
Go to https://www.googleapis.com/service_accounts/v1/jwk/securetoken#system.gserviceaccount.com and retrieve the modulus (n) and exponent (e) for the relevant kid
Generate the public key using a lib (rsa-pem-from-mod-exp)
Use the key to verify using the 'official' jwt lib
The above results in a public key as such:
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAxXpo7ChLMnv1QTovmm9DkAnYgINO1WFBWGAVRt93ajftPpVNcxMT
MAQI4Jf06OxFCQib94GyHxKDNOYiweVrHVYH9j/STF+xbQwiPF/8L7+haC2WXMl2
tkTgmslVewWuYwpfm4CoQFV29OVGWCqwEcbCaycWVddm1ykdryXzNTqfzCyrSZdZ
k0yoE0Q1GDcuUl/6tjH1gAfzN6c8wPvI2YDhc5gIHm04BcLVVMBXnC0hxgjbJbN4
zg2QafiUpICZzonOUbK6+rrIFGfHpcv8mWG1Awsu5qs33aFu1Qx/4LdMAuEsvX9f
EmFZCUS8+trilqJbcsd/AQ9eOZLAB0BdKwIDAQAB
-----END RSA PUBLIC KEY-----
Two things seem to be wrong. One is that the key is different from the one I can extract from the private key. The other is that the one I extract from the private key has these comments instead:
-----BEGIN PUBLIC KEY-----
-----END PUBLIC KEY-----
with no 'RSA'. Does this matter? In any case, it doesn't verify.
Finally, did I misunderstand the OpenID flow completely? Are the JWKs generated from a private key that I need as well to verify my JWTs? Should I expose my own JWKs on my auth server for the other services to contact and use instead of Google's? I'm a bit confused as to what the Firebase Admin SDK does and doesn't do, I think :-)
I know this is a lot of questions, but I think they're all related.
Some resources I've relied on in my research (besides the official admin sdk docs ofcourse):
jwt.io
Is it still possible to do server side verification of tokens in Firebase 3?
https://ncona.com/2015/02/consuming-a-google-id-token-from-a-server/
https://stackoverflow.com/a/42410233/1409779
https://andrewlock.net/a-look-behind-the-jwt-bearer-authentication-middleware-in-asp-net-core/
After re-authenticating the Firebase client SDK with the custom token, the client actually generates a new ID token with the claims from the custom token. This ID token is what you should use to verify requests made to your different microservices (documented here). So yes, your original ID token is discarded, but a new one is created in its place. And that ID token will be automatically refreshed every hour. So, you should be able to just call user.getToken() to get a valid ID token whenever you need it. That method handles all the caching on your behalf.

Where are JWT tokens stored on the server and other related questions

As the title suggests, where are JWT tokens stored on the server side? in database or in memeory? I understand the implementation can vary due to different requirements, but just in general where would you store it?
If I want to provide a very basic token authentication server, meaning upon receiving a username and password via a POST request, I would like to return a token. In this case, how is a token generated with a very basic algorithm work differently than a jwt token?
With a token generated by a simple algorithm:
it does not contain payload
its value is not computed based on the username and password, thus it cannot be rehashed back to anything meaningful
In this case, is there still value to use JWT?
Thanks!
client needs to store it, on server storage is not required.
JWT have all the claims in itself and is signed by the server as well. On receipt, server checks for the signature and reads the claims. It does not match it against a stored value. That is the whole point of using JWT against access tokens.
Look at how a JWT is structured.
You don't need to store token on server side.
You should store a private key ( any string of your choice)at server preferably as environment variable.The jsonwebtoken provided method use this private key to generate a token to pass to client.
Client has to store this token at client side so that it can pass this token to subsequent request to server in header.
Server would extract the token value from header and validate it using private key by calling a method of jsonwebtoken.If token is not modified by any means then validate will succeed.
Jwt token is not required to be stored but the "secret-key" needs to be stored.
The structure of jwt is header.payload.signature where signature is generated as below by the server :
signature = HS256(base64Header + '.' + base64Payload, 'mysecret')
So in essense:
1.header.payload.signature is sent to client on first sign in
2.client return back header.payload.signature in subsequent api call
3.server decodes it for verification as below:
base64Header, base64Payload, signature = token.split('.')
header = base64Decode(base64Header)
payload = base64Decode(base64Payload)
serverComputedSignature = HS256(base64Header + '.' + base64Payload,
'mysecret')
if serverComputedSignature != signature:
print('FAILED')
A token is a generic term. JWT defines the structure of a token which contains the below three parts.
1. header
2. payload
3. signature
Storing JWT or any other format of token is driven by the business need.
If the content of the JWT has to be used/validated for any reason then it can be stored in a DB or any other storage.
If the need is to validate the signature then there is no reason to store the issued JWT.

Resources