![](/img/trans.png)
[英]How to Configure Swagger in .NET Core 2.2 WebApi and Azure AD 2.0?
[英]How to configure .net core angular azure AD authentication?
我目前正在研究 Azure AD 身份驗證集成到 Angular -.Net core 3.1 項目。 這是一個從 Visual Studio 2019 模板(ASP.NET Core Web App)生成的項目。
在 Azure 門戶中,我注冊了 2 個應用程序並通過MS 教程和此配置。
兩個注冊的應用程序:
但是我只發布了一個App服務,其中包含SPA和API。 登錄后,我得到一個令牌,它是 append 到每個 api 調用與 MSAL 攔截器。
問題是所有的調用返回都是:401,由於“觀眾無效”。 在 auth 令牌中,受眾重視 frontend_app 的客戶端 ID。
我該如何解決才能接受觀眾? 僅對一項應用服務使用 2 個應用注冊是否正確?
我和你有同樣的問題,相信我已經想出了一個解決方案。 我最初遵循的所有指南都使用隱式流程。 正如卡爾在他的回答中指出的那樣(我認為這不能正確解決您的問題),有一個身份驗證流程,這是 go 的推薦方式。 不幸的是,所有示例和指南中的標准 MSAL 庫都是 1.x,不支持身份驗證流程。 相反,您需要使用MSAL.js 2.0 。 問題是 angular 庫仍處於alpha階段
所以,這就是我所做的一切。 我正在使用 Angular 10 前端和 ASP.NET Core 3.1 后端。
首先,您創建后端 api 應用注冊(您可能不需要更改)。 這是相關的文檔: 注冊 Web API 。 重要筆記:
然后按照MSAL.js 2.0文檔創建前端應用注冊。 重要說明如下:
您的應用注冊應類似於以下內容:
現在是代碼。 對於您的 angular 應用程序,首先安裝必要的模塊:
npm install @azure/msal-browser @azure/msal-angular@alpha
然后將其添加到您的應用程序模塊中:
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { APP_INITIALIZER, NgModule } from '@angular/core';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { tap } from 'rxjs/operators';
import {
IPublicClientApplication,
PublicClientApplication,
InteractionType,
BrowserCacheLocation,
LogLevel,
} from '@azure/msal-browser';
import {
MsalGuard,
MsalInterceptor,
MsalBroadcastService,
MsalInterceptorConfiguration,
MsalModule,
MsalService,
MSAL_GUARD_CONFIG,
MSAL_INSTANCE,
MSAL_INTERCEPTOR_CONFIG,
MsalGuardConfiguration,
} from '@azure/msal-angular';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
const PROTECTED_RESOURCE_MAP: Map<string, Array<string>> = new Map([
['https://graph.microsoft.com/v1.0/me', ['user.read']],
[
'api/admin/users',
['api://<backend app id>/access_as_admin'],
],
]);
const IS_IE =
window.navigator.userAgent.indexOf('MSIE ') > -1 ||
window.navigator.userAgent.indexOf('Trident/') > -1;
export function loggerCallback(logLevel, message) {
console.log(message);
}
export function MSALInstanceFactory(): IPublicClientApplication {
return new PublicClientApplication({
auth: {
clientId: '<frontend app id>',
authority:
'https://login.microsoftonline.com/<azure ad tenant id>',
redirectUri: 'http://localhost:4200',
postLogoutRedirectUri: 'http://localhost:4200/#/logged-out',
},
cache: {
cacheLocation: BrowserCacheLocation.LocalStorage,
storeAuthStateInCookie: IS_IE, // set to true for IE 11
},
system: {
loggerOptions: {
loggerCallback,
logLevel: LogLevel.Verbose,
piiLoggingEnabled: false,
},
},
});
}
export function MSALInterceptorConfigFactory(): MsalInterceptorConfiguration {
return {
interactionType: InteractionType.Redirect,
protectedResourceMap: PROTECTED_RESOURCE_MAP,
};
}
export function MSALGuardConfigFactory(): MsalGuardConfiguration {
return {
interactionType: InteractionType.Redirect,
};
}
export function initializeApp(appConfig: AppConfigService) {
const promise = appConfig
.loadAppConfig()
.pipe(tap((settings: IAppConfig) => {}))
.toPromise();
return () => promise;
}
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
BrowserAnimationsModule,
AppRoutingModule,
HttpClientModule,
MsalModule,
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: MsalInterceptor,
multi: true,
},
{
provide: MSAL_INSTANCE,
useFactory: MSALInstanceFactory,
},
{
provide: MSAL_GUARD_CONFIG,
useFactory: MSALGuardConfigFactory,
},
{
provide: MSAL_INTERCEPTOR_CONFIG,
useFactory: MSALInterceptorConfigFactory,
},
MsalService,
MsalGuard,
MsalBroadcastService,
],
bootstrap: [AppComponent],
})
export class AppModule {}
然后,您可以簡單地將MsalGuard
扔到您想要保護的任何路線上。
對於后端,首先安裝 Microsoft.Identity.Web package:
dotnet add package Microsoft.Identity.Web --version 1.3.0
這是我的 Startup.cs 中的相關代碼:
public void ConfigureServices(IServiceCollection services)
{
// other stuff...
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(options =>
{
Configuration.Bind("AzureAd", options);
})
.AddInMemoryTokenCaches();
services.AddCors((options =>
{
options.AddPolicy("FrontEnd", builder =>
builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
}));
// other stuff...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// other stuff...
app.UseCors("FrontEnd");
app.UseAuthentication();
app.UseAuthorization();
// other stuff...
}
appsettings.json 包含:
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "<azure ad domain>",
"TenantId": "<azure ad tenant id>",
"ClientId": "<backend app id>"
}
正如我在評論中所說,401錯誤通常是因為您的受眾與您要調用的 api 不匹配,因此您需要確保您的目標受眾是您的 api,在您的問題中它應該是您的backend_api ,我使用auth 代碼流為您做一個簡單的演示:
解析令牌:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.