[C#] OWIN OAUTH 实现数据持久化和分布式部署

参考资料: 1.[ASP.NET] 结合Web API在OWIN下实现OAuth

                2.在ASP.NET中基于Owin OAuth使用Client Credentials Grant授权发放Token

 

本文使用WebAPI+Owin.OAuth 实现 OAuth认证服务以及资源获取认证

主要讲述如何对令牌(Token)进行持久化存储,以及分布式认证

如果您也感兴趣,可先参考上边两篇文章进行搭建 您的OAuth程序

 

背景:

  使用 WebAPI+Owin.OAuth 非常便捷的搭建起了OAuth认证以及Api接口管控之后,发现了一些不符合使用场景的问题。由于公司数据量大,需要认证的API较多,其中有一些比较重要的API,如登陆的API接口,如果认证服务出现异常,将会导致多系统无法正常访问。所以我们需要关注认证服务的稳定性,正常情况下我们会进行分布式架设认证服务,通过负载均衡实现多服务器备源,保证系统稳定使用。

  Owin.OAuth认证流程十分便捷:Client端申请AccessToken时,Owin.OAuth会自动认证,并生成返回Token,这个过程会把Token存储在服务端程式中,当Client调用API时,Owin.OAuth又会帮助你验证服务端存储的Token;开发者几乎不用编写任何代码就实现了OAuth认证,但这至少会带来两个问题:

         1:资源接口必须和认证服务在同一个项目中

         2.无法多服务器分布部署,因为你不能保证Client每次请求都发生在同一台服务上

   所以我们需要获取并存储Token,然后使用我们存储的Token对Client的请求进行验证

 

实现:

    其他关于认证服务和资源接口的搭建大家可以参考上边两篇文章,这边主要讲上述文章没有的内容

  1.如何获取TOKEN

           Owin.OAuth会自动生成Token并返回给客户端,这个过程未对服务端开放,但我们可以通过重写OAuthAuthorizationServerProvider中的TokenEndpointResponse方法来实现Token的获取

代码如下(ps:如果你不知这段代码应该加在哪里,我建议你先阅读一下 参考资料的两篇文章)

public override async Task TokenEndpointResponse(OAuthTokenEndpointResponseContext context)
        {
            //成功获取到Token
            var token = context.AccessToken;
            //获取到Token的生存时间
            var expiresUtc = context.Properties.ExpiresUtc;

            //存储到数据库 
            //dal.Insert(token,expiresUtc)

            //调用基类方法
            await base.TokenEndpointResponse(context);
        }

这样我们就可以成功的把 Token获取并存入数据库了,用于多服务器认证

 

   2.如何自定义验证Token

             单服务器验证权限时十分简单,我们只需要在API上加上[Authorize]就可以了如下:

[Authorize]
[HttpGet]
public HttpResponseMessage Get()
{
    return new HttpResponseMessage { Content = new StringContent("Hello World!", Encoding.GetEncoding("UTF-8"), "text/plain") };
}

           但该标签只能验证本地的 Token 无法验证我们存储在数据库中的Token,这时我们需要重写一下AuthorizeAttribute类了

代码如下

 public class TokenAuthorizeAttribute : AuthorizeAttribute
    {
        DAL.OAuthDAL dal = new DAL.OAuthDAL();
        public override void OnAuthorization(HttpActionContext actionContext)
        {
            base.OnAuthorization(actionContext);
        }

        protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
        {
            //这里你可以填写自己的异常描述
            base.HandleUnauthorizedRequest(actionContext);
        }

        protected override bool IsAuthorized(HttpActionContext actionContext)
        {
            //需要先验证一下Headers中是否有 Authorization 参数
            if (actionContext.Request.Headers.Authorization == null)
            {
                return false;
            }
            bool isok = false;

            //通过数据库验证Token是否有效
            //isok=dal.Check(actionContext.Request.Headers.Authorization.Parameter)

            //返回验证结果
            return isok;
        }
    }

这时候我们有了一个新的类 TokenAuthorizeAttribute,我们使用它来帮我们验证接口

[TokenAuthorize]
[HttpGet]
public HttpResponseMessage Get()
{
   return new HttpResponseMessage { Content = new StringContent("Hello World!", Encoding.GetEncoding("UTF-8"), "text/plain") };
}

这样我们就可以对认证服务进行多服务器架设部署,以及认证服务与资源接口分离了

结尾:

     这些只是我在开发过程中遇见的问题和解决方案,不一定是最好的方法。

     大家有什么好的方法也可以指教一下我。

然后:

     说到最后,在我做OAuth这几天,我的理解是:OAuth只是提供了一种安全,开放的授权流程,它只关注两点:1.如何生成获取令牌;2.如何验证令牌!它本身并未实现任何代码!如果您的需求比较简单,您可以直接引用Nuget上的包进行快速开发,如果您的需求比较复杂,您也可以直接实现生成令牌和验证令牌

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值