【发布时间】: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 权限的配置
以下是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应用程序中。
标签: reactjs asp.net-core authentication azure-active-directory jwt