如何解决Angular UI应用程序不会调用受AzureAD保护的Asp.net核心API
我正在尝试使用 AzureAD 保护从 angularUI 调用 WebAPI ,但这是我遇到的错误:
zone-evergreen.js:2952 GET https:// localhost:44319 / api / employee 401 :
我还引用了以下博客:
Azure AD Authentication In Angular And ASP.NET Core Web API App
msal.service.ts
import { Injectable } from '@angular/core';
import { broadcastService,MsalService } from '@azure/msal-angular';
import * as Msal from 'msal';
import { environment } from '../../environments/environment';
import { Observable } from 'rxjs';
@Injectable()
export class MsalUserService {
private accesstoken: any;
public clientApplication: Msal.UserAgentApplication = null;
constructor() {
this.clientApplication = new Msal.UserAgentApplication(
environment.uiClienId,'https://login.microsoftonline.com/' + environment.tenantId,this.authCallback,{
storeAuthStateInCookie: true,//cacheLocation: 'localStorage',});
}
public GetAccesstoken(): Observable<any> {
if (sessionStorage.getItem('msal.idtoken') !== undefined && sessionStorage.getItem('msal.idtoken') != null) {
this.accesstoken = sessionStorage.getItem('msal.idtoken');
console.log(this.accesstoken);
}
return this.accesstoken;
}
public authCallback(errorDesc,token,error,tokenType) {
if (token) {
} else {
console.log(error + ':' + errorDesc);
}
}
public getCurrentUserInfo() {
const user = this.clientApplication.getUser();
alert(user.name);
}
public logout() {
this.clientApplication.logout();
我将环境文件设置如下:
export const environment = {
production: false,baseUrl: 'https://localhost:44319/',scopeUri: ['api://3b4451a3-f813-4980-a477-fa8077138b8a/UserRead'],tenantId: 'e2xt89c0-058e-4dde-bb96-46de5ff97fe5',uiClienId: '9ebpqb4f-ee19-43c4-a221-2fec4930a1ec',redirectUrl: 'http://localhost:4200'
};
app.module.ts
import { AppComponent } from './app.component';
import { NavMenuComponent } from './nav-menu/nav-menu.component';
import { HomeComponent } from './home/home.component';
import { CounterComponent } from './counter/counter.component';
import { FetchDataComponent } from './fetch-data/fetch-data.component';
import { EmployeeComponent } from './employee/employee.component';
export const protectedResourceMap: any =
[
[environment.baseUrl,environment.scopeUri
]
];
@NgModule({
declarations: [
AppComponent,NavMenuComponent,HomeComponent,CounterComponent,FetchDataComponent,EmployeeComponent
],imports: [
MsalModule.forRoot({
clientID: environment.uiClienId,authority: 'https://login.microsoftonline.com/' + environment.tenantId,protectedResourceMap: protectedResourceMap,redirectUri: environment.redirectUrl
}),browserModule.withServerTransition({ appId: 'ng-cli-universal' }),AppRoutingModule,HttpClientModule,FormsModule,],providers: [HttpClient,MsalUserService,{
provide: HTTP_INTERCEPTORS,useClass: MsalInterceptor,multi: true
}
],bootstrap: [AppComponent]
})
export class AppModule { }
Employee.ts
import { Injectable } from '@angular/core';
import { HttpClient,HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { environment } from '../../environments/environment';
import { MsalUserService } from '../service/msaluser.service';
import { EmployeeModel } from './employeemodel';
@Injectable({
providedIn: 'root'
})
export class EmployeeService {
private url = environment.baseUrl + 'api/employee';
httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
};
constructor(private http: HttpClient,private msalService: MsalUserService
) { }
getEmployees(): Observable<EmployeeModel[]> {
this.httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json','Authorization': 'Bearer ' + this.msalService.GetAccesstoken()
})
};
console.log(this.url);
return this.http.get(this.url,this.httpOptions)
.pipe((response: any) => {
return response;
});
}
getCurrentUserInfo() {
this.msalService.getCurrentUserInfo();
}
logout() {
this.msalService.logout();
}
}
appsetting.json
"AzureActiveDirectory": {
"Instance": "https://login.microsoftonline.com/","Domain": "mydomain.onmicrosoft.com","TenantId": "e2xt89c0-058e-4dde-bb96-46de5ff97fe5","ClientId": "api://3bdd4161a3-f813-4980-a477-fa8077138b8a"
}
StartUp.cs
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
// In production,the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme).AddAzureADBearer(options => Configuration.Bind("AzureActiveDirectory",options));
string corsDomains = "http://localhost:4200";
string[] domains = corsDomains.Split(",".tochararray(),StringSplitOptions.RemoveEmptyEntries);
services.AddCors(o => o.AddPolicy("AppCORSPolicy",builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.WithOrigins(domains);
}));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios,see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseCors("AppCORSPolicy");
app.UseHttpsRedirection();
app.UseStaticFiles();
if (!env.IsDevelopment())
{
app.UseSpaStaticFiles();
}
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",pattern: "{controller}/{action=Index}/{id?}");
});
app.UseSpa(spa =>
{
// To learn more about options for serving an Angular SPA from ASP.NET Core,// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.sourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
}
EmployeeController.cs
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class EmployeeController : ControllerBase
{
[HttpGet]
public IEnumerable<Employee> Get()
{
List<Employee> employees = new List<Employee>
{
new Employee { Id = 1,Name = "AA",Company = "ABC",City = "xyz" },new Employee { Id = 2,Name = "BB",new Employee { Id = 3,Name = "CC",City = "xyz" }
};
return employees;
}
}
它在网络中显示“ zone-evergreen.js:2952 GET https:// localhost:44319 / api / employee 401”的错误
请帮助我解决此问题。 预先谢谢你。
解决方法
我犯了一个常见错误。我在environment.ts中使用http传递了baseurl,但是应该为https。
export const environment = {
production: false,baseUrl: 'https://localhost:44319/',scopeUri: ['api://3b4451a3-f813-4980-a477-fa8077138b8a/UserRead'],tenantId: 'e2xt89c0-058e-4dde-bb96-46de5ff97fe5',uiClienId: '9ebpqb4f-ee19-43c4-a221-2fec4930a1ec',redirectUrl: 'http://localhost:4200'
};
我希望这可以帮助某人并节省时间。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。