2

我正在使用oidc-client角度。按照本教程

import { UserManager, UserManagerSettings, User } from 'oidc-client';

我的客户:

export function getClientSettings(): UserManagerSettings {
return {
authority: 'https://localhost:44305/',
client_id: 'angular_spa',
redirect_uri: 'http://localhost:4200/auth-callback',
post_logout_redirect_uri: 'http://localhost:4200/',
response_type: 'id_token token',
scope: 'openid profile api1',
filterProtocolClaims: true,
loadUserInfo: true,
automaticSilentRenew: false
};

在身份服务器中我正在使用Assembly Microsoft.AspNetCore.Identity.UI, Version=2.1.3.0

我正在添加这样的默认身份:

[assembly: 
HostingStartup(typeof(WebApp.Areas.Identity.IdentityHostingStartup))]
namespace WebApp.Areas.Identity 
{
   public class IdentityHostingStartup: IHostingStartup {
     public void Configure(IWebHostBuilder builder) {
       builder.ConfigureServices((context, services) => {
         services.AddDbContext < WebAppContext > (options =>
             options.UseSqlite(context.Configuration.GetConnectionString("WebAppContextConnection")));

         services.AddDefaultIdentity < WebAppUser > ()
            .AddEntityFrameworkStores < WebAppContext > ();
     });
    }
  }
}

WebAppUser来源于IdentityUser

启动.cs:

public class Startup
{

    private ILogger<DefaultCorsPolicyService> _logger;
    private IHostingEnvironment _env;

    public Startup(ILoggerFactory loggerFactory, IHostingEnvironment env)
    {
        _logger = loggerFactory.CreateLogger<DefaultCorsPolicyService>();
        _env = env;
    }
    private static void SetupIdentityServer(IdentityServerOptions identityServerOptions)
    {
        identityServerOptions.UserInteraction.LoginUrl = new PathString("/Identity/Account/Login");
        //  identityServerOptions.Cors.CorsPolicyName = "CorsPolicy";
    }
    public void ConfigureServices(IServiceCollection services)
    {

        services.AddCors(o => o.AddPolicy("CorsPolicy", builder =>
        {
            builder
             .WithOrigins("https://localhost:44305")
            .AllowAnyOrigin()
                   .AllowAnyMethod()
                   .AllowAnyHeader();
        }));

        //  services.AddMvc();
        var cors = new DefaultCorsPolicyService(_logger)
        {
            AllowAll = true
        };

        var cert = new X509Certificate2(Path.Combine(_env.ContentRootPath, "mycert.pfx"), "xxxxx");
        services.AddIdentityServer(SetupIdentityServer)//SetupIdentityServer
                 .AddSigningCredential(cert)
                 .AddInMemoryApiResources(Config.GetApiResources())
                 .AddInMemoryClients(Config.GetClients())
                 // .AddTestUsers(TestUsers.Users)
                 .AddInMemoryIdentityResources(Config.GetIdentityResources());
                 services.AddSingleton<ICorsPolicyService>(cors);

    }
    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        //loggerFactory.AddConsole();
        app.UseDeveloperExceptionPage();

        app.Map("/api", api =>
        {
            api.UseCors(x => x.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin());
            api.UseAuthentication();

            api.Run(async context =>
            {
                var result = await context.AuthenticateAsync("api");
                if (!result.Succeeded)
                {
                    context.Response.StatusCode = 401;
                    return;
                }

                context.Response.ContentType = "application/json";
                await context.Response.WriteAsync(JsonConvert.SerializeObject("API Response!"));
            });
        });

        app.UseIdentityServer();

        app.UseStaticFiles();
        app.UseMvcWithDefaultRoute();

        //Run these PMC commands after this.
        //Add - Migration CreateIdentitySchema
        //Update - Database

    }
}

在身份服务器 4 中,我启用了https. 所以问题是,如果我尝试使用受保护的 Angular 应用程序,我将URL导航到身份服务登录页面。看起来它正在对数据库中的用户进行正确的身份验证。但它只是刷新登录页面而不重定向到回调URL

这里有一些日志可能会有所帮助

2019 - 03 - 07 01: 19: 30.553 - 06: 00[INF] 开始 IdentityServer4 版本 2.3 .2 .0 2019 - 03 - 07 01: 19: 30.632 - 06: 00[INF] 您正在使用内存中的版本的持久授权存储。这将仅在内存中存储同意决策、授权代码、刷新和引用令牌。如果您在生产中使用这些功能中的任何一个,您希望切换到不同的存储实现。2019 - 03 - 07 01: 19: 30.643 - 06: 00 [INF] 使用 IdentityServer 的默认身份验证方案 idsrv 2019 - 03 - 07 01: 19: 30.644 - 06: 00 [DBG] 使用 idsrv 作为默认 ASP.NET Core身份验证方案 2019 - 03 - 07 01: 19: 30.644 - 06: 00 [DBG] 使用 Identity.External 作为默认 ASP.NET Core 方案进行登录 2019 - 03 - 07 01: 19: 30.645 - 06: 00 [ DBG] 使用 Identity.External 作为默认 ASP。授权请求中没有用户 2019 - 03 - 07 01: 19: 31.945 - 06: 00[DBG] 开始授权请求协议验证 2019 - 03 - 07 01: 19: 31.983 - 06: 00[DBG] 客户端的客户端配置验证angular_spa 成功了。2019 - 03 - 07 01: 19: 32.069 - 06: 00 [DBG] 调用自定义验证器:IdentityServer4.Validation.DefaultCustomAuthorizeRequestValidator 2019 - 03 - 07 01: 19: 32.099 - 06: 00 [INF] ValidatedAuthorizeRequest {“ClientId”: “angular_spa”、“ClientName”:“Angular 4 客户端”、“RedirectUri”:“ http://localhost:4200/auth-callback ”、“AllowedRedirectUris”:[“ http://localhost:4200/auth-callback ” , " http://localhost:4200/silent-refresh.html"], "SubjectId": "anonymous", "ResponseType": "id_token token", "ResponseMode": "fragment", "GrantType": "implicit", "RequestedScopes": "openid profile api1", "State": “cd6df66e397546d3aab62533de28a2d2”,“UiLocales”:null,“Nonce”:“8b3af6331d784e9a9cad076555f16174”,“AuthenticationContextReferenceClasses”:null,“DisplayMode”:null,“PromptMode”:null,“MaxAge”:null,“LoginHint”:null,“SessionId” ": null, "Raw": { "client_id": "angular_spa", "redirect_uri": " http://localhost:4200/auth-callback取消保护票证失败 2019 - 03 - 07 01: 19: 40.844 - 06: 00[INF] idsrv 未通过身份验证。失败消息:取消保护票证失败 2019 - 03 - 07 01: 19: 41.517 - 06: 00[INF] AuthenticationScheme: Identity.Application 已登录。2019 - 03 - 07 01: 19: 41.518 - 06: 00[INF] 用户登录。2019 - 03 - 07 01: 19: 41.528 - 06: 00 [INF] idsrv 未通过身份验证。失败消息:取消保护票证失败 2019 - 03 - 07 01: 19: 41.528 - 06: 00 [INF] idsrv 未通过身份验证。失败消息:取消保护票证失败 2019 - 03 - 07 01: 19: 41.528 - 06: 00 [DBG] 请求路径/连接/授权/回调匹配到端点类型授权 2019 - 03 - 07 01: 19: 41.529 - 06: 00 [DBG] 端点启用:授权,成功创建处理程序:IdentityServer4.Endpoints.AuthorizeCallbackEndpoint 2019 - 03 - 07 01: 19: 41.529 - 06: 00[INF] 调用 IdentityServer 端点:IdentityServer4.Endpoints.AuthorizeCallbackEndpoint 用于/连接/授权/回调 2019 - 03 - 07 01: 19: 41.535 - 06: 00 [DBG] 开始授权回调请求 2019 - 03 - 07 01: 19: 41.536 - 06: 00 [INF] idsrv 未通过身份验证。失败消息:取消保护票证失败 2019 - 03 - 07 01: 19: 41.541 - 06: 00 [DBG] 授权请求中没有用户存在 2019 - 03 - 07 01: 19 : 41.541 - 06: 00 [DBG] 开始授权请求协议验证 2019 - 03 - 07 01: 19: 41.541 - 06: 00 [DBG] 客户端 angular_spa 的客户端配置验证成功。2019 - 03 - 07 01: 19: 41.541 - 06: 00 [DBG] 调用自定义验证器:IdentityServer4.Validation.DefaultCustomAuthorizeRequestValidator 2019 - 03 - 07 01: 19: 41.541 - 06: 00 [INF] ValidatedAuthorizeRequest {“ClientId”:http://localhost:4200/auth-callback ", "AllowedRedirectUris": [" http://localhost:4200/auth-callback ", " http://localhost:4200/silent-refresh.html "], " SubjectId”:“anonymous”,“ResponseType”:“id_token token”,“ResponseMode”:“fragment”,“GrantType”:“implicit”,“RequestedScopes”:“openid profile api1”,“State”:“cd6df66e397546d3aab62533de28a2d2”, “UiLocales”:null,“Nonce”:“8b3af6331d784e9a9cad076555f16174”,“AuthenticationContextReferenceClasses”:null,“DisplayMode”:null,“PromptMode”:null,“MaxAge”:null,“LoginHint": null, "SessionId": null, "Raw": { "client_id": "angular_spa", "redirect_uri": " http://localhost:4200/auth-callback”,“response_type”:“id_token token”,“scope”:“openid profile api1”,“state”:“cd6df66e397546d3aab62533de28a2d2”,“nonce”:“8b3af6331d784e9a9cad076555f16174”},“$type”:“AuthorizeRequestValidationLog”} 2019 - 07 01: 19: 41.541 - 06: 00 [INF] 显示登录:用户未通过身份验证 2019 - 03 - 07 01: 19: 41.552 - 06: 00 [INF] idsrv 未通过身份验证。失败消息:取消保护票证失败 2019 - 03 - 07 01: 19: 41.553 - 06: 00 [INF] idsrv 未通过身份验证。失败消息:取消保护票证失败 2019 - 03 - 07 01: 19: 41.553 - 06: 00 [INF] AuthenticationScheme: Identity.External 签名出去。

抱歉,我尝试正确格式化日志,但没有奏效。

更新

我的服务器端配置看起来像这样

 public class Config
{
    public static IEnumerable<ApiResource> GetApiResources()
    {
        return new List<ApiResource>
{
    new ApiResource("api1", "My API")
};
    }

    public static IEnumerable<Client> GetClients()
    {
        return new List<Client>
{
    new Client
    {

        ClientSecrets =
        {
            new Secret("superSecretPassword".Sha256())
        },


            ClientId = "angular_spa",
            ClientName = "Angular 4 Client",
            AllowedGrantTypes = GrantTypes.ImplicitAndClientCredentials ,  //implicit
            AllowedScopes = new List<string> { "openid", "profile", "userInfo", "api1" },

            //AllowedScopes = new List<string> { StandardScopes.OpenId, StandardScopes.Profile, StandardScopes.Email },
     RedirectUris = new List<string> {"http://localhost:4200/auth-callback", "http://localhost:4200/silent-refresh.html"},
            PostLogoutRedirectUris = new List<string> { "http://localhost:4200/" },
            AllowedCorsOrigins = new List<string> { "http://localhost:4200" },
            AllowAccessTokensViaBrowser = true,
            Enabled = true,
            AllowOfflineAccess = true
    }
};
    }
    public static List<IdentityResource> GetIdentityResources()
    {
        return new List<IdentityResource>
{
    new IdentityResources.OpenId(),
    new IdentityResources.Profile() // <-- usefull
};
    }
}

我的项目结构看起来像这样

在此处输入图像描述

它没有任何控制器。应该有吗?

更新 2 看起来我想出了什么问题。

returnUrl方法没有正确解决POST。它是完整的URL。如果我强迫它正确返回URL它会起作用

在此处输入图像描述

           var redirect_uri =  HttpUtility.ParseQueryString(returnUrl).Get("redirect_uri");

我按照上面的方法做了,并在重定向函数中使用了变量'redirect_uri'。它有效,但它看起来像一个黑客。它应该自动得到正确的东西吗?

有了这个,我在 Angular 端收到“无响应状态”错误,oidc-client重定向后没有用户。

更新

看起来我正在使用一些不同的nuget包。 HttpContext.SignInAsync有以下构造函数。

我的HttpContext似乎被定义在

Microsoft.AspNetCore.Mvc.RazorPages

看起来我有错误的 Nugets 或其他东西。我也在尝试提供适当的 ClaimsPrincipal 但不工作。

在此处输入图像描述

4

2 回答 2

1

我看到关于 returnUrl 和 redirect_uri 之间的区别有点混乱。尽管最终目标是重定向到客户端的 redirect_uri,但在身份验证之后,客户端实际上必须重定向到授权端点以进行进一步处理(因此 url 不同的原因)。您根本不需要更改 returnUrl 并且可以保持原样。

您现在面临的问题是您在HttpContext.SignInAsync成功验证后没有调用。该SignInAsync方法用于管理带有用户信息的 cookie,该信息在 returnUrl 处告诉端点用户已成功通过身份验证,并且可以将令牌返回到 redirect_uri。有很多重载SignInAsync,但我发现最容易使用的是HttpContext.SignInAsync(string subject, params Claim[] claims). 完成此操作后,您应该能够完成身份验证。

于 2019-03-10T13:55:40.963 回答
-1

身份服务器配置

将 RedirectUris 设置为您的 Angular 应用程序托管 url。

角应用

openIDImplicitFlowConfiguration.redirect_url = this.oidcConfigService.clientConfiguration.redirect_url;

于 2019-03-12T10:25:38.817 回答