Implements certificate credential authentication using JWT assertions#247
Implements certificate credential authentication using JWT assertions#247simonrob merged 5 commits intosimonrob:mainfrom
Conversation
|
Thanks for the contribution! In order to test before merging this I'll need access to an account that can be authenticated via JWT, which I don't have at the moment. Is this something you could provide for this purpose? |
|
I could provide you with a temporary test account. How can I contact you privately? |
|
That would be perfect. You can reach me via my GitHub username at Gmail. |
|
I have sent you an email. |
|
Thanks for providing the test account – I've just taken a look. I made a few minor edits:
Just so there is a record, here's a sample configuration file entry using this method: [your-email-address@example.com]
permission_url = https://login.microsoftonline.com/*** your tenant id here ***/oauth2/v2.0/authorize
token_url = https://login.microsoftonline.com/*** your tenant id here ***/oauth2/v2.0/token
oauth2_scope = https://outlook.office365.com/IMAP.AccessAsUser.All https://outlook.office365.com/SMTP.Send offline_access
redirect_uri = http://localhost
client_id = *** your client id here ***
jwt_certificate_path = /path/to/certificate.pem
jwt_key_path = /path/to/key.pemUnless there are any other features to be added, I think this is probably ready to be merged. Let me know what you think? |
|
Thanks for taking your time to polish this - it's looking really good now. Re:
They might not be required by the spec, but at least for
I also found this page which states:
and
|
|
Interesting – thanks for following up. The original page isn't completely clear – it essentially just lists the properties defined in the RFC. Because of this, I determined through experimentation which ones O365 does and does not actually require for OAuth 2.0 login. I hadn't seen the other link you've found, but in its Crafting the assertion section it gives this example: // no need to add exp, nbf as JsonWebTokenHandler will add them by default.
var claims = new Dictionary<string, object>()
{
{ "aud", tokenEndpoint },
{ "iss", clientId },
{ "jti", Guid.NewGuid().ToString() },
{ "sub", clientId }
};As explained in the comment, the From testing, I found that the So: long story short, I think |
Sounds reasonable to me. |
Since Microsoft is no longer issuing client secrets with indefinite validity for O365 application registrations, I have decided to implement certificate credential authentication using JWT assertions. At this time, there seem to be no restrictions on the validity of self-signed certificates (I managed to upload and use a 10yr certificate to Entra just fine).
Microsoft even recommends certificate authentication:
The workflow and technicals for certificate authentication are described here.
This PR adds two account configuration options
jwt_certificate_pathandjwt_key_path. These options are to be used in place ofclient_secret(i.e., that value should be removed).jwt_certificate_pathis expected to be a path to a x509 pem-encoded certificate;jwt_key_pathis expected to be a path to an unencrypted pem-encoded private key.To generate the certificate and private key, the following command can be used:
The
certificate.pemthat is generated can then be uploaded to the application registration in the Entra admin console.