C# 从Core1.1迁移到2.0-身份验证

C# 从Core1.1迁移到2.0-身份验证,c#,.net,authentication,asp.net-core-1.1,.net-core-2.0,C#,.net,Authentication,Asp.net Core 1.1,.net Core 2.0,在我的.NETCore1.1代码中,我按照如下方式进行身份验证(将承载令牌发送到外部URL,并在返回令牌中查找声明)。此代码位于Configure方法中 app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationScheme = "Cookies" }); app.UseOpenIdConnectAuthentication(ne

在我的.NETCore1.1代码中,我按照如下方式进行身份验证(将承载令牌发送到外部URL,并在返回令牌中查找声明)。此代码位于
Configure
方法中

app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationScheme = "Cookies"
        });

        app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
        {
            AuthenticationScheme = "oidc",
            SignInScheme = "Cookies",

            Authority = signinAuthority,
            RequireHttpsMetadata = signinHTTPS,

            ClientId = "skybus",
            ClientSecret = "secret",

            ResponseType = "code id_token",
            Scope = { "api1", "offline_access" },

            GetClaimsFromUserInfoEndpoint = true,
            SaveTokens = true
        });
services.AddAuthentication(options => {
            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
        })
            .AddCookie()
            .AddOpenIdConnect(o =>
            {
                o.Authority = signinAuthority;
                o.SignInScheme = "Cookies";
                o.RequireHttpsMetadata = signinHTTPS;
                o.ClientId = "skybus";
                o.ClientSecret = "secret";
                o.ResponseType = "code id_token";
                o.GetClaimsFromUserInfoEndpoint = true;
                o.SaveTokens = true;
                o.Scope.Add("api1");
                o.Scope.Add("offline_access");
            });
现在我将我的代码升级到.net Core 2.0,
UseCookieAuthentication
UseOpenIdConnectAuthentication
都已更改。我发现很难找到在这种情况下需要做什么

我在
ConfigureServices
方法中将其更改为如下内容

app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationScheme = "Cookies"
        });

        app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
        {
            AuthenticationScheme = "oidc",
            SignInScheme = "Cookies",

            Authority = signinAuthority,
            RequireHttpsMetadata = signinHTTPS,

            ClientId = "skybus",
            ClientSecret = "secret",

            ResponseType = "code id_token",
            Scope = { "api1", "offline_access" },

            GetClaimsFromUserInfoEndpoint = true,
            SaveTokens = true
        });
services.AddAuthentication(options => {
            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
        })
            .AddCookie()
            .AddOpenIdConnect(o =>
            {
                o.Authority = signinAuthority;
                o.SignInScheme = "Cookies";
                o.RequireHttpsMetadata = signinHTTPS;
                o.ClientId = "skybus";
                o.ClientSecret = "secret";
                o.ResponseType = "code id_token";
                o.GetClaimsFromUserInfoEndpoint = true;
                o.SaveTokens = true;
                o.Scope.Add("api1");
                o.Scope.Add("offline_access");
            });
在浏览器中,我看到了上述更改后的此URL。它应该显示我的外部登录页面,如果用户没有登录或返回到我的网站主页


我不知道您是否使用IdentityServer4,但他们在github上提供了一些ASP.NET Core 2.0的示例

希望这对你有帮助


您是否使用了身份验证中间件

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseAuthentication();
...
我跟着开始迁移。此链接涵盖了大部分迁移,但我面临的问题是,我的大部分声明都丢失了

使用ASP.NET Core 1.x,客户端将收到声明:nbf、exp、iss、aud、nonce、iat、c_哈希、sid、sub、身份验证时间、idp、amr

在Core2.0中,我们只获得sid、sub和idp。发生了什么事

微软在OpenID连接处理程序中添加了一个新概念,称为Claimations。索赔操作允许修改来自外部提供商的索赔如何映射(或不映射)到ClaimsPrincipal中的索赔。查看OpenIdConnectOptions的ctor,您可以看到处理程序现在默认情况下将跳过以下声明:

ClaimActions.DeleteClaim("nonce");
ClaimActions.DeleteClaim("aud");
ClaimActions.DeleteClaim("azp");
ClaimActions.DeleteClaim("acr");
ClaimActions.DeleteClaim("amr");
ClaimActions.DeleteClaim("iss");
ClaimActions.DeleteClaim("iat");
ClaimActions.DeleteClaim("nbf");
ClaimActions.DeleteClaim("exp");
ClaimActions.DeleteClaim("at_hash");
ClaimActions.DeleteClaim("c_hash");
ClaimActions.DeleteClaim("auth_time");
ClaimActions.DeleteClaim("ipaddr");
ClaimActions.DeleteClaim("platf");
ClaimActions.DeleteClaim("ver");
如果要“取消跳过”索赔,则需要在设置处理程序时删除特定的索赔操作。以下是收回amr索赔的非常直观的语法:

options.ClaimActions.Remove("amr");
向OIDC提供商请求更多索赔

当您请求更多范围时,例如导致更多索赔的概要文件或自定义范围,还有另一个令人困惑的细节需要注意

根据OIDC协议中的响应类型,有些声明通过id令牌传输,有些通过userinfo端点传输

因此,首先,您需要在处理程序中启用对userinfo端点的支持:

options.GetClaimsFromUserInfoEndpoint = true;
最后,您需要添加以下类来导入所有其他自定义声明

public class MapAllClaimsAction : ClaimAction
    {
        public MapAllClaimsAction() : base(string.Empty, string.Empty)
        {
        }

        public override void Run(JObject userData, ClaimsIdentity identity, string issuer)
        {
            foreach (var claim in identity.Claims)
            {
                // If this claimType is mapped by the JwtSeurityTokenHandler, then this property will be set
                var shortClaimTypeName = claim.Properties.ContainsKey(JwtSecurityTokenHandler.ShortClaimTypeProperty) ?
                    claim.Properties[JwtSecurityTokenHandler.ShortClaimTypeProperty] : string.Empty;

                // checking if claim in the identity (generated from id_token) has the same type as a claim retrieved from userinfo endpoint
                JToken value;
                var isClaimIncluded = userData.TryGetValue(claim.Type, out value) || userData.TryGetValue(shortClaimTypeName, out value);

                // if a same claim exists (matching both type and value) both in id_token identity and userinfo response, remove the json entry from the userinfo response
                if (isClaimIncluded && claim.Value.Equals(value.ToString(), StringComparison.Ordinal))
                {
                    if (!userData.Remove(claim.Type))
                    {
                        userData.Remove(shortClaimTypeName);
                    }
                }
            }

            // adding remaining unique claims from userinfo endpoint to the identity
            foreach (var pair in userData)
            {
                JToken value;
                var claimValue = userData.TryGetValue(pair.Key, out value) ? value.ToString() : null;
                identity.AddClaim(new Claim(pair.Key, claimValue, ClaimValueTypes.String, issuer));
            }
        }
    }
然后使用上述类别代码将其添加到
索赔

options.ClaimActions.Add(new MapAllClaimsAction());