当前位置:首页 > Windows程序 > 正文

在OWIN WebAPI中基于OAuth授权【客户端模式(Client Credentials Grant)】

2021-05-24 Windows程序

标签:

适应范围

采用Client Credentials方式,即应用公钥、密钥方式获取Access Token,适用于任何类型应用,但通过它所获取的Access Token只能用于访问与用户无关的Open API,并且需要开发者提前向开放平台申请,成功对接后方能使用。认证服务器不提供像用户数据这样的重要资源,仅仅是有限的只读资源或者一些开放的 API。例如使用了第三方的静态文件服务,如Google Storage或Amazon S3。这样,你的应用需要通过外部API调用并以应用本身而不是单个用户的身份来读取或修改这些资源。这样的场景就很适合使用客户端证书授权,通过此授权方式获取Access Token仅可访问平台授权类的接口。

比如获取App首页最新闻列表,由于这个数据与用户无关,所以不涉及用户登录与授权,但又不想任何人都可以调用这个WebAPI,这样场景就适用[例:比如微信公众平台授权]。

Client Credentials Grant: +---------+ +---------------+ | | | | | |>--(A)- Client Authentication --->| Authorization | | Client | | Server | | |<--(B)---- Access Token ---------<| | | | | | +---------+ +---------------+ Figure 6: Client Credentials Flow 基本流程 

技术分享

A.客户端提供用户名和密码交换令牌
B.认证服务器验证通过,,发放令牌,后面根据这个令牌获取资源即可

服务实现

使用WEBAPI实现,新建一个不启用身份验证空的WEBAPI项目
安装包

Install-Package Microsoft.AspNet.Identity.Owin
Install-Package Microsoft.Owin.Security.OAuth
Install-Package Microsoft.AspNet.WebApi.Owin
Install-Package Microsoft.AspNet.WebApi.WebHost
Install-Package Microsoft.Owin.Host.SystemWeb

OWIN WEBAPI

public partial class Startup { public void ConfigureAuth(IAppBuilder app) { /* app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions { TokenEndpointPath = new PathString("/token"), Provider = new ApplicationOAuthProvider(), AccessTokenExpireTimeSpan = TimeSpan.FromHours(2), AuthenticationMode = AuthenticationMode.Active, //HTTPS is allowed only AllowInsecureHttp = false AllowInsecureHttp = true //ApplicationCanDisplayErrors = false }); app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); */ app.UseOAuthBearerTokens(new OAuthAuthorizationServerOptions { TokenEndpointPath = new PathString("/token"), Provider = new ApplicationOAuthProvider(), //RefreshTokenProvider = new ApplicationRefreshTokenProvider(), AccessTokenExpireTimeSpan = TimeSpan.FromHours(2), AuthenticationMode = AuthenticationMode.Active, //HTTPS is allowed only AllowInsecureHttp = false AllowInsecureHttp = true //ApplicationCanDisplayErrors = false }); } } public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider { /* private OAuth2ClientService _oauthClientService; public ApplicationOAuthProvider() { this.OAuth2ClientService = new OAuth2ClientService(); } */ /// <summary> /// 验证客户[client_id与client_secret验证] /// </summary> /// <param></param> /// <returns></returns> public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) { //:48339/token //grant_type=client_credentials&client_id=irving&client_secret=123456 string client_id; string client_secret; context.TryGetFormCredentials(out client_id, out client_secret); if (client_id == "irving" && client_secret == "123456") { context.Validated(client_id); } else { //context.Response.StatusCode = Convert.ToInt32(HttpStatusCode.OK); context.SetError("invalid_client", "client is not valid"); } return base.ValidateClientAuthentication(context); } /// <summary> /// 客户端授权[生成access token] /// </summary> /// <param></param> /// <returns></returns> public override Task GrantClientCredentials(OAuthGrantClientCredentialsContext context) { /* var client = _oauthClientService.GetClient(context.ClientId); oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, client.ClientName)); */ var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType); oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, "iphone")); var ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties() { AllowRefresh = true }); context.Validated(ticket); return base.GrantClientCredentials(context); } /// <summary> /// 刷新Token[刷新refresh_token] /// </summary> /// <param></param> /// <returns></returns> public override Task GrantRefreshToken(OAuthGrantRefreshTokenContext context) { //enforce client binding of refresh token if (context.Ticket == null || context.Ticket.Identity == null || !context.Ticket.Identity.IsAuthenticated) { context.SetError("invalid_grant", "Refresh token is not valid"); } else { //Additional claim is needed to separate access token updating from authentication //requests in RefreshTokenProvider.CreateAsync() method } return base.GrantRefreshToken(context); } public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context) { if (context.ClientId == "irving") { var expectedRootUri = new Uri(context.Request.Uri, "/"); if (expectedRootUri.AbsoluteUri == context.RedirectUri) { context.Validated(); } } return Task.FromResult<object>(null); } }

资源服务

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/70411.html