为了账号安全,请及时绑定邮箱和手机立即绑定

使用 IdentityServer4 从单个客户端接受承载身份验证和 OpenIdConnect

使用 IdentityServer4 从单个客户端接受承载身份验证和 OpenIdConnect

C#
泛舟湖上清波郎朗 2022-10-15 15:16:42
在对IdentityServer4 Quickstart 示例解决方案(特别是 8_AspNetIdentity 示例)进行一些调整后,我遇到了一些问题。我会先说我不确定我正在尝试做的事情是否不受支持,或者我做错了。此示例解决方案包含与我的问题相关的以下项目:一个身份服务器,一个使用 OpenIdConnect 对其用户进行身份验证的 MVC 客户端(名为 MVCClient),对其用户使用不记名身份验证的 Web API 客户端(名为 API)设计为 API 客户端的控制台应用程序(名为 ResourceOwnerClient)我正在尝试做的是将 API 项目合并到 MVCClient 中,以便 MVCClient 既可以使用 OIDC 对来自其 MVC 网站的用户进行身份验证,也可以使用承载身份验证对 ResourceOwnerClient 进行身份验证。我对 MVCClient 的 Startup.cs 进行了以下更改:改为services.AddMvc();:services.AddMvc(config =>{    var policy = new AuthorizationPolicyBuilder(new[]        {            JwtBearerDefaults.AuthenticationScheme,            CookieAuthenticationDefaults.AuthenticationScheme,            "oidc"        })        .RequireAuthenticatedUser()        .Build();    config.Filters.Add(new AuthorizeFilter(policy));});将 JWT 不记名选项添加到services.AddAuthentication():.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>{    options.Authority = "http://localhost:5000";    options.RequireHttpsMetadata = false;    options.Audience = "api1";})现在从技术上讲,这确实有效,因为 ResourceOwnerClient 和 MVC 用户都可以成功地通过 MVCClient 进行身份验证。然而,我有一个警告:当我从 MVC 端对用户进行身份验证时,我注意到我当前的用户中有两个身份。两者在声明等方面都是相同的。这只发生在我在 MVCClient 中设置断点时,在 IdentityServer 上只有一个身份。在 IdentityServer 上,我注册了一个 UserClaimsPrincipalFactory,它将我自己的自定义声明添加到 ClaimsIdentity。在 IdentityServer 上的两个身份中,我可以看到重复的声明。因此,我看到的不是一个身份和两个自定义声明,而是两个身份,每个身份都有 4 个自定义声明。我的 UserClaimsPrincipalFactory 中的 CreateAsync 方法也被单次登录击中 5 次。虽然这种行为很奇怪,但它似乎没有任何负面影响。但这只是我正在构建的更大应用程序的概念证明,我担心我将来可能会因此遇到问题。如果有人以前尝试过这种事情,或者知道为什么会发生这种行为,我们将不胜感激。
查看完整描述

1 回答

?
素胚勾勒不出你

TA贡献1827条经验 获得超9个赞

虽然这种设计不会发生任何不好的事情,但我会完全改造它。为什么?因为您正在混合 aClient和 an ApiResource,它们应该在逻辑上分开。AClient是一个应用程序,一些用户与之交互的东西,即使它是一个无头的应用程序(即自动化服务);而 anApiResource由提供给 Clients 的资源组成,因此没有用户可以直接与其交互。


您可以针对 IdentityServer 添加两种身份验证,一种作为 API(并将其添加为JwtBearer),另一种作为客户端(并将其添加为Cookies)。然后,您可以根据该动作/控制器的功能使用[Authorize(AuthenticationSchemes = "JwtBearer")]和。= "Cookies"


撇开这一点不谈,问题是您的应用程序正在为 MVC 端获取一个身份,而为 API 端获取一个身份,因为它无法告诉您想要哪个身份。


只要你有一个想法,这就是我的一个带有 ASP.NET Core Identtiy 的 IdentityServer 的样子,你可以使用 UI 登录它,还可以使用 JwtToken 访问 REST 端点:


services

    .AddAuthentication(options =>

    {

        options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;

        options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;

        options.DefaultSignInScheme = IdentityConstants.ExternalScheme;

    })

    .AddIdentityServerAuthentication(JwtBearerDefaults.AuthenticationScheme, options =>

    {

        options.Authority = Configuration["IdentityServerUrl"];

        options.ApiName = Configuration["ApiName"];


        options.RequireHttpsMetadata = false;

    })

    .AddCookie(IdentityConstants.ApplicationScheme, o =>

    {

        o.LoginPath = new PathString("/Account/Login");

        o.Events = new CookieAuthenticationEvents()

        {

            OnValidatePrincipal = SecurityStampValidator.ValidatePrincipalAsync

        };

    })

    .AddCookie(IdentityConstants.ExternalScheme, o =>

    {

        o.Cookie.Name = IdentityConstants.ExternalScheme;

        o.ExpireTimeSpan = TimeSpan.FromMinutes(5.0);

    })

    .AddCookie(IdentityConstants.TwoFactorRememberMeScheme, o =>

    {

        o.Cookie.Name = IdentityConstants.TwoFactorRememberMeScheme;

    })

    .AddCookie(IdentityConstants.TwoFactorUserIdScheme, o =>

    {

        o.Cookie.Name = IdentityConstants.TwoFactorUserIdScheme;

        o.ExpireTimeSpan = TimeSpan.FromMinutes(5.0);

    });


查看完整回答
反对 回复 2022-10-15
  • 1 回答
  • 0 关注
  • 136 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号