我正在为vue js客户端应用程序使用.net核心身份服务器4身份验证。我支持多租户。我在客户端使用oidc客户端Java脚本库进行身份验证。
客户端配置将是这样
authority: 'http://identity.identityserver.com/',
"redirect_uri": "http://app.clientapp.com/callback",
"client_id": "app1",
"grant_type": "authorization_code",
"client_secret": "secret_code",
"response_type": "code",
"scope": "openid profile web.api",
"post_logout_redirect_uri": "http://app.clientapp.com/logoutSuccess",
身份服务器配置将是这样
new Client
{
ClientId = "app1",
ClientName = "Vue JS APP",
ClientSecrets = new List<Secret> { new Secret("secret_code") },
AllowedGrantTypes = GrantTypes.Code,
AllowAccessTokensViaBrowser = true,
AlwaysIncludeUserClaimsInIdToken = true,
AlwaysSendClientClaims = true,
RedirectUris = { "http://app.clientapp.com/callback" },
RequireConsent = false,
PostLogoutRedirectUris = { "http://app.clientapp.com/callback/logoutSuccess" },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"web.api",
},
},
这按预期工作,没有任何问题。它重定向到身份服务器,弹出登录窗口,输入凭据后,成功重定向到http://app.clientapp.com/callback。
我的要求是,基于用户登录名,我必须将用户重定向到他的子域,即支持多租户。例如,如果用户“ user1”的承租人是tenant1,即使配置的回调URL为http://app.clientapp.com/callback,则在成功重定向后,用户也必须重定向到http://tenant1.clientapp.com/callback。我已经在身份服务器中进行了必要的更改,以使用IRedirectUriValidator覆盖它。并且它正在重定向回http://tenant1.clientapp.com/callback。但是问题是,客户端的oidc-client抛出“在存储中找不到匹配状态”。
任何人都可以在这个问题上提供帮助。
先谢谢了。
答案 0 :(得分:0)
这并不特别适用于您的情况,但是,对于其他人在这个特殊的oidc-client错误上head之以鼻,觉得值得一试。
我们发现了导致此错误间歇出现在日志中的两个其他原因。在我们的例子中,在oicd登录回调内部的oidc-client-js方法signinRedirectCallback()
期间引发了“在存储中找不到匹配状态”错误。
原因:
系统时钟的用户设置为与当前实际时间相差5分钟以上(在oidc-client-js中,clockSkew默认为5分钟)
用户正在共享和重复使用由Identity Server生成的带有安全参数的唯一生成的登录URL
/login?ReturnUrl=https%3A%2F%2Fae-xxxxxx%2Fauthorize%2Fcallback%3Fclient_id%3Dxxxxxx%26redirect_uri%3Dhttps%253A%252F%252Fxxxxxxxx.com%252Fsignin-oidc%26response_type%3Dcode%26scope%3Dopenid%2520profile%2520email%26state%3D3b6da3263b9e47c3a954c1d6b149337f%26code_challenge%asagasgsagas-Wf8VWWWRWiGvCPfcu3MdDFhA%26code_challenge_method%3DS256%26response_mode%3Dquery
)
我们最终在包裹oidc-client-js的AuthContext中捕获并报告了错误,如下所示:
signinRedirectCallback = async () => {
try {
await this.UserManager.signinRedirectCallback();
} catch (error) {
Sentry.captureException(error, {
level: "warning",
});
// clearing state and storage
// may not be necessary,
// but it seems reasonable
this.UserManager.clearStaleState();
localStorage.clear();
throw new Error(error);
}
};
然后在signin-oidc回调中,捕获错误并将用户引导至错误页面:
import { useEffect, useContext } from "react";
import { useHistory } from "react-router-dom";
import AuthContext from "contexts/auth";
export default () => {
const auth = useContext(AuthContext);
const history = useHistory();
useEffect(() => {
auth.signinRedirectCallback().catch((error) => {
history.replace("/error?code=login_callback_error");
});
}, [auth, history]);
return "";
};