Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removed dependency on System.IdentityModel.Tokens.Jwt from WPS #22112

Merged
merged 15 commits into from
Jun 24, 2021

Conversation

KrzysztofCwalina
Copy link
Member

@KrzysztofCwalina KrzysztofCwalina commented Jun 23, 2021

This PR includes a custom implementation of a JWT builder/writer.
The JwtBuilder is now used instead of an external dependency on System.IdentityModel.Tokens.Jwt

I wanted to make the code fast and non-allocating. The System.IdentityModel.Tokens.Jwt library caches tokens. This new implementation does not. The cache has been identified as problematic in preview 1.

@KrzysztofCwalina KrzysztofCwalina requested a review from ellismg June 23, 2021 20:55

string accessToken = JwtUtils.GenerateJwtBearer(audience, claims: null, expiresAt, _credential);
// TODO: is this a bug in the service?
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vicancy, I noticed something strange when I was changing this code. The key string comes from the portal. If I Base64 decode it, this library will not successfully authenticate with the service. If I just use ASCII bytes of the key string, it does work. The same behavior was present in preview 1, but I find it strange. Key strings of other services need to be Base64 decoded.

@KrzysztofCwalina
Copy link
Member Author

@GrabYourPitchforks, you might want to look into the NS2Bridge.cs for BCL text transformation APIs we would love to have in a package.

@KrzysztofCwalina KrzysztofCwalina marked this pull request as ready for review June 23, 2021 21:51
int maxBufferLength =
Base64.GetMaxEncodedToUtf8Length(headerSha256.Length + payloadLength)
+ 1 // dot
+ Base64.GetMaxEncodedToUtf8Length(32); // signature SHA256 hash size
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we make this static readonly to avoid computing it once per call?

Copy link
Member Author

@KrzysztofCwalina KrzysztofCwalina Jun 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Payload length is per call. The Uri and DateTimeOffsets change between calls. This computation is very cheap. It's just 4/3 * length. https://github.com/dotnet/runtime/blob/main/src/libraries/System.Memory/src/System/Buffers/Text/Base64Encoder.cs#L150

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feedback was specifically about the just making the result of a Base64.GetMaxEncodedToUtf8Length(32) constant, but no need to change things here.

Assert.NotNull(exp);
Assert.IsTrue(long.TryParse(exp, out var expireAt));

// default expire atfte should be ~5 minutes (~300 seconds)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// default expire atfte should be ~5 minutes (~300 seconds)
// default expire after should be ~5 minutes (~300 seconds)

return result;
}

public static void Append(this StringBuilder sb, ReadOnlySpan<char> value)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is unused, can it be removed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I had a WriteTo(StringBulder) overload. But I removed it. If we ever make the JwtBulder public, it would be good to have these, but I will add them at that point.

public static ReadOnlySpan<byte> Iss => s_iss;
public static ReadOnlySpan<byte> Jti => s_jti;

// this is the standrd JWT header. { "alg": "HS256", "typ": "JWT" }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// this is the standrd JWT header. { "alg": "HS256", "typ": "JWT" }
// this is Base64 encoding of the standard JWT header. { "alg": "HS256", "typ": "JWT" }

private Utf8JsonWriter _writer;
private MemoryStream _memoryStream;
private byte[] _key;
private bool isDisposed;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: should we name it _isDisposed?

int payloadLength = (int)_writer.BytesCommitted; // writer is wrrapping MemoryStream, and so the length will never overflow int.

int payloadIndex = headerSha256.Length;
int maxBufferLength =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any concerns about /this/ computation overflowing?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be very hard to make it overflow, but I changed the code to do checked additions.

@KrzysztofCwalina KrzysztofCwalina removed the request for review from JialinXin June 23, 2021 22:27
Copy link
Member

@ellismg ellismg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - Thanks for the changes!

@KrzysztofCwalina KrzysztofCwalina merged commit 77dc25a into Azure:main Jun 24, 2021
@KrzysztofCwalina KrzysztofCwalina deleted the WPSJWT branch July 8, 2021 16:19
azure-sdk pushed a commit to azure-sdk/azure-sdk-for-net that referenced this pull request Feb 2, 2023
Dev keyvault microsoft.key vault 2022 02 01 preview swagger completeness (Azure#22154)

* Adds base for updating Microsoft.KeyVault from version stable/2022-07-01 to version 2022-02-01-preview

* Updates readme

* Updates API version in new specs and examples

* Fixed breaking changes in managedHsm.json. (Azure#22112)

Fixed LRO_RESPONSE_HEADER, INVALID_REQUEST_PARAMETER and OBJECT_MISSING_REQUIRED_PROPERTY errors.

Co-authored-by: Rahul Alapati <rahulalapati@microsoft.com>

* Undid the API version changes to the Vaults_List API (Azure#22142)

* Fixed breaking changes in managedHsm.json.
Fixed LRO_RESPONSE_HEADER, INVALID_REQUEST_PARAMETER and OBJECT_MISSING_REQUIRED_PROPERTY errors.

* Undid the API Version change to the VaultListFilterTypes API.

Co-authored-by: Rahul Alapati <rahulalapati@microsoft.com>

* Update listVault.json (Azure#22155)

* Update listVault.json

* Remove the preview API version for the enum

* Delete Vault_Lists API specification

* Added the Vaults_List swagger specification back.

* Abstracted Vaults_List API into 2015-11-01 directory to Swagger ModelValidation Errors.

* Resolved unresolvable references.

* Reorganized the definitions.

* Reorganized the 2015-11-01 directory under 2022-02-01-preview

* Moved the 2015-11-10 directory to stable.

* Undo the abstraction changes.

* Readd the listVault.json.

* Added suppression directives for INVALID_REQUEST_PARAMETER and OBJECT_MISSING_REQUIRED_PROPERTY.

* Modify suppress rule.

* Update the suppression directive.

* Update suppression directive.

* Update suppression directive.

* Update suppression directives.

* Updated suppression directive.

* Added suppression directives for INVALID_REQUEST_PARAMETER, OBJECT_MISSING_REQUIRED_PROPERTY

* Updated suppression directives.

* Updated suppression directives.

* Updated suppression directives.

* Updated suppression directives.

* Updated suppression directives.

* Added x-ms-validation rules to the api-version parameter.

* Updated suppression directives.

* Added individual suppression directives.

* Removed where clause from the OBJECT_MISSING_REQUIRED_PROPERTY suppression directive.

* Corrected yaml title for suppression directives.

Co-authored-by: Rahul Alapati <rahulalapati@microsoft.com>

---------

Co-authored-by: Rahul Alapati <rahulalapati@microsoft.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants