使用Identity Server 4,VueJS和oidc-client

时间:2019-02-01 14:40:45

标签: identityserver4 oidc-client-js

我正在计算机上同时测试服务器和客户端,并且遇到以下情况:我可以很好地登录到客户端,执行一些工作,关闭浏览器而不注销。然后,我再次打开客户端,但我仍然登录(预期),但是过了一分钟后,我自动注销(未预期)。

我使用的是这样配置的oidc-client.js:

var mgr = new Oidc.UserManager({
    userStore: new Oidc.WebStorageStateStore({ store: window.localStorage }),
    authority: 'http://localhost:5000',
    client_id: 'TST_PORTAL',
    redirect_uri: window.location.origin + '/static/callback.html',
    response_type: 'code id_token token',
    scope: 'api47 openid profile read write offline_access active_dir email',
    post_logout_redirect_uri: window.location.origin + '/',
    silent_redirect_uri: window.location.origin + '/static/silent-renew.html',
    accessTokenExpiringNotificationTime: 10,
    automaticSilentRenew: true,
    filterProtocolClaims: true,
    loadUserInfo: true
})

经过进一步调查,我发现客户端正在调用/ connect / checksession(返回状态200)以支持单点登录,然后调用/ connect / authorize?client_id ...,该操作失败(302重定向到/ home / error) 。身份服务器日志说“授权请求中没有用户”和“无效的客户端授予类型:隐式。我配置了hybrid和client_credentials。我读了here,所以我将此代码添加到IdentityServer启动中:

services.ConfigureApplicationCookie(options =>
{
   options.Cookie.SameSite = SameSiteMode.None;
});

但这似乎没有帮助。

大声考虑一下,这可能是跨域问题,因为它们在不同的端口上运行,或者我没有正确设置COR?我没有看到cors错误。 checksession GET请求还应该具有参数吗?我一直在阅读规范,它谈论的是iframe,但不是网络流量,因此我不确定该流量应该是什么样。

更新

我的应用程序的第一页是匿名身份验证登录页面,该页面会检查它们是否已登录。如果已登录,它将其重定向到主页。用于检查的代码是这样的:

// Get signed in status without prompting to log in
getIsSignedIn() {
    console.log('Checking if signed in');
    return new Promise((resolve, reject) => {
        mgr.getUser().then(function (user) {
            if (user == null) {
                console.log('Not Signed In');
                return resolve(false)
            } else {
                if (user.expired) {
                   console.log('User expired');
                   return resolve(false)
                } else {
                    console.log('Signed In');
                    return resolve(true)
                }
            }
        }).catch(function (err) {
            console.log('Error when checking if signed in');
            return reject(false)
        });
    })
}

即使我打开一个新的浏览器,这似乎也返回了true。我什至将Oidc.WebStorageStateStore更改为使用默认值而不是localStorage。

1 个答案:

答案 0 :(得分:1)

很多事情都可能导致此行为。

1)一次退出(monitorSession:true)    这是做什么的? -登录到应用程序后(从IDP服务器重定向后,OIDC-客户端JS将在iframe中包含CheckSession端点,OIDC库每2秒(default)在内部对该iframe进行ping操作,以验证idsrv。会话Cookie值与应用程序ID令牌中的值匹配,如果不匹配,OIDC会引发用户退出事件addUserSignedOut,这取决于您的应用程序,甚至从OIDC。除非您启用了单点注销,否则除非应用程序进行处理,否则它不会将用户带回登录页面。

2)静音更新(automaticSilentRenew:true)    当您将此标志启用为true时,您无法控制应该在何时进行静默更新,default会在访问令牌到期时间1分钟之前进行静默更新。因此,如果silentrenew失败,将引发silentrenew事件addSilentRenewError。这取决于您的应用程序,甚至在OIDC提出时如何处理。

3)如果您说的是关闭整个浏览器并转到url应用程序URL,则应删除身份服务器cookie,因为它们是会话cookie。因此,如果您已经处理了单个注销事件,那么OIDC将在加载应用程序后2秒内引发注销事件。由于您没有看到登录页面,因此我认为您可能未在应用程序中处理过此事件。

4)当进行静默更新时(在令牌exp时间的1分钟之前),这一次您的应用将与IDP服务器通信,但是关闭浏览器时将没有会话cookie,并且会出现静默更新错误(大概这一次,您可能已经看到了所描述的错误),并且在这种情况下必须已处理了silentrenew错误,这就是为什么您看到登录屏幕的原因。 (只是基于您的输入的一个疯狂的假设。)

希望这会有所帮助!