gpt4 book ai didi

angular - MSAL、Angular 和 ASP.NET Core 的 CORS 错误

转载 作者:行者123 更新时间:2023-12-05 03:56:14 25 4
gpt4 key购买 nike

我正在尝试构建一个 ASP.NET Core webapi + Angular 网站,用户可以在其中使用 Microsoft 个人或工作或学校电子邮件登录。我按照此处描述的说明进行操作: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-angular/README.md

但是遇到这个问题,

  1. angular 网站加载,主页上的 protected 组件触发登录过程

  2. 出现微软网站

  3. 我登录

  4. 浏览器加载以下 url:https://localhost:44321/#id_token=...&state=...

  5. 网站再次重新加载(登录后第二次)

  6. 我看到以下错误

    在“https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=...”访问 XMLHttpRequest(重定向自“https://localhost:44321/Environment/GetUserInfo” ) 来自“https://localhost:44321”的来源已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin” header 。

使用 Visual Studio 2019 16.4.2 和 chrome 79.0.3945.88 在本地调试时

有什么想法吗?
谢谢

我创建了我的项目使用

dotnet new angular -o myapp

并在 Azure.Portal 中创建应用注册
使用以下重定向 URI 进行身份验证

  • https://localhost:44321/signin-microsoft
  • https://login.microsoftonline.com/
  • http://localhost:30662/
  • https://localhost:44321/signin-oidc
  • https://localhost:44321/

检查了所有“为公共(public)客户端建议的重定向 URI”
注销网址:https://localhost:44321/signout-callback-oidc
隐式授予:访问 token 和 ID token
实时 SDK 支持:是
默认客户端类型:否

证书与 secret
我创建了一个客户端密码,因为我尝试使用 Microsoft 提供程序(请参阅下面的注释代码)然后尝试使用 AzureAd

API权限
Microsoft.Graph User.Read

公开 API
范围 = [应用程序 ID URI]/access_as_user,仅限管理员
客户端应用程序 = [CLIENT_ID_FROM_AZURE_PORTAL],上述范围

服务器端
appsettings.json

 "AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "[Application ID URI]",
"ClientId": "[CLIENT_ID_FROM_AZURE_PORTAL]",
"TenantId": "common",
"CallbackPath": "/signin-oidc"
},

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("AllowAllOrigins",
builder =>
{
builder
.AllowAnyMethod()
.AllowAnyHeader()
.AllowAnyOrigin();
});
});

services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});

// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});

//services
// .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
// .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
// .AddMicrosoftAccount(microsoftOptions =>
//{
// microsoftOptions.ClientId = "[CLIENT_ID_FROM_AZURE_PORTAL]";
// microsoftOptions.ClientSecret = "[CLIENT_SECRET_FROM_AZURE_PORTAL]";
//});

services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));

services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
options.Authority = options.Authority + "/v2.0/";
options.TokenValidationParameters.ValidateIssuer = false;
});

services.AddControllers(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseCors("AllowAllOrigins");

if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}

app.UseHttpsRedirection();
app.UseCookiePolicy();
app.UseStaticFiles();
if (!env.IsDevelopment())
{
app.UseSpaStaticFiles();
}

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});

app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";

if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
}

客户端
app.module.ts

...
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { MsalModule, MsalGuard, MsalInterceptor } from '@azure/msal-angular';
...
export const protectedResourceMap: [string, string[]][] = [
['https://localhost:44321/Environment/GetUserInfo', ['[Application ID URI]/access_as_user']],
['https://localhost:44321/api/Environment/GetUserInfo', ['[Application ID URI]/access_as_user']],
['https://graph.microsoft.com/v1.0/me', ['user.read']],
['https://login.microsoftonline.com/common', ['user.read']]
];

@NgModule({
declarations: [
AppComponent,
NavMenuComponent,
HomeComponent,
CounterComponent,
EntitySignoffComponent
],
imports: [
BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
HttpClientModule,
FormsModule,
AgGridModule.withComponents([]),
MsalModule.forRoot({
clientID: [CLIENT_ID_FROM_AZURE_PORTAL],
authority: "https://login.microsoftonline.com/common",
redirectUri: "https://localhost:44321/",
validateAuthority: true,
cacheLocation: "localStorage",
storeAuthStateInCookie: false, // dynamically set to true when IE11
postLogoutRedirectUri: "https://localhost:44321/",
navigateToLoginRequestUrl: true,
popUp: false,
unprotectedResources: [ "https://login.microsoftonline.com/common" ],
protectedResourceMap: protectedResourceMap
}
),
RouterModule.forRoot([
{ path: '', component: HomeComponent, pathMatch: 'full', canActivate: [MsalGuard] }
{ path: 'counter', component: CounterComponent, canActivate: [MsalGuard] },
])
],
providers: [NavMenuComponent, { provide: HTTP_INTERCEPTORS, useClass: MsalInterceptor, multi: true }],

package.json

{
"name": "myapp",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"build:ssr": "ng run myapp:server:dev",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "8.2.14",
"@angular/common": "^8.2.14",
"@angular/compiler": "8.2.14",
"@angular/core": "^8.2.14",
"@angular/forms": "8.2.14",
"@angular/platform-browser": "8.2.14",
"@angular/platform-browser-dynamic": "8.2.14",
"@angular/platform-server": "8.2.14",
"@angular/router": "8.2.14",
"@azure/msal-angular": "^0.1.4",
"@nguniversal/module-map-ngfactory-loader": "8.2.6",
"aspnet-prerendering": "^3.0.1",
"bootstrap": "^4.4.1",
"core-js": "^3.6.1",
"jquery": "3.4.1",
"oidc-client": "^1.10.1",
"popper.js": "^1.16.0",
"rxjs": "^6.5.4",
"rxjs-compat": "^6.5.4",
"zone.js": "0.10.2"
},
"devDependencies": {
"@angular-devkit/build-angular": "^0.803.21",
"@angular/cli": "8.3.21",
"@angular/compiler-cli": "8.2.14",
"@angular/language-service": "8.2.14",
"@types/jasmine": "^3.5.0",
"@types/jasminewd2": "~2.0.8",
"@types/node": "~13.1.2",
"codelyzer": "^5.2.1",
"jasmine-core": "~3.5.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "^4.4.1",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "^2.1.1",
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.5.1",
"typescript": "3.5.3"
},
"optionalDependencies": {
"node-sass": "^4.13.0",
"protractor": "~5.4.2",
"ts-node": "~8.5.4",
"tslint": "~5.20.1"
}
}

Error in Chrome after login

最佳答案

这个问题没有太多赞成票,但我在使用 MSAL 时也遇到了 CORS 错误。对我来说,这是由于为@azure/msal-angular 选择的身份验证方案与后端期望的身份验证方案不匹配造成的。

在我的例子中,两者都需要是 JWTBearer 或“Bearer {token}”。

您获得 CORS 的原因是不匹配会触发后端尝试通过 Microsoft 进行身份验证,从而导致重定向(和跨源请求)。通过调整前端和后端身份验证方案,问题就迎刃而解了。

关于angular - MSAL、Angular 和 ASP.NET Core 的 CORS 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59606039/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com