zoukankan      html  css  js  c++  java
  • ASP.NET OAuth 2.0 新手上路

    OAuth2.0资料

    初衷:一直想整理授权系列demo,让自己项目高端大尚,列出新手授权系列,帮助小白程序员不用在为授权头疼      

            OAuth 允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的 2 小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth 让用户可以授权第三方网站访问他们存储在另外服务提供者的某些特定信息,而非所有内容。

    以上概念来自:https://zh.wikipedia.org/wiki/OAuth

    详细理论知识,参考文章如下文章,本文章重在实践

    1.http://www.cnblogs.com/lanxiaoke/p/6358332.html

    2.https://www.cnblogs.com/selimsong/p/8037717.html

    3.http://www.cnblogs.com/xishuai/p/aspnet-webapi-owin-oauth2.html

    项目实践开发

    步骤1和步骤2都行,看官乐意就行

    步骤1

    通过NuGet安装

    Microsoft.Owin.Security.OAuth

    Owin Microsoft.Owin.Host.SystemWeb(重点)

    步骤2

    Owin Microsoft.Owin.Host.SystemWeb(重点)

    Microsoft.Owin.Security.OAuth

    Microsoft.Owin.Security.Cookies(可忽略)

    Microsoft.AspNet.Identity.Owin

    重点在于步骤1少了一个核心dll,少了这个核心dll无法启动部署owin

    新增Startup.cs

    [assembly: OwinStartup(typeof(OAuth2.Startup))]
    namespace OAuth2
    {
        public partial class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                ConfigureAuth(app);
            }
        }
    }

    Owin Microsoft.Owin.Host.SystemWeb 通过这个dll,程序启动时候注册,如果不引用,该方法不会生效,看官可以打个断点试一试

    新增Startup.Auth.cs

    namespace OAuth2
    {
        public partial class Startup
        {
            public void ConfigureAuth(IAppBuilder app)
            {
                app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()
                {
                    //从url中获取token,兼容hearder方式
                    //Provider = new QueryStringOAuthBearerProvider("access_token")
                });
                var OAuthOptions = new OAuthAuthorizationServerOptions
                {
                    AllowInsecureHttp = true,
                    TokenEndpointPath = new PathString("/token"), //获取 access_token 认证服务请求地址
                    AuthorizeEndpointPath = new PathString("/authorize"), //获取 authorization_code 认证服务请求地址
                    AccessTokenExpireTimeSpan = TimeSpan.FromSeconds(3600), //access_token 过期时间
    
                    Provider = new OpenAuthorizationServerProvider(), //access_token 相关认证服务
                    AuthorizationCodeProvider = new OpenAuthorizationCodeProvider(), //authorization_code 认证服务
                    RefreshTokenProvider = new OpenRefreshTokenProvider() //refresh_token 认证服务
                };
    
                app.UseOAuthBearerTokens(OAuthOptions); //表示 token_type 使用 bearer 方式
    
    
    
            }
        }
    
        public class QueryStringOAuthBearerProvider : OAuthBearerAuthenticationProvider
        {
            readonly string _name;
    
            public QueryStringOAuthBearerProvider(string name)
            {
                _name = name;
            }
    
            public override Task RequestToken(OAuthRequestTokenContext context)
            {
                var value = context.Request.Query.Get(_name);
    
                if (!string.IsNullOrEmpty(value))
                {
                    context.Token = value;
                }
    
                return Task.FromResult<object>(null);
            }
        }
    
    }

    眼光犀利的同学肯定注意到这两个类名相同,命名空间也相同,为什么没有报错  请注意关键字 partial 

    OpenAuthorizationServerProvider示例代码  详细见demo,只提代码需要注意地方

            /// <summary>
            /// 验证 client 信息
            /// </summary>
            public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
            {
                string clientId;
                string clientSecret;
                if (!context.TryGetBasicCredentials(out clientId, out clientSecret))
                {
                    context.TryGetFormCredentials(out clientId, out clientSecret);
                }
    
                if (clientId != "xishuai" || clientSecret != "123")
                {
                    context.SetError("invalid_client", "client or clientSecret is not valid");
                    return;
                }
                context.Validated();
            }

            public string BaseString()
            {
                string clientId = "xishuai";
                string clientSecret = "123";
                return Convert.ToBase64String(Encoding.ASCII.GetBytes(clientId + ":" + clientSecret));
            }
    验证生效如图 按照如下格式 key:value,然后base64编码 
    context.TryGetBasicCredentials 否则解析不了 验证不通过

    OpenAuthorizationCodeProvider示例代码 详细见demo

    OpenRefreshTokenProvider 示例代码 详细见demo

    新增ValueController.cs

    public class ValueController : ApiController
        {
            // GET api/values  access_token验证才能访问
            [Authorize]
            [HttpGet]
            public IEnumerable<string> Index()
            {
                return new string[] { "value1", "value2" };
            }
            
    //获取授权code [HttpGet] [Route(
    "api/authorization_code")] public HttpResponseMessage Get(string code) { return new HttpResponseMessage() { Content = new StringContent(code, Encoding.UTF8, "text/plain") }; } }

    新增OAuthon2Controller.cs

        public class OAuthon2Controller : Controller
        {
            //根据你项目端口
            private const string HOST_ADDRESS = "http://localhost:60903";
    
            // GET: OAuthon2   直接获取授权code链接,方便获取code
            public string Index()
            {
                string clientId = "xishuai";
                string url = $"{HOST_ADDRESS}/authorize?grant_type=authorization_code&response_type=code&client_id={clientId}&redirect_uri={HttpUtility.UrlEncode($"{HOST_ADDRESS}/api/authorization_code")}";
                return url;
            }
    
        }

    根据获取的url,   在将红色部分url复制出来到浏览器中可以获取到code

    现在code有了  将获取access_token

    1

    grant_type:authorization_code

    code:图上红色url返回给你的

    client_id:xishuai 可以理解为appid  自定义,因为代码中固定了,你可以改

    redirect_uri:这个链接你也能改的,接受code 在ValueController.cs   (action:api/authorization_code)

    http://localhost:60903/api/authorization_code

    这个地方需要注意  需要和你获取code redirect_uri保持一致就行

    string url = $"{HOST_ADDRESS}/authorize?grant_type=authorization_code&response_type=code&client_id={clientId}&redirect_uri={HttpUtility.UrlEncode($"{HOST_ADDRESS}/api/authorization_code")}";

    然后你就拿到access_token 去调用 api/Value/Index

    2

    如果这个地方你输入错,会获取失败

    Authorization     Bearer后面空格 在输入access_token 

    源码下载

  • 相关阅读:
    k8s管理
    Docker
    容器技术学习系列(一)-Docker基础知识学习
    Linux系统下DHCP服务安装部署和使用详解
    Linux下配置yum源为阿里云或网易的详解
    一道算法题目(1)
    SS命令和Netstat命令比较
    centos配置redis的主从复制(2)
    centos配置redis的主从复制(1)
    散列表(22)
  • 原文地址:https://www.cnblogs.com/xiaobai123/p/9348074.html
Copyright © 2011-2022 走看看