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

Implemented C# 8 Nullable Reference Type standard. #231

Merged
merged 1 commit into from
Jun 26, 2020

Conversation

pmaytak
Copy link
Contributor

@pmaytak pmaytak commented Jun 23, 2020

Issue #15
Original branch #183

  • Implemented C# 8 Nullable Reference Type standard.
  • Includes additional null checks for public method parameters.
  • Few cases where I had to refactor a little to prevent null exceptions.
  • Misc warning and comment fixes.

Note 1:
Created a separate branch because rebasing #183 had some conflicts. Work from #183 is included here.

Note 2:
Analyzers had some funky behavior. Some code didn't have squiggly underlines. Error list had some weird warning types. Perhaps something to do with preview .NET build?
image

References:
Nullable reference types
Reserved attributes contribute to the compiler's null state static analysis
Try out Nullable Reference Types
Update libraries to use nullable reference types and communicate nullable rules to callers

.editorconfig Show resolved Hide resolved
@@ -10,8 +10,8 @@ internal static class AuthorityHelpers
{
internal static string BuildAuthority(MicrosoftIdentityOptions options)
{
var baseUri = new Uri(options.Instance);
var pathBase = baseUri.PathAndQuery.TrimEnd('/');
Uri baseUri = new Uri(options.Instance);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

By default, var becomes the nullable reference type (Uri? in this case). So in some cases I used explicit type instead.

@@ -27,19 +27,19 @@ public void LoadIfNeeded(CertificateDescription certificateDescription)
switch (certificateDescription.SourceType)
{
case CertificateSource.KeyVault:
certificateDescription.Certificate = LoadFromKeyVault(certificateDescription.Container, certificateDescription.ReferenceOrValue);
certificateDescription.Certificate = LoadFromKeyVault(certificateDescription.Container!, certificateDescription.ReferenceOrValue!);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

! overrides the conversion from nullable to non-nullable type, which otherwise would throw an exception. In this case, the properties shouldn't be null.

@@ -203,7 +199,7 @@ private static void ParseStoreLocationAndName(string storeDescription, ref Store
DefaultCertificateLoader defaultCertificateLoader = new DefaultCertificateLoader();
CertificateDescription certDescription = certificateDescription.First();
defaultCertificateLoader.LoadIfNeeded(certDescription);
return certDescription?.Certificate;
return certDescription.Certificate!;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Certificate here, I assume, should never be null. But if it's not found in the cert store, it will be null. I think this will result in passing null to MSAL and to Wilson.

Copy link
Collaborator

Choose a reason for hiding this comment

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

MSAL will handle the cert being null and throw an ArgumentNullException, we catch the exception


In reply to: 444031657 [](ancestors = 444031657)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  • We do get an uncaught NPE when trying to set token decryption cert.

    options.TokenValidationParameters.TokenDecryptionKey =
    new X509SecurityKey(DefaultCertificateLoader.LoadFirstCertificate(microsoftIdentityOptions.TokenDecryptionCertificates));

  • Yes, we do catch the NPE from MSAL. But the exception is kind of general. Also, FromBase64 gives Cannot find the requested object.; FromDisk gives The system cannot find the file specified. Similar to my other comment, maybe we can update this to give better messaging and user experience when we implement cert rotation stuff.

Copy link
Collaborator

Choose a reason for hiding this comment

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

That's fine, but maybe something for a separate PR w/a new issue.

@@ -16,17 +16,17 @@ public class MicrosoftIdentityOptions : OpenIdConnectOptions
/// <summary>
/// Gets or sets the Azure Active Directory instance, e.g. "https://login.microsoftonline.com".
/// </summary>
public string Instance { get; set; }
public string Instance { get; set; } = null!;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a workaround for properties that are really non-nullable, except in once instance when the Data Transfer Objects are not yet initialized.

Comment on lines +8 to +9
# SA0001: XML comment analysis disabled
dotnet_diagnostic.SA0001.severity = none
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This removes 4 warnings from the build pipeline related to disabled comment analysis.

@pmaytak pmaytak marked this pull request as ready for review June 23, 2020 08:12
{
events = new JwtBearerEvents();
}
events ??= new JwtBearerEvents();
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: space?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Where? Looks right.

@@ -80,6 +80,8 @@ public OpenIdConnectMiddlewareDiagnostics(ILogger<OpenIdConnectMiddlewareDiagnos
/// <param name="events">Events to subscribe to.</param>
public void Subscribe(OpenIdConnectEvents events)
{
events ??= new OpenIdConnectEvents();
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: space?

if (token == null)
{
throw new SecurityTokenValidationException("Token is not JWT token.");
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

is that the right error message? when would the casting fail in this case and result in a null token value? the message should have some customer value, so how can they resolve or understand the issue to fix it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am not sure if it's always JwtSecurityToken. Is it? If it is, I can just explicitly cast it.

Copy link
Collaborator

Choose a reason for hiding this comment

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

might be something to look into. the error message is misleading.

@jennyf19
Copy link
Collaborator

some comments. it's hard to review w/so many xml and spelling changes. in the future, can you do those in a separate PR, especially when you have so many? it tends to create noise and slows down the review. thank you.

@pmaytak
Copy link
Contributor Author

pmaytak commented Jun 25, 2020

some comments. it's hard to review w/so many xml and spelling changes. in the future, can you do those in a separate PR, especially when you have so many? it tends to create noise and slows down the review. thank you.

@jennyf19 Will do.

Copy link
Collaborator

@jmprieur jmprieur 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 @pmaytak
A few questions

.editorconfig Show resolved Hide resolved
src/Microsoft.Identity.Web/ITokenAcquisition.cs Outdated Show resolved Hide resolved
@pmaytak pmaytak force-pushed the pmaytak/nullableReferences branch 3 times, most recently from ef1a6ca to 9a9fb77 Compare June 25, 2020 23:22
Copy link
Collaborator

@jennyf19 jennyf19 left a comment

Choose a reason for hiding this comment

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

on my end, only pending things are making a separate PR for throwing exceptions w/the certs and checking the token type.

…l null checks for public method parameters. Minor comment fixes.
@pmaytak pmaytak force-pushed the pmaytak/nullableReferences branch from 9a9fb77 to 3fc2f23 Compare June 26, 2020 19:19
@pmaytak pmaytak merged commit 9924ba1 into master Jun 26, 2020
@pmaytak pmaytak deleted the pmaytak/nullableReferences branch June 26, 2020 19:31
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.

3 participants