Skip to content
This repository was archived by the owner on Nov 22, 2018. It is now read-only.

Updated UID generation in DefaultClaimUidExtractor #52

Merged
merged 1 commit into from
Feb 16, 2016
Merged

Conversation

ajaybhargavb
Copy link
Contributor

return new string[]
{
"sub",
subClaim.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 comment #30 (comment) mentions the claim and issuer... @blowdart want to explain exactly what to do?

Copy link
Member

Choose a reason for hiding this comment

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

You'd take the claim value, and the claim issuer (the Issuer property on the claim), and safely concatenate them (basically you do len(value)+value+len(issuer)+issuer), then either put that in the token, or a SHA256 hash of the concatenated value.

This basically means that if, for example, facebook and google issued the same sub claim value, you could still tell them apart, because the issuer is different.

Copy link
Member

Choose a reason for hiding this comment

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

Well these 2-string arrays are run through a SHA256 hash soon after this method returns. Questions:

  • Should they be 3-string arrays, adding the issuer?
  • Use Issuer or OriginalIssuer from the Claim?

@rynowak
Copy link
Member

rynowak commented Feb 6, 2016

{
// Arrange
var identity = new ClaimsIdentity();
identity.AddClaim(new Claim("fooClaim", "fooClaimValue"));
Copy link
Member

Choose a reason for hiding this comment

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

Nit: Please avoid "foo" and similar

Copy link
Member

Choose a reason for hiding this comment

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

Our tests use foo in thousands of places, what's wrong with it? It at least makes it clear that it's an arbitrary value...

@ajaybhargavb
Copy link
Contributor Author

Updated.

@ajaybhargavb
Copy link
Contributor Author

Need to add more tests. Will do it once the updated design is accepted.

@@ -66,7 +66,12 @@ public AntiforgeryToken GenerateCookieToken()
if (identity != null && identity.IsAuthenticated)
Copy link
Member

Choose a reason for hiding this comment

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

Should we still check this now that you're checking User?.Identities? Seems redundant and unnecessary

Copy link
Member

Choose a reason for hiding this comment

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

Also, why does caller pass in httpContext.User.Identity when this code turns around and uses httpContext.User?.Identities? Another reason to start w/ the ClaimsPrinciple as @rynowak suggested below.

Copy link
Member

Choose a reason for hiding this comment

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

Note that if Identity is equal to the first member of Identities where IsAuthenticated is true, existing code was 🆗. (I'm not sure whether "primary" in the Identity doc comment means IsAuthenticated or something else.)

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 looked at the code. It does not check for IsAuthenticated. It simply selects first non-null identity. https://github.com/dotnet/corefx/blob/master/src/System.Security.Claims/src/System/Security/Claims/ClaimsPrincipal.cs

@rynowak
Copy link
Member

rynowak commented Feb 8, 2016

var nameIdentifierClaim = claimsIdentity.FindFirst(
claim => string.Equals(ClaimTypes.NameIdentifier, claim.Type, StringComparison.Ordinal));
if (nameIdentifierClaim != null && !string.IsNullOrEmpty(nameIdentifierClaim.Value))
if (claimsIdentities == null)
Copy link
Member

Choose a reason for hiding this comment

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

Can the IEnumerable<T> be null in real scenarios?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure. But I guess returning null is better than just letting it blow up.

Copy link
Member

Choose a reason for hiding this comment

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

We don't add these kind of checks just because. It may mislead developers down the road if it's not a real scenario. Check.

Copy link
Member

Choose a reason for hiding this comment

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

Actually, this isn't a real scenario since the caller checks exactly this condition. Just Debug.Assert().

@dougbu
Copy link
Member

dougbu commented Feb 8, 2016

@ajaybhargavb
Copy link
Contributor Author

Updated.

@@ -60,16 +61,17 @@ public AntiforgeryToken GenerateCookieToken()
};

var isIdentityAuthenticated = false;
var identity = httpContext.User?.Identity as ClaimsIdentity;
var authenticatedIdentity = httpContext.User?.Identities?.FirstOrDefault(c => c.IsAuthenticated == true);
Copy link
Member

Choose a reason for hiding this comment

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

We're trying hard to optimize Antiforgery. Don't introduce Linq here.

Copy link
Member

Choose a reason for hiding this comment

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

Also,

  • Can Identities really be null? Check the real code and don't check here unless it's a real scenario.
  • Lots of boilerplate around authenticatedIdentity repeated in two methods. Suggest a helper method.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can Identities really be null?

You are right. It can never be null. An empty list is always allocated.

@dougbu
Copy link
Member

dougbu commented Feb 10, 2016

@ajaybhargavb
Copy link
Contributor Author

Updated.

@@ -60,16 +61,17 @@ public AntiforgeryToken GenerateCookieToken()
};

var isIdentityAuthenticated = false;
var identity = httpContext.User?.Identity as ClaimsIdentity;
var authenticatedIdentity = httpContext.User != null ? GetAuthenticatedIdentity(httpContext.User) : null;
Copy link
Member

Choose a reason for hiding this comment

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

Remove the ternary and have GetAuthenticatedIdentity() return null when passed null.

"LOCAL AUTHORITY",
ClaimTypes.Name,
"claimName",
"LOCAL AUTHORITY",
Copy link
Member

Choose a reason for hiding this comment

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

This test demonstrates the behaviour I complained about here. Should never mix claims from multiple identities in the same UID.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@dougbu
Copy link
Member

dougbu commented Feb 10, 2016

@ajaybhargavb
Copy link
Contributor Author

Updated.

using System.Security.Claims;

namespace Microsoft.AspNetCore.Antiforgery.Internal
{
/// <summary>
/// This interface can extract unique identifers for a claims-based identity.
/// This interface can extract unique identifers for a list of claims-based identities.
Copy link
Member

Choose a reason for hiding this comment

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

For a ClaimsPrincipal

@rynowak
Copy link
Member

rynowak commented Feb 10, 2016

:shipit: from me. Get a signoff of @dougbu and @blowdart also

Debug.Assert(claimsPrincipal != null);

var uniqueIdentifierParameters = GetUniqueIdentifierParameters(claimsPrincipal.Identities);
if (uniqueIdentifierParameters == null)
{
// Skip anonymous users
Copy link
Member

Choose a reason for hiding this comment

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

Fix this comment. Never reach here if the principal isn't logged in somehow.

@dougbu
Copy link
Member

dougbu commented Feb 10, 2016

:shipit: with a couple more tests. Suggest walking @blowdart though the tests and getting his agreement on the new behaviour.

@ajaybhargavb
Copy link
Contributor Author

Updated and Rebased.

@ajaybhargavb
Copy link
Contributor Author

Ping @blowdart

@blowdart
Copy link
Member

Works for me. Might need more kittens though.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants