为什么要使用Identity Server和asp.net core 2在基于令牌的身份验证上使用cookie

时间:2018-09-11 10:55:45

标签: c# asp.net asp.net-identity asp.net-core-2.0 identityserver4

我正在创建一个示例应用程序,目的只是为了了解身份服务器4身份验证如何与Asp.net core 2一起工作。我注意到有些Cookie是针对不同级别生成的,如所附的屏幕截图所示。我的问题是为什么生成这些cookie?

下面的语句,是从Identity Server文档中获得的。身份服务器配置时

IdentityServer内部使用自定义方案(通过常量IdentityServerConstants.DefaultCookieAuthenticationScheme)调用AddAuthentication和AddCookie,

这为什么它在身份服务器本身上调用AddCookies方法?

当我将Asp.net核心Web客户端配置为使用身份服务器身份验证时,它也会调用AddCookie()方法。当我尝试发表评论时,它会给我一个错误。我不清楚这里发生了什么。

身份服务器配置

services.AddIdentityServer()
                .AddDeveloperSigningCredential()
                .AddToDoUserStore()
                .AddInMemoryIdentityResources(Config.GetIdentityResources())
                .AddInMemoryApiResources(Config.GetApiResources())
                .AddInMemoryClients(Config.GetClients());

            services.AddAuthentication("MyCookie")
            .AddCookie("MyCookie", options =>
            {
                options.ExpireTimeSpan = new System.TimeSpan(0, 0, 15);
            });

Web客户端配置

services.AddAuthentication(options =>
            {
                options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
            })
            .AddCookie()
            .AddOpenIdConnect(options =>
            {
                options.Authority = "https://localhost:44377/";
                options.RequireHttpsMetadata = true;
                options.ClientId = "ToDoTaskManagmentClient";
                options.Scope.Clear();
                options.Scope.Add("openid");
                options.Scope.Add("profile");
                options.Scope.Add("address");
                options.Scope.Add("roles");
                options.Scope.Add("usertodoapi");
                options.Scope.Add("countries");
                options.Scope.Add("subscriptionlevel");
                options.Scope.Add("offline_access");
                options.ResponseType = "code id_token";
                options.SaveTokens = true;
                options.ClientSecret = "secret";
                options.GetClaimsFromUserInfoEndpoint = true;
                options.ClaimActions.Clear();
                options.ClaimActions.MapJsonKey("given_name", "given_name");
                options.ClaimActions.MapJsonKey("family_name", "family_name");
                options.ClaimActions.MapJsonKey("role", "role");
                options.ClaimActions.MapJsonKey("country", "country");
                options.ClaimActions.MapJsonKey("subscriptionlevel", "subscriptionlevel");
                options.Events = new OpenIdConnectEvents()
                {
                    OnTokenValidated = e =>
                    {
                        var identity = e.Principal;
                        var subjectClaim = identity.Claims.FirstOrDefault(z => z.Type == "sub");
                        var expClaims = identity.Claims.FirstOrDefault(z => z.Type == "exp");
                        var newClaimsIdentity = new ClaimsIdentity(e.Scheme.Name);
                        newClaimsIdentity.AddClaim(subjectClaim);
                        newClaimsIdentity.AddClaim(expClaims);

                        e.Principal = new ClaimsPrincipal(newClaimsIdentity);
                        return Task.FromResult(0);
                    },
                    OnUserInformationReceived = e =>
                    {
                        e.User.Remove("address");
                        return Task.FromResult(0);
                    }
                };
            });

enter image description here

2 个答案:

答案 0 :(得分:1)

您的Identity Server应用程序需要身份验证cookie(和会话ID cookie),以便前端通道端点(授权,同意,check_session_iframe以及其他)可以知道用户是否已通过身份验证以及会话的当前状态。没有这个,就不会知道谁在叫它。如果IDS4检测到传入请求未通过身份验证,则IDS4将自动重定向到默认方案的登录URL,然后您可以自由地实施所需的任何身份验证流程。

根据体系结构,您的客户端应用程序可能需要cookie,也可能不需要。传统的服务器端WebForms或MVC风格的应用程序将需要一个,但使用oidc-client-js之类的库的纯JS客户端将不需要,并且可以纯粹使用从身份服务器获取的访问令牌与后端进行通信。

答案 1 :(得分:0)

IdentityServer不执行任何操作。它所做的只是处理低级别的身份验证/授权并返回声明主体。您正在使用IdentityServer的应用程序将设置cookie。

您在这里所做的基本上是让同一服务器托管IdentityServer和基于cookie auth的前端。 Cookie部分用于传统的登录流程UI,因此应用程序可以识别用户是否已通过身份验证,并在用户身份验证时或重定向到用户时重定向到登录表单或帐户页面,或重定向回原始应用程序。

可以完全拆分成一个完全不同的应用程序,然后您的IdentityServer应用程序将不再需要cookie身份验证配置。