本文介绍了IdentityServer用作另一个IdentityServer的外部身份提供程序时,无法正确重定向的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

登录并同意后使用任何标准身份提供者(Google,Facebook)时,它们都会重定向到我的主Identity Server,并使其重定向到其中注册的隐式客户端.如何使用充当外部身份提供者的另一台Identity Server来实现相同的行为?

When using any of the standard identity providers (Google, Facebook) after logging in and consent they redirect to my primary Identity Server and let it redirect to implicit client registered within it. How can I achieve the same behavior with another Identity Server serving as external identity provider?

我的安全体系结构由两个Identity Server组成,主要的一个(v3)使用另一个(v4)作为外部身份提供程序.隐式客户端使用主IdentityServer打开一个弹出窗口.

My security architecture consists of two Identity Servers, primary one (v3) using the other (v4) as an external identity provider. The implicit client opens a popup with primary IdentityServer.

我无法遵循以下流程:

充当外部IdP的身份服务器卡在端点上:

Identity Server acting as external IdP gets stuck on endpoint:

/connect/authorize/login?client_id=primaryIdentityServer&redirect_uri=https://primaryIdentityServer.example.com/signin-oidc&response_mode=form_post&response_type=code id_token&scope=openid profile email

出现错误消息:

Refused to send form data to 'https://jsclient.example.com/#(...)' because it violates the following Content Security Policy directive: "form-action https://primaryIdentityServer.example.com".

外部身份提供者的主要IdentityServer配置:

Primary IdentityServer configuration for external identity provider:

var opts = new OpenIdConnectAuthenticationOptions {
    ClientId = "primaryServer",
    ClientSecret = "secret",
    RedirectUri = "https://primaryIdentityServer.example.com/signin-oidc",
    Authority = "https://externalIdPIdentityServer.example.com",
    ResponseType = "code id_token",
    Scope = "openid profile email",
    SignInAsAuthenticationType = signInAsType
};

app.UseOpenIdConnectAuthentication(opts);

在IdentityServer中注册的IdentityServer主服务器,用作外部IDP:

IdentityServer primary registered within IdentityServer serving as external IdP:

new Client
{
    ClientId = "primaryServer",
    AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
    RedirectUris = new List<string>
    {
        "https://primaryIdentityServer.example.com/signin-oidc"
    },
    ClientSecrets = 
    {
        new Secret("secret".Sha256())
    },

    AllowedScopes =
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile,
        IdentityServerConstants.StandardScopes.Email
    },
    AlwaysIncludeUserClaimsInIdToken = true
}

编辑:当我尝试在/permissions端点上检查我的应用权限并使用外部IdentityServer进行身份验证时,我注意到了,我被重定向到权限端点,没有任何问题.

I noticed when I try to check my app permissions on /permissions endpoint and authenticate using external IdentityServer I'm redirected to permission endpoint without any issues.

编辑:我尝试过切换到Identity Server之间的隐式流.从response_type中删除了秘密,code,并将隐式设置为允许的授予类型,并且在将发布数据发送到我的js客户端时,我仍然收到相同的错误,因此似乎选择的流(混合或隐式)与该问题无关.

I've tried switching to implicit flow between Identity Servers. Removed secrets, code from response_type and set implicit as allowed grant type and I still receive the same error with sending post data to my js client so it seems that selected flow (hybrid or implicit) is irrelevant for this issue.

编辑:我已经检查了认证过程所卡在的端点的来源:

I've checked the source of the endpoint on which the authentication process is stuck:

<form method='post' action='https://primaryIdentityServer.example.com/signin-oidc'><input type='hidden' name='id_token' value='{token}' />
<input type='hidden' name='access_token' value='{token}' />
<input type='hidden' name='token_type' value='Bearer' />
<input type='hidden' name='expires_in' value='3600' />
<input type='hidden' name='scope' value='openid profile' />
<input type='hidden' name='state' value='OpenIdConnect.AuthenticationProperties={props}' />
<input type='hidden' name='session_state' value='{state}' />
</form><script>(function(){document.forms[0].submit();})();</script>

具有查询参数:https://externalIdPIdentityServer.example.com/connect/authorize/consent?client_id=primaryServer&redirect_uri=https://primaryIdentityServer.example.com/signin-oidc&response_mode=form_post&response_type=token id_token&scope=openid profile&state={state}&nonce={nonce}

所以错误很奇怪:

Refused to send form data to 'https://jsclient.example.com/#(...)' because it violates the following Content Security Policy directive: "form-action https://primaryIdentityServer.example.com".

因为在任何地方都没有提到jsclient.example.com.

since jsclient.example.com isn't mentioned anywhere.

编辑:问题仅出现在Chrome中,而不出现在Firefox或IE Edge中.

Issue appears only in Chrome, not in Firefox or IE Edge.

推荐答案

我已经开始在IdentityServer4问题中搜索"chrome"和"csp"关键字,并找到了以下一个关键字:"> https://github.com/IdentityServer/IdentityServer4/issues/659

I've started searching for "chrome" and "csp" keywords in IdentityServer4 issues and found this one: https://github.com/IdentityServer/IdentityServer4/issues/659

结果证明,需要更改授权响应上的表单操作CSP,并且1.0.1版中的IdentityServer4版本已放宽了此策略指令.

Turns out that form-action CSP on authorize response needed to be changed and IdentityServer4 versions from 1.0.1 have this policy directive relaxed.

我将IdentityServer4从1.0.0更新到1.0.2,它解决了这个问题.

I updated IdentityServer4 from 1.0.0 to 1.0.2 and it solved the problem.

这篇关于IdentityServer用作另一个IdentityServer的外部身份提供程序时,无法正确重定向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-21 02:58