【发布时间】:2016-03-31 15:43:18
【问题描述】:
我已经从有关如何实施 AspNet.Security.OpenIdConnect.Server 的帖子中了解了所有信息。
Pinpoint,你听到了吗? ;)
我已经设法将令牌发行和令牌消费分开。我不会显示“身份验证服务器端”,因为我认为这部分已经设置完毕,但我将展示如何在自定义 AuthorizationProvider 中构建身份验证票证:
public sealed class AuthorizationProvider : OpenIdConnectServerProvider
{
// The other overrides are not show. I've relaxed them to always validate.
public override async Task GrantResourceOwnerCredentials(GrantResourceOwnerCredentialsContext context)
{
// I'm using Microsoft.AspNet.Identity to validate user/password.
// So, let's say that I already have MyUser user from
//UserManager<MyUser> UM:
var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme);
//identity.AddClaims(await UM.GetClaimsAsync(user));
identity.AddClaim(ClaimTypes.Name, user.UserName);
(await UM.GetRolesAsync(user)).ToList().ForEach(role => {
identity.AddClaim(ClaimTypes.Role, role);
});
var ticket = new AuthenticationTicket(new ClaimsPrincipal(identity),
new AuthenticationProperties(),
context.Options.AuthenticationScheme);
// Some new stuff, per my latest research
ticket.SetResources(new[] { "my_resource_server" });
ticket.SetAudiences(new[] { "my_resource_server" });
ticket.SetScopes(new[] { "defaultscope" });
context.Validated(ticket);
}
}
并在认证服务器上启动:
using System;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.Data.Entity;
using Microsoft.Extensions.DependencyInjection;
using MyAuthServer.Providers;
namespace My.AuthServer
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication();
services.AddCaching();
services.AddMvc();
string connectionString = "there is actually one";
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<MyDbContext>(options => {
options.UseSqlServer(connectionString).UseRowNumberForPaging();
});
services.AddIdentity<User, Role>()
.AddEntityFrameworkStores<MyDbContext>().AddDefaultTokenProviders();
}
public void Configure(IApplicationBuilder app)
{
app.UseIISPlatformHandler();
app.UseOpenIdConnectServer(options => {
options.ApplicationCanDisplayErrors = true;
options.AllowInsecureHttp = true;
options.Provider = new AuthorizationProvider();
options.TokenEndpointPath = "/token";
options.AccessTokenLifetime = new TimeSpan(1, 0, 0, 0);
options.Issuer = new Uri("http://localhost:60556/");
});
app.UseMvc();
app.UseWelcomePage();
}
public static void Main(string[] args) => WebApplication.Run<Startup>(args);
}
}
果然,当我收到这个 HTTP 请求时,我确实得到了一个访问令牌,但我不确定该访问令牌是否包含资源服务器期望的所有数据。
POST /token HTTP/1.1
Host: localhost:60556
Content-Type: application/x-www-form-urlencoded
username=admin&password=pw&grant_type=password
现在,在资源服务器端,我正在使用 JWT 承载身份验证。在启动时,我有:
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.Data.Entity;
using Microsoft.Extensions.DependencyInjection;
namespace MyResourceServer
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
string connectionString = "there is actually one";
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<MyDbContext>(options => {
options.UseSqlServer(connectionString).UseRowNumberForPaging();
});
services.AddIdentity<User, Role>()
.AddEntityFrameworkStores<MyDbContext>().AddDefaultTokenProviders();
}
public void Configure(IApplicationBuilder app)
{
app.UseIISPlatformHandler();
app.UseMvc();
app.UseWelcomePage();
app.UseJwtBearerAuthentication(options => {
options.Audience = "my_resource_server";
options.Authority = "http://localhost:60556/";
options.AutomaticAuthenticate = true;
options.RequireHttpsMetadata = false;
});
}
public static void Main(string[] args) => WebApplication.Run<Startup>(args);
}
}
当我向资源服务器发出这个 HTTP 请求时,我得到一个 401 Unauthorized:
GET /api/user/myroles HTTP/1.1
Host: localhost:64539
Authorization: Bearer eyJhbGciOiJS...
Content-Type: application/json;charset=utf-8
拥有到/api/user/myroles 的路由的控制器用一个没有参数的普通[Authorize] 装饰。
我觉得我在身份验证和资源服务器中都缺少一些东西,但不知道它们是什么。
询问“如何验证 AspNet.Security.OpenIdConnect.Server 颁发的令牌”的其他问题没有答案。我将不胜感激。
另外,我注意到示例提供程序中注释掉了 OAuth Introspection,并且在某处读到 Jwt 不会很快得到支持。我找不到给我 OAuth Instrospection 的依赖项。
更新我已经包含了我的 startup.cs,来自每个身份验证和资源服务器。会不会有什么错误会导致资源服务器对每个请求总是返回 401?
在整个过程中我没有真正触及的一件事是签名。它似乎在身份验证服务器上为 JWT 生成签名,但资源服务器(我猜)不知道签名密钥。回到 OWIN 项目,我必须创建一个机器密钥并放在两台服务器上。
【问题讨论】:
-
嘿。如果您看到未回答的 ASOS 问题,请将链接发送给我,以便我回答;)
-
我的意思是这些问题的答案回答了他们的问题,而不是我的问题。
标签: authentication oauth-2.0 asp.net-core openid-connect aspnet-contrib