配置授权服务器端点
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了配置授权服务器端点相关的知识,希望对你有一定的参考价值。
Question
我们如何使用用户名和密码流在ASP.NET 5中使用持票令牌?对于我们的场景,我们希望让用户使用AJAX调用进行注册和登录,而无需使用外部登录。
为此,我们需要一个授权服务器端点。在以前的ASP.NET版本中,我们将执行以下操作,然后在ourdomain.com/Token
URL上登录。
// Configure the application for OAuth based flow
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14)
};
但是,在当前版本的ASP.NET中,上述操作无效。我们一直试图找出新的方法。例如,GitHub上的aspnet/identity example配置了Facebook,Google和Twitter身份验证,但似乎没有配置非外部OAuth授权服务器端点,除非这是AddDefaultTokenProviders()
所做的,在这种情况下我们想知道提供商的URL是什么是。
Research
我们从reading the source here了解到,我们可以通过在IAppBuilder.UseOAuthBearerAuthentication
类中调用Startup
来向HTTP管道添加“bearer authentication middleware”。虽然我们仍然不确定如何设置其令牌端点,但这是一个良好的开端。这不起作用:
public void Configure(IApplicationBuilder app)
{
app.UseOAuthBearerAuthentication(options =>
{
options.MetadataAddress = "meta";
});
// if this isn't here, we just get a 404
app.Run(async context =>
{
await context.Response.WriteAsync("Hello World.");
});
}
在去ourdomain.com/meta
时,我们收到了我们的hello world页面。
进一步的研究表明,我们也可以使用IAppBuilder.UseOAuthAuthentication
扩展方法,并且它需要一个OAuthAuthenticationOptions
参数。该参数具有TokenEndpoint
属性。因此,虽然我们不确定我们在做什么,但我们尝试了这一点,当然这不起作用。
public void Configure(IApplicationBuilder app)
{
app.UseOAuthAuthentication("What is this?", options =>
{
options.TokenEndpoint = "/token";
options.AuthorizationEndpoint = "/oauth";
options.ClientId = "What is this?";
options.ClientSecret = "What is this?";
options.SignInScheme = "What is this?";
options.AutomaticAuthentication = true;
});
// if this isn't here, we just get a 404
app.Run(async context =>
{
await context.Response.WriteAsync("Hello World.");
});
}
换句话说,在去ourdomain.com/token
时,没有错误,只有我们的hello world页面。
好的,让我们回顾一下OWIN / Katana 3提供的不同OAuth2中间件(及其各自的IAppBuilder
扩展)以及将移植到ASP.NET Core的中间件:
app.UseOAuthBearerAuthentication
/OAuthBearerAuthenticationMiddleware
:它的名字并不是非常明显,但它(并且仍然是,因为它已被移植到ASP.NET Core)负责验证OAuth2服务器中间件发出的访问令牌。它基本上是cookie中间件的令牌对应物,用于保护您的API。在ASP.NET Core中,它已经通过可选的OpenID Connect功能进行了丰富(现在它可以自动从发布令牌的OpenID Connect服务器中检索签名证书)。
注意:从ASP.NET Core beta8开始,它现在名为app.UseJwtBearerAuthentication
/ JwtBearerAuthenticationMiddleware
。
app.UseOAuthAuthorizationServer
/OAuthAuthorizationServerMiddleware
:顾名思义,OAuthAuthorizationServerMiddleware
是OAuth2授权服务器中间件,用于创建和发布访问令牌。此中间件不会移植到ASP.NET Core:OAuth Authorization Service in ASP.NET Core。app.UseOAuthBearerTokens
:这个扩展并不真正对应于中间件,只是围绕app.UseOAuthAuthorizationServer
和app.UseOAuthBearerAuthentication
的包装。它是ASP.NET Identity包的一部分,只是配置OAuth2授权服务器和用于在单个调用中验证访问令牌的OAuth2承载中间件的便捷方式。它不会移植到ASP.NET Core。
ASP.NET Core将提供一个全新的中间件(我很自豪地说我设计了它):
app.UseOAuthAuthentication
/OAuthAuthenticationMiddleware
:这个新的中间件是一个通用的OAuth2交互式客户端,其行为与app.UseFacebookAuthentication
或app.UseGoogleAuthentication
完全相同,但几乎支持任何标准的OAuth2提供商,包括您的。谷歌,Facebook和微软提供商都已经更新,以继承这个新的基础中间件。
因此,您实际需要的中间件是OAuth2授权服务器中间件,也就是OAuthAuthorizationServerMiddleware
。
虽然它被社区的很大一部分视为必不可少的组件,但它不会被移植到ASP.NET Core。
幸运的是,已经有了直接的替代品:AspNet.Security.OpenIdConnect.Server(https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server)
此中间件是与Katana 3一起提供的OAuth2授权服务器中间件的高级分支,但其目标是OpenID Connect(它本身基于OAuth2)。它使用相同的低级方法,提供细粒度控制(通过各种通知),并允许您使用自己的框架(Nancy,ASP.NET Core MVC)来为您的授权页面提供服务,就像使用OAuth2服务器中间件一样。配置很简单:
ASP.NET Core 1.x:
// Add a new middleware validating access tokens issued by the server.
app.UseOAuthValidation();
// Add a new middleware issuing tokens.
app.UseOpenIdConnectServer(options =>
{
options.TokenEndpointPath = "/connect/token";
// Create your own `OpenIdConnectServerProvider` and override
// ValidateTokenRequest/HandleTokenRequest to support the resource
// owner password flow exactly like you did with the OAuth2 middleware.
options.Provider = new AuthorizationProvider();
});
ASP.NET Core 2.x:
// Add a new middleware validating access tokens issued by the server.
services.AddAuthentication()
.AddOAuthValidation()
// Add a new middleware issuing tokens.
.AddOpenIdConnectServer(options =>
{
options.TokenEndpointPath = "/connect/token";
// Create your own `OpenIdConnectServerProvider` and override
// ValidateTokenRequest/HandleTokenRequest to support the resource
// owner password flow exactly like you did with the OAuth2 middleware.
options.Provider = new AuthorizationProvider();
});
有一个OWIN / Katana 3版本,以及支持.NET Desktop和.NET Core的ASP.NET Core版本。
不要犹豫,试试the Postman sample了解它是如何工作的。我建议阅读the associated blog post,它解释了如何实现资源所有者密码流。
如果您仍然需要帮助,请随时给我打电话。祝好运!
在@ Pinpoint的帮助下,我们将答案的基础连接起来。它显示了组件如何连接在一起而不是一个完整的解决方案。
Fiddler Demo
通过我们的基本项目设置,我们能够在Fiddler中提出以下请求和响应。
请求
POST http://localhost:50000/connect/token HTTP/1.1
User-Agent: Fiddler
Host: localhost:50000
Content-Length: 61
Content-Type: application/x-www-form-urlencoded
grant_type=password&username=my_username&password=my_password
响应
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 1687
Content-Type: application/json;charset=UTF-8
Expires: -1
X-Powered-By: ASP.NET
Date: Tue, 16 Jun 2015 01:24:42 GMT
{
"access_token" : "eyJ0eXAiOi ... 5UVACg",
"expires_in" : 3600,
"token_type" : "bearer"
}
响应提供了一个承载令牌,我们可以使用它来访问应用程序的安全部分。
Project Structure
这是Visual Studio中我们项目的结构。我们必须将Properties
> Debug
> Port
设置为50000
,以便它充当我们配置的身份服务器。以下是相关文件:
ResourceOwnerPasswordFlow
Providers
AuthorizationProvider.cs
project.json
Startup.cs
Startup.cs
为了便于阅读,我将Startup
类拆分为两个部分。
Startup.ConfigureServices
对于基础知识,我们只需要AddAuthentication()
。
public partial class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication();
}
}
Startup.Configure
public partial class Startup
{
public void Configure(IApplicationBuilder app)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear();
// Add a new middleware validating access tokens issued by the server.
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
Audience = "resource_server_1",
Authority = "http://localhost:50000/",
RequireHttpsMetadata = false
});
// Add a new middleware issuing tokens.
app.UseOpenIdConnectServer(options =>
{
// Disable the HTTPS requirement.
options.AllowInsecureHttp = true;
// Enable the token endpoint.
options.TokenEndpointPath = "/connect/token";
options.Provider = new AuthorizationProvider();
// Force the OpenID Connect server middleware to use JWT
// instead of the default opaque/encrypted format.
options.AccessTokenHandler = new JwtSecurityTokenHandler
{
InboundClaimTypeMap = new Dictionary<string, string>(),
OutboundClaimTypeMap = new Dictionary<string, string>()
};
// Register an ephemeral signing key, used to protect the JWT tokens.
// On production, you'd likely prefer using a signing certificate.
options.SigningCredentials.AddEphemeralKey();
});
app.UseMvc();
app.Run(async context =>
{
await context.Response.WriteAsync("Hello World!");
});
}
}
AuthorizationProvider.cs
public sealed class AuthorizationProvider : OpenIdConnectServerProvider
{
public override Task ValidateTokenRequest(ValidateTokenRequestContext context)
{
// Reject the token requests that don't use
// grant_type=password or grant_type=refresh_token.
if (!context.Request.IsPasswordGrantType() &&
!context.Request.IsRefreshTokenGrantType())
{
context.Reject(
error: OpenIdConnectConstants.Errors.UnsupportedGrantType,
description: "Only grant_type=password and refresh_token " +
"requests are accepted by this server.");
return Task.FromResult(0);
}
// Since there's only one application and since it's a public client
// (i.e a client that cannot keep its credentials private), call Skip()
// to inform the server that the requ以上是关于配置授权服务器端点的主要内容,如果未能解决你的问题,请参考以下文章
无法使用“/connect/authorize”端点从 IdentityServer4 获取授权码
通过 REST 端点进行 Spring Security 身份验证/授权
具有多个grant_type的Spring Oauth2授权服务器用户信息端点不起作用
在不中断授权流程的情况下替换 OpenIdConnectOptions 配置中的发现文档端点 (OpenID Connect .Net Core 3.1)