JWT Token 中的 Aud 字段表示啥?

Posted

技术标签:

【中文标题】JWT Token 中的 Aud 字段表示啥?【英文标题】:What Aud field indicates in JWT Token?JWT Token 中的 Aud 字段表示什么? 【发布时间】:2021-06-15 11:49:30 【问题描述】:

您好,我有 SPA 应用程序和 .Net 核心 Web API。我在 azure AD 中注册了两个应用程序。下面是我在 react 应用中的 adal 配置。

   /* istanbul ignore file */
import  adalGetToken, AuthenticationContext, UserInfo  from 'react-adal';
import  UserProfile  from '../common/models/userProfile';
class AdalContext 
    private authContext: AuthenticationContext | any;
    private appId: string = '';

    public initializeAdal(adalConfig: any) 
        this.authContext = new AuthenticationContext(adalConfig);
        this.appId = adalConfig.clientId;
    
    get AuthContext() 
        return this.authContext;
    

    public getToken(): Promise<string | void | null> 
        return adalGetToken(this.authContext, this.appId).catch((error: any) => 
            if (error.msg === 'login_required' || error.msg === 'interaction_required') 
                this.authContext.login();
            
        );
    

    public acquireToken(callback: Function) 
        let user = this.AuthContext.getCachedUser();
        if (user) 
            this.authContext.config.extraQueryParameter = 'login_hint=' + (user.profile.upn || user.userName);
        

        adalGetToken(this.authContext, this.appId).then(
            (token) => 
                callback(token);
            ,
            (error) => 
                if (error) 
                    if (error.msg === 'login_required') this.authContext.login();
                    else 
                        console.log(error);
                        alert(error);
                    
                
            
        );
    

    public getCachedToken(): string 
        return this.authContext.getCachedToken(this.authContext.config.clientId);
    
    public getCachedUser(): UserInfo 
        return this.authContext.getCachedUser();
    

    public getUserProfileData(): UserProfile 
        const user = this.authContext.getCachedUser();
        const userProfileData = new UserProfile();
        if (user) 
            userProfileData.name = user.profile.name;
            userProfileData.firstName = user.profile.given_name;
            userProfileData.surname = user.profile.family_name;
            userProfileData.emailAddress = user.userName;
            userProfileData.userProfileName = user.profile.name || user.userName;
        
        return userProfileData;
    

    public logOut() 
        this.authContext.logOut();
    


const adalContext: AdalContext = new AdalContext();
export default adalContext;
export const getToken = () => adalContext.getToken();

我能够重定向到 Azure AD 并能够获取令牌。我首先标记了 Aud 字段,该字段的值是为前端 SPA 应用注册的 azure 广告应用的客户端 ID。

以下是我在 .Net 核心 API 中验证代码的代码。

 services.AddAuthentication(x =>
            
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            )
            .AddJwtBearer(options =>
            
                options.SaveToken = true;
                options.RequireHttpsMetadata = true;
                options.Authority = $"authSettingsWebAPI.Instance/authSettingsWebAPI.TenantId";
                options.Audience = azureAuthSettings.ClientId; //client id of Azure AD front end SPA APP
                options.TokenValidationParameters = new TokenValidationParameters
                
                    ValidateAudience = true,
                    ValidateLifetime = true,
                    ValidateIssuer = true,
                    ValidateIssuerSigningKey = false,
                    ValidateActor = false,
                ;
            ); 

我的 Aud 字段具有 SPA 应用程序的 vale 客户端 ID。我在这里有点困惑。

Aud 应该是在 azure AD 中注册的 SPA 应用的值或客户端 ID 在 azuure AD 中注册的 Web API 应用?

这里我很困惑,因为我最近有第三个应用程序(我称之为受保护的 API),我的 API 调用另一个 Web API 应用程序(受保护的 API),我希望从 Web API 应用程序到受保护的 API 应用程序进行身份验证代流使用。

当我们想代表流程实施时,我将拥有如下所示的网址

POST https://login.microsoftonline.com/tenant/oauth2/v2.0/token
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
&client_id=client_id of Web API Gateway application
&client_secret=client_secret
&assertion=access token from previous step
&scope=permission for Protected API application
&requested_token_use=on_behalf_of

在上面的 url 断言是我收到的第一个 SPA 令牌,客户端 ID 是我的 API 应用程序客户端 ID。如果我传递从 SPA 收到的 api 应用程序客户端 ID 和令牌,那么它会给我错误

Azure AD 映像

令牌中的客户端 ID 和 Aud 值应该相同,但在 aud 中,我正在获取 SPA 应用程序的客户端 ID 值。有人可以帮助我了解我在令牌中收到的 Aud 字段是正确的还是高于我以错误方式构建的 url?有人可以帮我解决这个问题吗?任何帮助,将不胜感激。谢谢 以下是我对 ToDoListAPI API 权限的配置

以下是 ToDoListAPI 公开 API 的配置

以下是SPA的配置

邮递员

【问题讨论】:

Aud 在第一个访问令牌中应该是 Web API 应用程序的客户端 ID。 嗨艾伦谢谢你的澄清。我有强烈的怀疑,你清除了。但为什么我在 Aud 中获得 SPA 应用程序客户端 ID?我缺少 azure Ad 中的任何配置吗?你能帮我解决这个问题吗? 问题在于用于获取第一个访问令牌的请求。你应该把api://client id of the Web API app/.default 换成scope 嗨艾伦,我应该把 api://Web API 应用的客户端 ID/.default 放在 SPA 应用或 Web API 应用中吗? 你应该把它放在SPA应用程序中。 【参考方案1】:

由于访问令牌适用于您的 Web API 应用程序,因此对于 V2.0,您需要将范围指定为 api://client id of the Web API app/.default

那么访问令牌中的aud 将是client id of the Web API app

您可以像这样在 Postman 中获取访问令牌:

根据我的经验,adal 使用的是 V1.0,因此我们不需要输入 .default。您应该在adalConfig 中指定范围,例如:

export const adalConfig = 
  tenant: 'tenant id',
  clientId: 'client id',
  endpoints: 
    api: 'client id of the Web API app',
  ,
  cacheLocation: 'localStorage',
;

这里是a sample供您参考。

【讨论】:

以上是关于JWT Token 中的 Aud 字段表示啥?的主要内容,如果未能解决你的问题,请参考以下文章

使用 JWT 受众字段作为授权角色

ID Token - JWT

如何在 access_token JWT 中添加更多数据

jwt的应用生成token,redis做储存

基于JWT的Token认证机制实现及安全问题

WebApi_基于Token的身份验证——JWT(z)