【发布时间】:2017-06-10 19:27:48
【问题描述】:
在登录并同意后使用任何标准身份提供者(Google、Facebook)时,它们会重定向到我的主身份服务器,并让它重定向到其中注册的隐式客户端。如何使用另一个身份服务器作为外部身份提供者实现相同的行为?
我的安全架构由两个身份服务器组成,主要的一个 (v3) 使用另一个 (v4) 作为外部身份提供者。隐式客户端打开一个带有主 IdentityServer 的弹出窗口。
以下流程有问题:
充当外部 IdP 的身份服务器卡在端点上:
/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 配置:
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:
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 进行身份验证时,我被重定向到权限端点,没有任何问题。
编辑:我尝试切换到身份服务器之间的隐式流。从 response_type 中删除了秘密 code 并将隐式设置为允许的授权类型,但在将发布数据发送到我的 js 客户端时仍然收到相同的错误,因此似乎所选流(混合或隐式)与此问题无关。
编辑:我已经检查了身份验证过程卡住的端点的来源:
<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。
编辑:问题仅出现在 Chrome 中,而不出现在 Firefox 或 IE Edge 中。
【问题讨论】:
-
似乎您正在重定向回 JavaScript 客户端应用程序,而不是重定向回主身份服务器。内容安全策略中提到了这一点,它允许外部身份提供者仅向主要身份提供者发布,因为它可能已经在客户端重定向 URL 处发送了重定向 URL,这可能是问题所在。 HTH
-
是的,我也得出了同样的结论。但我不明白为什么会这样。因为两个 IdentityServer 都只添加了主要的 url 作为有效的 redirect_url。我希望他们会在他们自己之间交换请求,并让主要的请求重定向到我的隐式 js 客户端。我希望行为更符合谷歌或 Facebook 的做法。您在那里注册您的 IdentityServer,提供重定向 url 并获取客户端 ID 和密钥 :)
-
在某个 idsvr 的某处有一个样本充当另一个 idsvr 的外部提供者? ty
标签: c# identityserver3 openid-connect identityserver4