除了受众群体的字符串比较之外,OAuth令牌受众验证是否还会执

时间:2018-01-24 17:39:31

标签: asp.net-core oauth-2.0 azure-active-directory

我正在使用Microsoft.AspNetCore.Authentication.OpenIdConnectMicrosoft.AspNetCore.Authentication.JwtBearer来验证ASP.NET核心应用中的OAuth令牌。如果我禁用了内置的受众群体验证并自行验证了aud声明,除了字符串比较之外还有什么必要,例如校验和或签名检查吗?

我的具体方案是我有一个纯客户端SPA应用程序使用msal.js(Azure AD OpenId Connect Workflow V2)与具有不同应用程序注册的.NET API交谈(因此不同的ApplicationId / ClientId / Audidence取决于抽象层)。即使使用原始POST调用,v2 Oauth工作流也不允许我使用具有受众A的访问令牌与受众B交谈.V1不允许我暴露客户端密钥或私钥在浏览器中。我更愿意让API接受多个受众,然后共享应用注册,直到流程存在。

1 个答案:

答案 0 :(得分:0)

查看Microsoft.IdentityModel.Tokens的代码,实际执行的验证只是字符串比较。似乎没有任何校验和签名检查。

    /// <summary>
    /// Determines if the audiences found in a <see cref="SecurityToken"/> are valid.
    /// </summary>
    /// <param name="audiences">The audiences found in the <see cref="SecurityToken"/>.</param>
    /// <param name="securityToken">The <see cref="SecurityToken"/> being validated.</param>
    /// <param name="validationParameters"><see cref="TokenValidationParameters"/> required for validation.</param>
    /// <exception cref="ArgumentNullException">If 'vaidationParameters' is null.</exception>
    /// <exception cref="ArgumentNullException">If 'audiences' is null and <see cref="TokenValidationParameters.ValidateAudience"/> is true.</exception>
    /// <exception cref="SecurityTokenInvalidAudienceException">If <see cref="TokenValidationParameters.ValidAudience"/> is null or whitespace and <see cref="TokenValidationParameters.ValidAudiences"/> is null.</exception>
    /// <exception cref="SecurityTokenInvalidAudienceException">If none of the 'audiences' matched either <see cref="TokenValidationParameters.ValidAudience"/> or one of <see cref="TokenValidationParameters.ValidAudiences"/>.</exception>
    /// <remarks>An EXACT match is required.</remarks>
    public static void ValidateAudience(IEnumerable<string> audiences, SecurityToken securityToken, TokenValidationParameters validationParameters)
    {
        if (validationParameters == null)
            throw LogHelper.LogArgumentNullException(nameof(validationParameters));

        if (!validationParameters.ValidateAudience)
        {
            IdentityModelEventSource.Logger.WriteWarning(LogMessages.IDX10233);
            return;
        }

        if (audiences == null)
            throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidAudienceException(LogMessages.IDX10207) { InvalidAudience = null });

        if (string.IsNullOrWhiteSpace(validationParameters.ValidAudience) && (validationParameters.ValidAudiences == null))
            throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidAudienceException(LogMessages.IDX10208) { InvalidAudience = Utility.SerializeAsSingleCommaDelimitedString(audiences) });

        foreach (string audience in audiences)
        {
            if (string.IsNullOrWhiteSpace(audience))
            {
                continue;
            }

            if (validationParameters.ValidAudiences != null)
            {
                foreach (string str in validationParameters.ValidAudiences)
                {
                    if (string.Equals(audience, str, StringComparison.Ordinal))
                    {
                        IdentityModelEventSource.Logger.WriteInformation(LogMessages.IDX10234, audience);
                        return;
                    }
                }
            }

            if (!string.IsNullOrWhiteSpace(validationParameters.ValidAudience))
            {
                if (string.Equals(audience, validationParameters.ValidAudience, StringComparison.Ordinal))
                {
                    IdentityModelEventSource.Logger.WriteInformation(LogMessages.IDX10234, audience);
                    return;
                }
            }
        }

        throw LogHelper.LogExceptionMessage(
            new SecurityTokenInvalidAudienceException(String.Format(CultureInfo.InvariantCulture, LogMessages.IDX10214, Utility.SerializeAsSingleCommaDelimitedString(audiences), (validationParameters.ValidAudience ?? "null"), Utility.SerializeAsSingleCommaDelimitedString(validationParameters.ValidAudiences)))
            {    InvalidAudience = Utility.SerializeAsSingleCommaDelimitedString(audiences) });
    }