Merge branch 'release/2.1' into dev
This commit is contained in:
commit
ce278eba92
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text.Encodings.Web;
|
||||
|
|
@ -44,6 +45,8 @@ namespace OpenIdConnectSample
|
|||
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
|
||||
|
||||
services.AddAuthentication(sharedOptions =>
|
||||
{
|
||||
sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
|
|
@ -56,9 +59,13 @@ namespace OpenIdConnectSample
|
|||
o.ClientId = Configuration["oidc:clientid"];
|
||||
o.ClientSecret = Configuration["oidc:clientsecret"]; // for code flow
|
||||
o.Authority = Configuration["oidc:authority"];
|
||||
|
||||
o.ResponseType = OpenIdConnectResponseType.CodeIdToken;
|
||||
o.SaveTokens = true;
|
||||
o.GetClaimsFromUserInfoEndpoint = true;
|
||||
|
||||
o.ClaimActions.MapAllExcept("aud", "iss", "iat", "nbf", "exp", "aio", "c_hash", "uti", "nonce");
|
||||
|
||||
o.Events = new OpenIdConnectEvents()
|
||||
{
|
||||
OnAuthenticationFailed = c =>
|
||||
|
|
|
|||
|
|
@ -87,6 +87,27 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
collection.Add(new CustomJsonClaimAction(claimType, valueType, resolver));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears any current ClaimsActions and maps all values from the json user data as claims, excluding duplicates.
|
||||
/// </summary>
|
||||
/// <param name="collection"></param>
|
||||
public static void MapAll(this ClaimActionCollection collection)
|
||||
{
|
||||
collection.Clear();
|
||||
collection.Add(new MapAllClaimsAction());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears any current ClaimsActions and maps all values from the json user data as claims, excluding the specified types.
|
||||
/// </summary>
|
||||
/// <param name="collection"></param>
|
||||
/// <param name="exclusions"></param>
|
||||
public static void MapAllExcept(this ClaimActionCollection collection, params string[] exclusions)
|
||||
{
|
||||
collection.MapAll();
|
||||
collection.DeleteClaims(exclusions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delete all claims from the given ClaimsIdentity with the given ClaimType.
|
||||
/// </summary>
|
||||
|
|
@ -96,5 +117,23 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
{
|
||||
collection.Add(new DeleteClaimAction(claimType));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delete all claims from the ClaimsIdentity with the given claimTypes.
|
||||
/// </summary>
|
||||
/// <param name="collection"></param>
|
||||
/// <param name="claimTypes"></param>
|
||||
public static void DeleteClaims(this ClaimActionCollection collection, params string[] claimTypes)
|
||||
{
|
||||
if (claimTypes == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(claimTypes));
|
||||
}
|
||||
|
||||
foreach (var claimType in claimTypes)
|
||||
{
|
||||
collection.Add(new DeleteClaimAction(claimType));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Security.Claims;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.OAuth.Claims
|
||||
{
|
||||
/// <summary>
|
||||
/// A ClaimAction that selects all top level values from the json user data and adds them as Claims.
|
||||
/// This excludes duplicate sets of names and values.
|
||||
/// </summary>
|
||||
public class MapAllClaimsAction : ClaimAction
|
||||
{
|
||||
public MapAllClaimsAction() : base("All", ClaimValueTypes.String)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Run(JObject userData, ClaimsIdentity identity, string issuer)
|
||||
{
|
||||
if (userData == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (var pair in userData)
|
||||
{
|
||||
var claimValue = userData.TryGetValue(pair.Key, out var value) ? value.ToString() : null;
|
||||
|
||||
// Avoid adding a claim if there's a duplicate name and value. This often happens in OIDC when claims are
|
||||
// retrieved both from the id_token and from the user-info endpoint.
|
||||
var duplicate = identity.FindFirst(c => string.Equals(c.Type, pair.Key, StringComparison.OrdinalIgnoreCase)
|
||||
&& string.Equals(c.Value, claimValue, StringComparison.Ordinal)) != null;
|
||||
|
||||
if (!duplicate)
|
||||
{
|
||||
identity.AddClaim(new Claim(pair.Key, claimValue, ClaimValueTypes.String, issuer));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -51,5 +51,62 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
Assert.Equal("role", roleClaims[1].Type);
|
||||
Assert.Equal("role2", roleClaims[1].Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MapAllSucceeds()
|
||||
{
|
||||
var userData = new JObject
|
||||
{
|
||||
["name0"] = "value0",
|
||||
["name1"] = "value1",
|
||||
};
|
||||
|
||||
var identity = new ClaimsIdentity();
|
||||
var action = new MapAllClaimsAction();
|
||||
action.Run(userData, identity, "iss");
|
||||
|
||||
Assert.Equal("name0", identity.FindFirst("name0").Type);
|
||||
Assert.Equal("value0", identity.FindFirst("name0").Value);
|
||||
Assert.Equal("name1", identity.FindFirst("name1").Type);
|
||||
Assert.Equal("value1", identity.FindFirst("name1").Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MapAllAllowesDulicateKeysWithUniqueValues()
|
||||
{
|
||||
var userData = new JObject
|
||||
{
|
||||
["name0"] = "value0",
|
||||
["name1"] = "value1",
|
||||
};
|
||||
|
||||
var identity = new ClaimsIdentity();
|
||||
identity.AddClaim(new Claim("name0", "value2"));
|
||||
identity.AddClaim(new Claim("name1", "value3"));
|
||||
var action = new MapAllClaimsAction();
|
||||
action.Run(userData, identity, "iss");
|
||||
|
||||
Assert.Equal(2, identity.FindAll("name0").Count());
|
||||
Assert.Equal(2, identity.FindAll("name1").Count());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MapAllSkipsDuplicateValues()
|
||||
{
|
||||
var userData = new JObject
|
||||
{
|
||||
["name0"] = "value0",
|
||||
["name1"] = "value1",
|
||||
};
|
||||
|
||||
var identity = new ClaimsIdentity();
|
||||
identity.AddClaim(new Claim("name0", "value0"));
|
||||
identity.AddClaim(new Claim("name1", "value1"));
|
||||
var action = new MapAllClaimsAction();
|
||||
action.Run(userData, identity, "iss");
|
||||
|
||||
Assert.Single(identity.FindAll("name0"));
|
||||
Assert.Single(identity.FindAll("name1"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue