我在WebApi中实现IdentityServer3令牌授权时遇到问题。我的解决方案有一个.NET Core Angular 4客户端项目和一个单独的.NET Framework 4.5.2 WebApi项目。在添加令牌授权之前,WebApi已经过测试并且正在运行。 IdentityServer3登录和身份验证也正常运行。我正在使用angular-auth-oidc-client节点模块。我已经验证了Request Header正在为Content-Type,Accept和Authorization设置指定的属性。以下是一些关键文件的代码。
用户-list.component.ts
import { Component, OnInit } from '@angular/core';
import { Http, Headers, Response } from '@angular/http';
import { Subject } from 'rxjs/Rx';
import { OidcSecurityService } from 'angular-auth-oidc-client';
import 'rxjs/add/operator/map';
class User {
userId: number;
firstName: string;
middleName: string;
lastName: string;
email: string;
}
@Component({
selector: 'user-list',
templateUrl: './user-list.html',
styleUrls: ['./user-list.css']
})
export class UserListComponent implements OnInit {
dtOptions: DataTables.Settings = {};
users: User[] = [];
dtTrigger: Subject<User> = new Subject();
constructor(private http: Http, private securityService: OidcSecurityService) { }
ngOnInit(): void {
this.dtOptions = {
searching: true,
pagingType: 'full_numbers',
pageLength: 5,
info: false,
lengthChange: false
};
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');
headers.append('Authorization', 'Bearer ' + this.securityService.getToken());
//this.dtOptions = this.http.get('api/settings/datatables')
// .toPromise()
// .then(response => response.json());
this.http.get('/api/home', { headers })
.map((response: Response) => response.json())
.subscribe(users => {
this.users = users;
this.dtTrigger.next();
});
}
}
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpModule } from '@angular/http';
import { AppRoutingModule } from './app.routes';
import { DataTablesModule } from 'angular-datatables';
import { AppComponent } from './app.component';
import { UserListComponent } from './user-list/user-list.component';
import { PostalCodeComponent } from './postal-code/postal-code.component';
import { AuthModule, OidcSecurityService, OpenIDImplicitFlowConfiguration } from 'angular-auth-oidc-client';
@NgModule({
declarations: [
AppComponent,
UserListComponent,
PostalCodeComponent
],
imports: [
BrowserModule,
AppRoutingModule,
HttpModule,
DataTablesModule,
AuthModule.forRoot()
],
providers: [OidcSecurityService],
bootstrap: [AppComponent]
})
export class AppModule {
constructor(public oidcSecurityService: OidcSecurityService) {
let settings = new OpenIDImplicitFlowConfiguration();
settings.stsServer = 'https://identitydev.company.com/oidc/core';
settings.redirect_url = 'http://localhost:4200';
settings.client_id = '802523112846585';
settings.response_type = 'id_token token';
settings.scope = 'openid app_profile app_client_api';
settings.post_logout_redirect_uri = 'http://localhost:4200';
settings.startup_route = '/';
//settings.forbidden_route = '/Forbidden';
//settings.unauthorized_route = '/Unauthorized';
settings.log_console_warning_active = true;
settings.log_console_debug_active = true;
//settings.max_id_token_iat_offset_allowed_in_seconds = 10;
//settings.override_well_known_configuration = true;
//settings.override_well_known_configuration_url = 'https://localhost:44386/wellknownconfiguration.json';
// this.oidcSecurityService.setStorage(localStorage);
this.oidcSecurityService.setupModule(settings);
}
}
Startup.cs
using Microsoft.Owin;
using Owin;
using System.Web.Http;
using IdentityServer3.AccessTokenValidation;
using System.Net.Http.Headers;
using Microsoft.Owin.Security.OAuth;
[assembly: OwinStartup(typeof(App.API.Test.Startup))]
namespace App.API.Test
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
{
Authority = "https://identitydev.company.com/oidc/core",
//RequiredScopes = new[] { "app_client_api" },
ValidationMode = ValidationMode.ValidationEndpoint
});
// configure web api
var config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
app.UseWebApi(config);
}
}
}
HomeController.cs
using System.Collections.Generic;
using System.Security.Claims;
using System.Web.Http;
using TRAX.Models;
namespace App.API.Test.Controllers
{
[Authorize]
[Route("api/home")]
public class HomeController : ApiController
{
[HttpGet]
public IEnumerable<User> Get()
{
UserList list = new UserList();
return list.GetAll;
}
//// GET api/home/{firstname}
//[HttpGet("{FirstName}")]
//public List<User> GetByFirstName(string FirstName)
//{
// UserList list = new UserList();
// return list.GetUserByFirstName(FirstName);
//}
}
}
**注意:有一个模型与该控制器一起返回数据,但您可以相信它返回了正确的列表。
答案 0 :(得分:1)
显然,解决方案是删除Microsoft在模板项目中创建的Global.ascx文件。然后我更新了Startup.cs文件。
using Microsoft.Owin;
using Owin;
using System.Web.Http;
using IdentityServer3.AccessTokenValidation;
[assembly: OwinStartup(typeof(App.API.Test.Startup))]
namespace App.API.Test
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
{
Authority = "https://identitydev.company.com/oidc/core",
RequiredScopes = new[] { "app_client_api" },
ValidationMode = ValidationMode.ValidationEndpoint
});
WebApiConfig.Register(config);
app.UseWebApi(config);
}
}
}
我也不需要在客户端API调用中包含Content-Type或Accept标头覆盖。我默认从WebApi返回JSON。