本文介绍了多个 IdentityServer 联合:错误无法取消保护消息.状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个主从类型配置以使用 IdentityServer4 进行身份验证,如下所示

I'm trying to create a master slave type configuration for authentication with IdentityServer4 as below

MyMasterIdentityServer0 (Master) - receives id_token and gives access_token
|---> MySlaveIdentityServer1 (Basic Auth)
|---> MySlaveIdentityServer2 (Windows Auth)
|---> MySlaveIdentityServer3 (SmartCard Certificate Auth)
|---> MySlaveIdentityServer4 (SAML SSO Auth)
|---> Cloud Demo IdentityServer
|---> Google Auth
|---> Facebook Auth
|---> Microsoft Auth
|---> Twitter Auth

我所有的应用程序和 api 都将指向 MyMasterIdentityServer0

All my applications and api will point to and authenticate with the MyMasterIdentityServer0

用户可以选择使用上述任何提供商进行身份验证.他们可以选择用户名/密码,在这种情况下,他们应该被重定向到 MySlaveIdentityServer1(基本身份验证),或者他们可以选择使用他们的 AD 帐户使用 Windows 身份验证,在这种情况下他们将被重定向到 >MySlaveIdentityServer2(Windows 身份验证),或选择任何其他提供商.

Users can have a choice of authentication using any of the above providers. They can choose username/password in which case they should be redirected to the MySlaveIdentityServer1 (Basic Auth), or they can choose using the Windows Auth using their AD account in which case they will be redirected to MySlaveIdentityServer2 (Windows Auth), or choose any other provider.

一旦用户通过身份验证,他就会从提供者服务器收到一个 id_token 并被重定向回 MyMasterIdentityServer0,在那里使用 Provider 和 ProviderUserId 查找外部用户,然后获得一个 access_token 到根据他的权限访问应用程序/api.

Once the user has been authenticated, he receives an id_token from the provider server and gets redirected back to the MyMasterIdentityServer0 where the external user is looked up using the Provider and ProviderUserId and then given an access_token to access the applications/api based on his permissions.

我面临的问题是 IdentityServer 主从配置对我不起作用,并且在用户重定向回主时给我一个错误无法取消保护消息.状态认证后的服务器.我尝试查找问题,AuthO 也遇到了他们最近修复的相同错误.

They problem I'm facing is that the IdentityServer Master Slave configuration is not working for me and is giving me an error Unable to unprotect the message.State when the user is redirected back to the master server after authentication. I tried looking up the issue and AuthO also faced this same bug which they recently fixed.

收到错误

异常:无法取消对消息的保护.状态

IdentityServer-Master 配置

// WORKING
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
    AuthenticationScheme = "ID4DemoCloud",
    DisplayName = "Login with ID4DemoCloud",
    SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme,
    SignOutScheme = IdentityServerConstants.SignoutScheme,
    Authority = "https://demo.identityserver.io/",
    ClientId = "implicit",

    TokenValidationParameters = new TokenValidationParameters
    {
        NameClaimType = "name",
        RoleClaimType = "role"
    },
    //Events = new OpenIdConnectEvents() { }
});

// NOT WORKING
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
    AuthenticationScheme = "MySlaveIdentityServer1BasicAuth",
    DisplayName = "Login with MySlaveIdentityServer1 Basic Auth",
    SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme,
    SignOutScheme = IdentityServerConstants.SignoutScheme,
    Authority = "http://localhost:5100/",
    ClientId = "MyMasterIdentityServer0",
    ClientSecret = "secret",
    RequireHttpsMetadata = false,

    //TokenValidationParameters = new TokenValidationParameters
    //{
    //    NameClaimType = "name",
    //    RoleClaimType = "role"
    //},
});

基本认证服务器客户端配置

public static class Clients
{
    public static IEnumerable<Client> GetClients()
    {
        return new[]
        {
            new Client
            {
                ClientId = "MyMasterIdentityServer0",
                ClientName = "My Master IdentityServer 0",
                ClientSecrets = new List<Secret> { new Secret("secret".Sha256()) },
                AllowedGrantTypes = GrantTypes.Implicit,
                AllowedScopes = new List<string>
                {
                    StandardScopes.OpenId,
                    StandardScopes.Profile
                },
                RequireConsent = false,
                AllowOfflineAccess = false,
                RedirectUris = new [] { "http://localhost:5000/signin-oidc" }
            }
        };
    }
}

除了内部部署的 MySlaveIdentityServers 1、2、3 和 4 之外,所有身份验证提供程序都工作正常……甚至云演示身份服务器也工作正常.任何人都可以给我任何建议或建议吗?

All the auth providers are working fine except the internally deployed MySlaveIdentityServers 1, 2, 3 and 4 ... even the Cloud Demo Identity server is working fine. Can anyone give me any advice or suggestions ?

推荐答案

我相信您会收到 Unable to unprotect the message.State 错误,因为您的一个 OIDC 提供商正在尝试解密/取消保护另一个的消息状态.(消息状态只是一个有助于安全的随机字符串.)

I believe you are getting the Unable to unprotect the message.State error because one of your OIDC providers is trying to decrypt/unprotect the message state of the other one. (The message state is just a random string to help with security.)

我建议您为每个 OIDC 提供商命名 AuthenticationSchemes,例如 oidc-demooidc-master.然后外部提供商应该将您发送回相应的 signin-oidc-demosignin-oidc-master 端点.

I suggest that you name the AuthenticationSchemes for each OIDC provider like oidc-demo and oidc-master. Then the external providers should send you back to the corresponding signin-oidc-demo and signin-oidc-master endpoints.

--

事实证明这个答案基本上是正确的.使用多个 OIDC 提供商时,您需要不同的 AuthenticationSchemes 和 CallbackPath 值:

Turns out this answer was basically, correct. When using multiple OIDC providers you need different AuthenticationSchemes AND CallbackPath values:

.AddOpenIdConnect("oidc-google", options =>
  {
    options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
    options.SignOutScheme = IdentityServerConstants.SignoutScheme;
    options.CallbackPath = "/signin-oidc-google";
    ...
  }
.AddOpenIdConnect("oidc-microsoft", options =>
  {
    options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
    options.SignOutScheme = IdentityServerConstants.SignoutScheme;
    options.CallbackPath = "/signin-oidc-microsoft";
    ...
  }

请注意,身份验证中间件会神奇地处理任何已配置的 CallbackPath,因此不需要显式处理.

Note that the authentication middleware will magically handle any CallbackPath that's configured, so it doesn't need to be handled explicitly.

如果您不区分 OIDC 提供商并使用单独的回调路径,他们可能会尝试使用相同的方案登录,并且加密将不匹配,并且只有在您的代码中注册的第一个 OIDC 提供商才能工作.

If you don't differentiate OIDC providers and use separate callback paths, they may try to sign in with the same scheme and the cryptography won't match and only the first OIDC provider registered in your code will work.

这篇关于多个 IdentityServer 联合:错误无法取消保护消息.状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 10:23