【问题标题】:Pass through authentication with ASP Core MVC, Web API and IdentityServer4?通过 ASP Core MVC、Web API 和 IdentityServer4 的身份验证?
【发布时间】:2017-08-25 21:58:15
【问题描述】:

我一直致力于迁移单体 ASP Core MVC 应用程序以使用服务架构设计。 MVC 前端网站使用HttpClient 从 ASP Core Web API 加载必要的数据。前端 MVC 应用程序的一小部分还需要使用 IdentityServer4(与后端 API 集成)进行的身份验证。这一切都很好,直到我将 Authorize 属性放在 Web API 上的控制器或方法上。我知道我需要以某种方式将用户授权从前端传递到后端才能使其正常工作,但我不确定如何。我尝试获取 access_token:User.FindFirst("access_token"),但它返回 null。然后我尝试了这个方法,我能够得到令牌:

var client = new HttpClient("url.com");
var token = HttpContext.Authentication.GetTokenAsync("access_token")?.Result;
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

此方法获取令牌但仍不使用后端 API 进行身份验证。我对这个 OpenId/IdentityServer 概念很陌生,我们将不胜感激!

这里是来自 MVC 客户端启动类的相关代码:

    private void ConfigureAuthentication(IApplicationBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationScheme = "Cookies",
            AutomaticAuthenticate = true,
            ExpireTimeSpan = TimeSpan.FromMinutes(60)
        });
        JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
        app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
        {
            AuthenticationScheme = "oidc",
            SignInScheme = "Cookies",

            Authority = "https://localhost:44348/",
            RequireHttpsMetadata = false,

            ClientId = "clientid",
            ClientSecret = "secret",

            ResponseType = "code id_token",
            Scope = { "openid", "profile" },
            GetClaimsFromUserInfoEndpoint = true,
            AutomaticChallenge = true, // Required to 302 redirect to login
            SaveTokens = true,

            TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
            {
                NameClaimType = "Name",
                RoleClaimType = "Role",
                SaveSigninToken = true
            },


        });
    }

以及 API 的 StartUp 类:

        // Add authentication
        services.AddIdentity<ExtranetUser, IdentityRole>(options =>
        {
            // Password settings
            options.Password.RequireDigit = true;
            options.Password.RequiredLength = 8;
            options.Password.RequireNonAlphanumeric = true;
            options.Password.RequireUppercase = true;
            options.Password.RequireLowercase = true;

            // Lockout settings
            options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
            options.Lockout.MaxFailedAccessAttempts = 10;

            // User settings
            options.User.RequireUniqueEmail = true;
        })
            .AddDefaultTokenProviders();
        services.AddScoped<IUserStore<ExtranetUser>, ExtranetUserStore>();
        services.AddScoped<IRoleStore<IdentityRole>, ExtranetRoleStore>();
        services.AddSingleton<IAuthorizationHandler, AllRolesRequirement.Handler>();
        services.AddSingleton<IAuthorizationHandler, OneRoleRequirement.Handler>();
        services.AddSingleton<IAuthorizationHandler, EditQuestionAuthorizationHandler>();
        services.AddSingleton<IAuthorizationHandler, EditExamAuthorizationHandler>();
        services.AddAuthorization(options =>
        {
            /* ... etc .... */
        });
        var serviceProvider = services.BuildServiceProvider();
        var serviceSettings = serviceProvider.GetService<IOptions<ServiceSettings>>().Value;
        services.AddIdentityServer() // Configures OAuth/IdentityServer framework
            .AddInMemoryIdentityResources(IdentityServerConfig.GetIdentityResources())
            .AddInMemoryClients(IdentityServerConfig.GetClients(serviceSettings))
            .AddAspNetIdentity<ExtranetUser>()
            .AddTemporarySigningCredential(); // ToDo: Add permanent SigningCredential for IdentityServer

【问题讨论】:

    标签: c# asp.net-core openid identityserver4


    【解决方案1】:

    添加了nuget package here 和以下代码进行修复:

    app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
    {
       Authority = "https://localhost:44348/",
       ApiName = "api"
    });
    

    这允许 API 托管 IdentityServer4 并将其自身用作身份验证。然后在 MvcClient 中,可以将不记名令牌传递给 API。

    【讨论】:

    • 如何从已经通过身份验证的 mvc 视图中获取 javascript 中的不记名令牌?
    【解决方案2】:

    是的,您需要将 IdentityServer4.AccessTokenValidation 包添加到您的 API 项目中。并检查下面的 cmets

    app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
    {
       Authority = "https://localhost:44348/", //Identity server host uri
       ApiName = "api", // Valid Api resource name 
       AllowedScopes = scopes // scopes:List<string> 
    });
    

    您应该从 API 的 StartUp 类中删除下面的代码并替换为上面的

     services.AddIdentityServer() // Configures OAuth/IdentityServer framework
                .AddInMemoryIdentityResources(IdentityServerConfig.GetIdentityResources())
                .AddInMemoryClients(IdentityServerConfig.GetClients(serviceSettings))
                .AddAspNetIdentity<ExtranetUser>()
                .AddTemporarySigningCredential();
    

    您的身份服务器上需要上述代码,而不是 API 或任何其他客户端上

    【讨论】:

      猜你喜欢
      • 2019-05-11
      • 1970-01-01
      • 2020-10-15
      • 2017-11-24
      • 2016-07-03
      • 2021-08-27
      • 2016-12-22
      • 1970-01-01
      • 2014-04-29
      相关资源
      最近更新 更多