Oauth 2.0 如何在现有登录屏幕和受信任的第二个网站上应用SSO

Oauth 2.0 如何在现有登录屏幕和受信任的第二个网站上应用SSO,oauth-2.0,single-sign-on,identityserver3,openid-connect,Oauth 2.0,Single Sign On,Identityserver3,Openid Connect,我们使用IdentityServer3(IdSvr3)进行授权/身份验证。我们想让我们的最终用户(或资源所有者:RO)能够在登录到初始网站(站点a)后,在不登录站点B的情况下登录(通过)第二个受信任的网站(站点B)。站点B为RO管理一组不同的资源。重要的是,RO不会重定向到IdSvr3登录/同意屏幕。到目前为止,我发现的一种可能的方法是:在站点内部,通过调用RequestResourceOwnerPasswordAsync(传递用户名和密码加上scope=“openid…”)创建一个访问令牌。该

我们使用IdentityServer3(IdSvr3)进行授权/身份验证。我们想让我们的最终用户(或资源所有者:RO)能够在登录到初始网站(站点a)后,在不登录站点B的情况下登录(通过)第二个受信任的网站(站点B)。站点B为RO管理一组不同的资源。重要的是,RO不会重定向到IdSvr3登录/同意屏幕。到目前为止,我发现的一种可能的方法是:在站点内部,通过调用RequestResourceOwnerPasswordAsync(传递用户名和密码加上scope=“openid…”)创建一个访问令牌。该访问令牌被发送到站点B,可通过该站点对RO进行身份验证。站点B通过调用connect/userinfo端点来检索用户信息。我想知道这是否是正确的方法/流程。我们假设RO总是首先进入站点A,而不是站点B。
提前感谢您花时间与我一起思考这个问题。

您可以在这里向identity server发送站点B范围的授权请求,并请求id\u令牌或参考令牌。确保在向idsrv发送授权请求时,您使用的是prompt=none,这样,如果用户已登录到站点a,您将获得访问令牌,而无需再次向用户显示同意。 下面的示例从JS文件执行相同的操作。在站点A中,您可以引用此脚本文件并使用IIFE执行脚本

 function getIdentityServerURL() {
    var url = global.appSettings.identityServerURL
                        + "/connect/authorize?client_id=siteB&response_type=id_token token&redirect_uri="
                        + global.appSettings.siteBUrl + "/Main/SsoCallback&scope=siteBscope openid email roles&prompt=none&nonce="
                        + genNonce();
    return encodeURI(url);
}
上面的代码将把您重定向到SsoCallback页面,在那里您可以创建一个虚拟iframe,并在减少授权请求的结果后将令牌发布回站点B。请参阅下面的代码

<script type="text/javascript">
var identityresult = window.location.hash.split('&').reduce(function (result, item) {
    var parts = item.split('=');
    result[parts[0]] = parts[1];
    return result;
}, {});

window.parent.postMessage(identityresult, '*');

var identityresult=window.location.hash.split('&').reduce(函数(结果,项){
var parts=item.split('=');
结果[部分[0]]=部分[1];
返回结果;
}, {});
window.parent.postMessage(identityresult,'*');


您的脚本可以侦听postmessage事件。希望这能有所帮助。

请求所有者密码流和单一登录不匹配。请重新考虑你的设计。如果用户不需要登录站点B,但需要使用令牌访问资源,那么站点B在我看来就像一个WebApi。谢谢rawel的回答。我还评估了站点B的作用和目的。除此之外,用定制的IdSvr3登录页面替换当前登录页面可能是个好主意。