登录后,Identity Server 4不会重定向到Angular应用程序

拉斯·马苏德(Raas Masood)

我在用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
};

在Identity Server中,我正在使用 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

Startup.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年3月7日01:19:32.069-06:00 [DBG]调用自定义验证器:IdentityServer4.Validation.DefaultCustomAuthorizeRequestValidator 2019年3月7日01:19:32.099-06:00 [INF] ValidatedAuthorizeRequest {“ ClientId”: “ angular_spa”,“ ClientName”:“ Angular 4 Client”,“ RedirectUri”:“ http:// localhost:4200 / auth-callback ”,“ AllowedRedirectUris”:[“ http:// localhost:4200 / auth-callback ” ,“ http:// localhost:4200 / silent-refresh.html“],” SubjectId“:”匿名“,” ResponseType“:” id_token令牌“,” ResponseMode“:”片段“,” GrantType“:”隐式“,” RequestedScopes“:” openid配置文件api1“,”状态“: “ cd6df66e397546d3aab62533de28a2d2”,“ UiLocales”:null,“ Nonce”:“ 8b3af6331d784e9a9cad076555f16174”,“ AuthenticationContextReferenceClasses”:null,“ DisplayMode”:null,“ PromptMode”:null,“ MaxAgeH”:null,“ Login “:null,” Raw“:{” client_id“:” angular_spa“,” redirect_uri“:” http:// localhost:4200 / auth-callback844-06:00 [INF] idsrv未通过身份验证。故障消息:取消保护票证失败2019-03-07 01:19:41.517-06:00 [INF] AuthenticationScheme:Identity.Application已登录。2019-03-07 07:19:41.518-06:00 [INF]用户登录了。2019-03-07 01:19:41.528-06:00 [INF] idsrv未通过身份验证。失败消息:Unprotect票证失败2019-03-07 01:19:41.528-06:00 [INF] idsrv未通过身份验证。失败消息:取消保护票证失败2019-03-07 01:19:41.528-06:00 [DBG]请求路径/连接/授权/回调与端点类型匹配授权2019-03-03-07: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-03-07:19:41.541-06:00 [DBG]开始授权请求协议验证2019-03-07 01:19:41.541-06:00客户端angular_spa的[DBG]客户端配置验证成功。2019年3月7日01:19:41.541-06:00 [DBG]调用自定义验证器:IdentityServer4.Validation.DefaultCustomAuthorizeRequestValidator 2019年3月7日01:19:41.541-06:00 [INF] ValidatedAuthorizeRequest {“ ClientId”: “ angular_spa”,“ ClientName”:“ Angular 4 Client”,“http:// localhost:4200 / auth-callback “,” AllowedRedirectUris“:[” http:// localhost:4200 / auth-callback “,” http:// localhost:4200 / silent-refresh.html “],” SubjectId”:“匿名”,“ ResponseType”:“ id_token令牌”,“ ResponseMode”:“片段”,“ GrantType”:“隐式”,“ RequestedScopes”:“ openid个人资料api1”,“ State”:“ cd6df66e397546d3aab62533de28a2d2”, “ UiLocales”:空,“ Nonce”:“ 8b3af6331d784e9a9cad076555f16174”,“ AuthenticationContextReferenceClasses”:空,“ DisplayMode”:空,“ PromptMode”:空,“ MaxAge”:空,“ LoginHint”:空,“ SessionId”:空,“ Raw”:{“ client_id”:“ angular_spa”,“ redirect_uri”:“ http:// localhost:4200 / auth-callback“,” response_type“:” id_token令牌“,” scope“:” openid个人资料api1“,” state“:” cd6df66e397546d3aab62533de28a2d2“,” nonce“:” 8b3af6331d784e9a9cad076555f16174“}},” $ type“:”验证请求“ -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未通过身份验证。失败消息:Unprotect票证失败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
};
    }
}

我的项目结构如下所示

在此处输入图片说明

it doesn't have any controllers. Should it have ?

UPDATE 2 looks like i figured out whats wrong.

The returnUrl is not resolving properly on the POST method. it is coming as the complete URL. if i force it to a proper return URL it works

在此处输入图片说明

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

I did as above and used variable 'redirect_uri' in Redirect function. it works but it looks like a hack. Should it automatically get the right thing ?

with this i get 'No state in response' error on Angular side and oidc-client have no user after redirect.

UPDATE

Looks like I'm using some different nuget package. HttpContext.SignInAsync has following constructors.

My HttpContext seems to be defined in

Microsoft.AspNetCore.Mvc.RazorPages

looks like i have wrong Nugets or something. i am trying to supply a proper ClaimsPrincipal as well but not working.

在此处输入图片说明

Randy

I see there's a bit of confusion concerning the difference between the returnUrl and the redirect_uri. Although the end goal is a redirect to the client's redirect_uri, after authentication the client must actually redirect to the authorize endpoint for further processing (hence the reason why the url is different). You shouldn't need to change the returnUrl at all and can leave it the way it was.

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

注销后重定向到登录(Identity Server 3)

托管在iss中后,客户端应用程序未重定向到Identity Server 4

登录后FBSDKGraphRequest不会重定向到应用程序

如何重定向到另一个应用程序 Single Sign On Identity Server 4 并注销

Identity Server4用户登录后选择帐户

Identityserver4 登录后不重定向到 xamarin.forms android 应用程序

Facebook浏览器登录重定向到应用程序后,处理程序不会被调用

手动将MVC操作重定向到Identity Server 4登录页面

反向代理后面的应用程序的Identity Server重定向URL

如何通过桌面/移动应用程序使用Identity Server 4登录

Angular OpenID:在浏览器中加载应用程序之前重定向到登录

带有docker-compose的Identity Server 4在/ connect / authorize / callback之后重定向到登录页面

.NET 应用程序重定向到登录页面

在React Redux应用程序上登录后重定向到首页

注册后如何使React应用程序重定向到登录页面?

将外部登录令牌从Identity Server流到客户端应用程序

在Spring应用程序中使用onAuthenticationSuccess将用户重定向到登录页面后的原始URL

在Chrome中选择“在新标签页中打开链接”选项时,应用程序路由重定向到Angular应用程序中的登录

在WSO2 Identity Server中启用一次注销,然后重定向到自定义登录页面

将Apache Server文档根目录重定向到SpringBoot应用程序

登录Identity Server 4-.Net Core 2.2

Identity Server 4中的自定义登录视图

将参数传递给Identity Server 4登录页面

Identity Server 4登录现有数据库

如何使Angular Client通知Identity Server使用哪种登录方法?

Active Directory登录后,ASP.NET MVC应用程序重定向到本地主机而不是应用程序URI

用户未登录应用程序时如何重定向到登录页面

当会话在Java Web应用程序中过期时,如何重定向到登录页面?

尝试附加到 div 时,Asp.net MVC 应用程序重定向到登录