博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JWT自定义授权服务商-OAuthAuthorizationServerProvider
阅读量:7016 次
发布时间:2019-06-28

本文共 6526 字,大约阅读时间需要 21 分钟。

hot3.png

 

      上一篇博客中,较多篇幅提及有关JWT和Katana项目,没有看过的朋友,建议先了解下:

       在上一篇的基础之上,我们进一步探索,这里以自定义的授权服务提供上为例,实现在自定义

OAuthAuthorizationServerProvider程序。代码入下:

首先,我们需要创建一个类:CustomOAuthProvider,继承自

///     ///     ///     public class CustomOAuthProvider : OAuthAuthorizationServerProvider    {}

其次,重写虚方法,实现验证逻辑。

///         ///         ///         ///         /// 
public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { var username = context.UserName; var password = context.Password; string userid; if (!CheckCredential(username, password, out userid)) { context.SetError("invalid_grant", "The user name or password is incorrect"); context.Rejected(); return Task.FromResult(null); } var ticket = new AuthenticationTicket(SetClaimsIdentity(context, userid, username), new AuthenticationProperties()); context.Validated(ticket); return Task.FromResult(context); } /// /// /// /// ///
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) { context.Validated(); return Task.FromResult(context); }

自定义一个AccessTokenFormat:

///      /// 自定义 jwt token 的格式     ///     public class CustomJwtFormat : ISecureDataFormat
{ private readonly byte[] _secret; private readonly string _issuer; public CustomJwtFormat(string issuer, byte[] secret) { _issuer = issuer; _secret = secret; } ///
/// /// ///
///
public string Protect(AuthenticationTicket data) { var secret = TextEncodings.Base64Url.Decode("IxrAjDoa2FqElO7IhrSrUJELhUckePEPVpaePlS_Xaw");//秘钥 SecurityKey securityKey = new InMemorySymmetricSecurityKey(secret); var signingKey = new InMemorySymmetricSecurityKey(_secret); var issued = data.Properties.IssuedUtc; var expires = data.Properties.ExpiresUtc; return new JwtSecurityTokenHandler().WriteToken(new JwtSecurityToken(_issuer, "Any", data.Identity.Claims, issued.Value.UtcDateTime, expires.Value.UtcDateTime, new SigningCredentials(securityKey, "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256", "http://www.w3.org/2001/04/xmlenc#sha256"))); } ///
/// /// ///
///
public AuthenticationTicket Unprotect(string protectedText) { var jst = new JwtSecurityTokenHandler(); var token = (JwtSecurityToken)jst.ReadToken(protectedText); var identity = new ClaimsIdentity(token.Claims); var ticket = new AuthenticationTicket(identity, new AuthenticationProperties() { }); return ticket; } }

最后,创建一个启动类,配置中间件。

///         ///         ///         ///         public void Configuration(IAppBuilder app)        {            HttpConfiguration config = new HttpConfiguration();            var issuer = "http://localhost:2817/";            var audience = "fNm0EDIXbfuuDowUpAoq5GTEiywV8eg0TpiIVnV8";//观众            var secret = TextEncodings.Base64Url.Decode("IxrAjDoa2FqElO7IhrSrUJELhUckePEPVpaePlS_Xaw");//秘钥            var signingKey = new System.IdentityModel.Tokens.InMemorySymmetricSecurityKey(secret);            //配置JwtBearer授权中间件            app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions()            {                AuthenticationMode = AuthenticationMode.Active,                AuthenticationType = "password",                AllowedAudiences = new[] { audience },                Provider = new OAuthBearerAuthenticationProvider()                {                    OnValidateIdentity = context =>                    {                        context.Ticket.Identity.AddClaim(new System.Security.Claims.Claim(ClaimTypes.NameIdentifier, context.Ticket.Identity.Name));                        return Task.FromResult(context);                    },                    OnRequestToken = (context) =>                    {                        if (context.Token != null)                        {                            context.Response.Headers["WWW-Authorization"] = "Bearer";                            var jst = new JwtSecurityTokenHandler();                            var token = (JwtSecurityToken)jst.ReadToken(context.Token);                            //创建身份                            var identity = new ClaimsIdentity(token.Claims, "JWT");                            context.Request.User = new ClaimsPrincipal(identity);                        }                        return Task.FromResult(context);                    }                },                IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]                {                     new SymmetricKeyIssuerSecurityTokenProvider(issuer, secret)                }            });            //配置OAuth中间件            app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions            {                //生产环境设为false                AllowInsecureHttp = true,                TokenEndpointPath = new PathString("/oauth2/token"),//请求token的路径                AccessTokenExpireTimeSpan = TimeSpan.FromDays(30),//令牌的过期时间                //请求获取token时,验证username, password                Provider = new CustomOAuthProvider(),                //定义token信息格式 --默认TicketDataFormat                AccessTokenFormat = new CustomJwtFormat(issuer, secret),            });            app.UseWebApi(config);//        }

模拟示例:

获取访问令牌:

{"access_token":"BLEx3eE72_P8O__wCRUEhdtMlpPq0pnswmPReBZYAVdueL1p33cfybdcd0mVBFZZFsG8OgK8LBik1ZuDADW-NHul-KM8TXbJzr_dVfs2bw9S-YUNKMkJjY7mHilbF3TEI3o54jGn11R8z2tlp_95oLNVn_D10zyAdKNGs8qtb7gMW_XUCQpkRmVNcEd58h9wREXHYnYjWYyMRYT-rttgvxU5LKU5VsUTpdIFjfx2c17ALqr7d0sqY5LZ3nDh-tNyMvNHgu9ea9G2uHE3CVbulOYb-7EVp4MkpzW8rQ0cTAI","token_type":"bearer","expires_in":2591999}

携带access_token访问资源:

[Authorize]    public class ValuesController : ApiController    {        // GET api/values        public IEnumerable
Get() { var owin = HttpContext.Current.GetOwinContext(); var identity = owin.Request.User; return new string[] { "value1", "value2" }; }}
["value1","value2"]

 

转载于:https://my.oschina.net/lichaoqiang/blog/867896

你可能感兴趣的文章
转: wireshark过滤语法总结
查看>>
获取JAVA对象占用的内存大小
查看>>
[机器学习] ML重要概念:梯度(Gradient)与梯度下降法(Gradient Descent)
查看>>
IOC的实现原理—反射与工厂模式的结合
查看>>
使用gdb调试python程序
查看>>
爬取7160
查看>>
Android安全机制
查看>>
【Eclpise】Eclipse中Tomcat启动失败或者是重启失败
查看>>
安卓APP载入HTML5页面解决方式总结
查看>>
套接字源代码分析
查看>>
centos 7 部署 open-falcon 0.2.0
查看>>
cocos2dx--两个场景切换各函数调用顺序
查看>>
通用的事件侦听器函数
查看>>
Java与.NET兼容的RSA密钥持久化方法
查看>>
Java Jvm运行机制原理
查看>>
php设计模式之工厂方法模式
查看>>
Javascript实现简单的选项卡
查看>>
解决山地车令人讨厌的中轴异响及其他异响问题
查看>>
mysql grant 用户权限总结
查看>>
Java Socket 死循环while如何判断客户端断开
查看>>