【发布时间】:2018-11-29 20:54:21
【问题描述】:
我有一个应用程序,它在服务器端由 asp.net core 2.1 web api 表示,在客户端由 angular 6 表示。在服务器端使用 OpenIddict 来支持令牌认证。主要问题是,当从 Angular 应用程序向服务器发送请求以生成或刷新客户端的 access_token 时,服务器会以 400(错误请求)响应,尽管当它从 Postman 发送时一切正常。添加了 Cors 策略以允许 corss-origin 请求,因为客户端和服务器端放置在不同的端口上,因此从 angular 到服务器的简单请求可以正常通过。
这里是启动类:
public class Startup
{
public Startup(IConfiguration configuration, IHostingEnvironment env)
{
Configuration = configuration;
hostingEnvironment = env;
}
public IConfiguration Configuration { get; }
private IHostingEnvironment hostingEnvironment { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContextPool<HospitalContext>(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
options.UseOpenIddict();
});
services.AddCors(options => options.AddPolicy("AllowLocalhost4200", builder =>
{
builder
.WithOrigins("http://localhost:4200")
.WithHeaders("Authorization", "Content-type")
.WithMethods("Get", "Post", "Put", "Delete");
}));
services.AddCustomIdentity();
services.AddCustomOpenIddict(hostingEnvironment);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseCors("AllowLocalhost4200");
app.UseAuthentication();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseMvc();
app.InitilizeDb();
}
}
如果有人需要查看配置,则在 ConfigureServices 方法中的 AddCustomOpenIddict 方法:
public static IServiceCollection AddCustomOpenIddict(this IServiceCollection services,
IHostingEnvironment env)
{
services.AddOpenIddict(options =>
{
options.AddEntityFrameworkCoreStores<HospitalContext>();
options.AddMvcBinders();
options.EnableTokenEndpoint("/connect/token");
options.EnableAuthorizationEndpoint("/connect/authorize");
options.AllowRefreshTokenFlow()
.AllowImplicitFlow();
options.SetAccessTokenLifetime(TimeSpan.FromMinutes(30));
options.SetIdentityTokenLifetime(TimeSpan.FromMinutes(30));
options.SetRefreshTokenLifetime(TimeSpan.FromMinutes(60));
if (env.IsDevelopment())
{
options.DisableHttpsRequirement();
}
options.AddEphemeralSigningKey();
});
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultForbidScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddOAuthValidation();
return services;
}
发送请求的Angular方法是:
public authorize(model: ILoginModel): Observable<Response> {
return this.http.post(`http://localhost:58300/connect/token`,
this.authService.authFormBody(model),
{headers: this.authService.authHeaders()});
}
使用 this.authService.authFormBody 和 this.authService.authHeaders:
authHeaders(): Headers {
const headers = new Headers(
{
'Content-Type': 'application/x-www-form-urlencoded'
});
return headers;
}
authFormBody(model: ILoginModel): string {
let body = '';
body += 'grant_type=password&';
body += 'username=' + model.email + '&';
body += 'password=' + model.password + '&';
body += 'scope=OpenId profile OfflineAccess Roles';
return body;
}
我实际上是基于令牌的身份验证的新手,所以可能存在配置问题或其他问题。非常感谢任何解决问题的提议。
【问题讨论】:
标签: asp.net-web-api angular6 openiddict