10

我正在使用 Identity 和 Sustainsys.Saml2(用于 SAML 身份验证)开发 ASP.NET Core 2 应用程序。我已经在 Startup.cs 文件中进行了必要的配置。现在,当我运行项目并尝试使用 SAML2 登录(作为外部登录)时,输入凭据后出现以下错误:

SecurityTokenInvalidAudienceException:IDX10214:观众验证失败。观众:“[PII 被隐藏]”。不匹配:validationParameters.ValidAudience: '[PII is hidden]' 或 validationParameters.ValidAudiences: '[PII is hidden]'。Microsoft.IdentityModel.Tokens.Validators.ValidateAudience(IEnumerable 受众、SecurityToken securityToken、TokenValidationParameters 验证参数)Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ValidateConditions(Saml2SecurityToken samlToken、TokenValidationParameters 验证参数)Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ValidateToken(字符串令牌,TokenValidationParameters 验证参数,出 SecurityToken 已验证令牌)Sustainsys.Saml2.Saml2P.Saml2Response+d__60.MoveNext() System.Collections.Generic。

我不明白这是什么意思。我错过了什么吗?

这是我在启动文件中的内容

services.AddAuthentication()
        .AddSaml2(options => 
        {
            var spOptions = new SPOptions
            {
                EntityId = new EntityId("https://localhost:44373/Saml2"),
                ReturnUrl = new Uri("https://localhost:44373"),
                MinIncomingSigningAlgorithm = "http://www.w3.org/2000/09/xmldsig#rsa-sha1",                  
            };                

            options.SPOptions = spOptions;
            options.IdentityProviders.Add(new IdentityProvider(new EntityId("https://www.example.com/SSO/SAML/App"), options.SPOptions)
            {
                AllowUnsolicitedAuthnResponse = false,                  
                MetadataLocation = "https://www.example.com/SSO/SAMLMetadata/App",                  
                LoadMetadata = true,                  
            }); 
        });

提前致谢...

4

3 回答 3

14

据我所知,此错误清楚地表明您的 SAML 令牌中的受众与您的启动配置中的值不同。比较这些值可能会有所帮助。有时会因为区分大小写的比较而导致验证失败,因此您应该注意在哪种情况下您的受众处于令牌和配置中。

根据源代码(Saml2Response)和Anders Abel指出的那样,ValidAudience属性是从SPOptions.EntityId您在此处配置的初始化:

var spOptions = new SPOptions
{
    EntityId = new EntityId("https://localhost:44373/Saml2"),
    ReturnUrl = new Uri("https://localhost:44373"),
    MinIncomingSigningAlgorithm = "http://www.w3.org/2000/09/xmldsig#rsa-sha1",                  
};

因此,您应该将EntityId已配置的值与 saml-token 中的值进行比较,可能如下所示:

<saml:Audience>The value here should be the same as in your startup configuration</saml:Audience>
于 2018-10-16T20:06:53.417 回答
1

IDX10214:如果您使用的是1.4.1 版或类似版本,请检查Microsoft.Identity.Web部分并收到此异常(字面意思是复制的,您必须更改日志级别appsettings.json才能看到此内容):

info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[1]
      Failed to validate the token.
      Microsoft.IdentityModel.Tokens.SecurityTokenInvalidAudienceException: IDX10214: Audience validation failed. Audiences: 'System.String'. Did not match: validationParameters.ValidAudience: 'System.String' or validationParameters.ValidAudiences: 'System.String'.
         at Microsoft.IdentityModel.Tokens.Validators.ValidateAudience(IEnumerable`1 audiences, SecurityToken securityToken, TokenValidationParameters validationParameters)
         at Microsoft.Identity.Web.Resource.RegisterValidAudience.ValidateAudience(IEnumerable`1 audiences, SecurityToken securityToken, TokenValidationParameters validationParameters)
         at Microsoft.IdentityModel.Tokens.Validators.ValidateAudience(IEnumerable`1 audiences, SecurityToken securityToken, TokenValidationParameters validationParameters)
         at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateAudience(IEnumerable`1 audiences, JwtSecurityToken jwtToken, TokenValidationParameters validationParameters)
         at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateTokenPayload(JwtSecurityToken jwtToken, TokenValidationParameters validationParameters)
         at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
         at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()

System.String实际看到这些's的价值会更有帮助。如果您使用 GUID 还是可记忆和可读的东西都没有关系。

本质上,您必须将Audience属性添加到appsettings.json并且必须等于Application ID URIAzure 门户中的。我没有任何运气破解ClientId并匹配Application ID URI. 这不是最终解决方案 - AFAIK 仍然必须等于Application (client) IDAzure 门户中的,即没有任何前缀或后缀的 GUID。

于 2020-12-27T23:22:47.610 回答
0

在我的例子中,JwtSecurityToken 的发行者和受众被省略了。在我的派生类 UserService: IUserService 中,我在函数 generateJwtToken 中定义了颁发者和受众变量。它们的变量必须与 ValidIssuer 和 ValidAudience 的 startup.csv 中的 services.AddJwtBearer 变量匹配。请参阅(https://dotnetcoretutorials.com/2020/01/15/creating-and-validating-jwt-tokens-in-asp-net-core/)。

引用:

The Issuer and Audience are funny things because realistically, you probably won’t have a lot of use for them. Issuer is “who” created this token, for example your website, and Audience is “who” the token is supposed to be read by. So a good example might be that when a user logs in, your authentication api (auth.mywebsite.com) would be the issuer, but your general purposes API is the expected audience (api.mywebsite.com). These are actually free text fields so they don’t have to be anything in particular, but later on when we validate the issuer/audience, we will need to know what they are.

公共类用户服务:IUserService {

private string generateJwtToken(long userId)
            {
                var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_appSettings.Secret));
                var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);
                var tokenOptions = new JwtSecurityToken(
                    issuer: "http://localhost:5000",
                    audience: "http://localhost:5000",
                    claims: new List<Claim> {
                        new Claim(ClaimTypes.Name, userId.ToString()),
                        new Claim(ClaimTypes.Role, "Operator")
                    },
                    expires: DateTime.UtcNow.AddDays(7),
                    signingCredentials: signinCredentials
                );
                var tokenString = new JwtSecurityTokenHandler().WriteToken(tokenOptions);
                return tokenString;

            }

}

启动.cs

public void ConfigureServices(IServiceCollection services)
        {

services.AddAuthentication(opt =>
            {
                opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(opt =>
            {
                opt.RequireHttpsMetadata = false;
                opt.SaveToken = true;
                opt.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateLifetime = true,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidIssuer = "http://localhost:5000",
                    ValidAudience = "http://localhost:5000"
                };
            });

}
于 2021-11-30T22:59:05.867 回答