tnblog
首页
视频
资源
登录

IdentityServer4实现OAuth2.0四种模式之授权码模式

7086人阅读 2020/1/3 16:37 总访问:63874 评论:0 收藏:1 手机
分类: .NET

授权码模式隐藏码模式最大不同是授权码模式不直接返回token,而是先返回一个授权码,然后再根据这个授权码去请求token。这比隐藏模式更为安全。从应用场景上来区分的话,隐藏模式适应于全前端的应用,授权码模式适用于有后端的应用,因为客户端根据授权码去请求token时是需要把客户端密码转进来的,为了避免客户端密码被暴露,所以请求token这个过程需要放在后台。

一,服务端配置

1,添加客户端

新建一个支持授权码模式的客户端,请求token时需要客户端密码,所以需要设置clientSecret。登录成功后重定向地址依然用之前建立的HTML页面。

  1. new Client()
  2.                {
  3.                    //客户端Id
  4.                     ClientId="apiClientCode",
  5.                     ClientName="ApiClient for Code",
  6.                     //客户端密码
  7.                     ClientSecrets={new Secret("apiSecret".Sha256()) },
  8.                     //客户端授权类型,Code:授权码模式
  9.                     AllowedGrantTypes=GrantTypes.Code,
  10.                     //允许登录后重定向的地址列表,可以有多个
  11.                    RedirectUris = {"https://localhost:5002/auth.html"},
  12.                     //允许访问的资源
  13.                     AllowedScopes={
  14.                        "secretapi"
  15.                    }
  16.                }

二,MVC客户端配置

由于和隐藏模式返回token用瞄点的方式不同,授权码是url参数化传递过来的。所以修改一下需要修改一下HTML代码,使其可以显示出参数化的授权码。

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.     <meta charset="utf-8" />
  5.     <title></title>
  6.     <script type="text/javascript">
  7.         var content = "";
  8.         window.onload = function ({
  9.             var url = window.location.href;
  10.  
  11.             var array = url.split("#");
  12.             if (array.length > 1) {
  13.                 content = array[1];
  14.             }
  15.             var search = window.location.search;
  16.             if (search) {
  17.                 search = search.substr(1);
  18.                 var paras = search.split("&");
  19.                 paras.forEach(element => {
  20.                     content += element;
  21.                     content+=";"
  22.                 });
  23.             }
  24.             document.getElementById("content").innerHTML = content;
  25.         }
  26.     </script>
  27. </head>
  28. <body>
  29.     <div id="content"></div>
  30. </body>
  31. </html>


三,获取授权码

 根据OAuth2.0协议,传递以下参数,传递地址还是参数IdentityServer4的Discover说明中的authorization_endpoint节点值http://localhost:5000/connect/authorize

  1. client_id:客户端Id
  2. redirect_uri=重定向Url,用户登录成功后跳回此地址
  3. response_type=code,固定值,表示获取授权码
  4. scope=secretapi,此token需要访问的api

拼接url:http://localhost:5000/connect/authorize?client_id=apiClientCode&redirect_uri=https://localhost:5002/auth.html&response_type=code&scope=secretapi

在浏览器中访问此url,会跳转到用户登录界面,用之前创建的用户apiUser和密码登录后浏览器会自动跳转回设置的重定向Url拼接url:http://localhost:5000/connect/authorize?client_id=apiClientCode&redirect_uri=https://localhost:5002/auth.html&response_type=code&scope=secretapi

 

 

 

 可以看到已经取到了code。

四,访问被保护的API

1,通过后台访问

  1. public async Task<IActionResult> GetData(string type,string userName,string password,string code)
  2.        {
  3.            type = type ?? "client";
  4.            var client = new HttpClient();
  5.            var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000");
  6.            if (disco.IsError)
  7.                return new JsonResult(new { err=disco.Error});
  8.            TokenResponse token = null;
  9.            switch (type)
  10.            {
  11.                case "client":
  12.                    token = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest()
  13.                    {
  14.                        //获取Token的地址
  15.                        Address = disco.TokenEndpoint,
  16.                        //客户端Id
  17.                        ClientId = "apiClientCd",
  18.                        //客户端密码
  19.                        ClientSecret = "apiSecret",
  20.                        //要访问的api资源
  21.                        Scope = "secretapi"
  22.                    });
  23.                    break;
  24.                case "password":
  25.                    token = await client.RequestPasswordTokenAsync(new PasswordTokenRequest()
  26.                    {
  27.                        //获取Token的地址
  28.                        Address = disco.TokenEndpoint,
  29.                        //客户端Id
  30.                        ClientId = "apiClientPassword",
  31.                        //客户端密码
  32.                        ClientSecret = "apiSecret",
  33.                        //要访问的api资源
  34.                        Scope = "secretapi",
  35.                        UserName =userName,
  36.                        Password = password
  37.                    });
  38.                    break;
  39.                case "code":
  40.                    token = await client.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest()
  41.                    {
  42.                        Address = disco.TokenEndpoint,
  43.                        ClientId = "apiClientCode",
  44.                        //客户端密码
  45.                        ClientSecret = "apiSecret",
  46.                        Code = code,
  47.                        RedirectUri = "https://localhost:5002/auth.html"
  48.                    });
  49.                    break;
  50.            }
  51.            if (token.IsError)
  52.                return new JsonResult(new { err = token.Error });
  53.            client.SetBearerToken(token.AccessToken);
  54.            string data = await client.GetStringAsync("https://localhost:5001/api/identity");
  55.            JArray json = JArray.Parse(data);
  56.            return new JsonResult(json);
  57.        }

直接访问:https://localhost:5002/home/getdata?type=code&code=93516f5af0c644c13228a66954d6c892816d358704536b6ca4e6623f6b00dee0


2,通过原生Http请求访问

根据OAuth2.0协议,传以下参数,地址则是之前在客户端模式和密码模式获取token时用到的地址,可以在identityServer4的discover文档中找到。

  1. client_id:客户端Id
  2. client_secret:客户端密码
  3. grant_type:authorization_code,固定值
  4. redirect_uri=重定向Url,用户登录成功后跳回此地址
  5. code:获取到的授权码
  6. scope=secretapi,此token需要访问的api


 

 获取到token就可以访问api了。

四种模式讲完,IdentityServer.Config.GetIdentityResouce还没用上呢!因为这四种模式只涉及到IdentityServer4的OAuth2.0特性


评价

IdentityServer4退出登录跳转到原页面

IdentityServer4退出登录,注销登录已经封装好了我们使用其实很简单//注销登录 publicIActionResultLogout() { returnSig...

IdentityServer4 单点登陆

hello大家好又见面了今天给大家分享一下identityServer4 首选我们先来了解一下什么是identityServer. 什么是单点登录统一...

IdentityServer4实现单点登录】

今天记录一下 NET Core id4的单点登录虽然现在很流行 也很高大上但是第一次玩 还是很多的坑的。简单来讲就是一个项目登录了...

NET Core【IdentityServer4单点登录】+【退出登录】

第一天接触NetCore,感觉坑很多,其他都还良好比如说我们现在有三个系统,一个是商品系统,一个是订单系统,另外一个就是单...

IdentityServer4 退出登录+EF

登录讲完了 我们讲一下退出登录退出比较简单啦[HttpGet] publicasyncTask&lt;IActionResult&gt;Logout(stringlogoutId) {...

IdentityServer4携带自定义的Claim

identityServer4要携带自定义的Claim,仅仅传递Claim是不行的还需要实现IProfileService方法才行publicclassImplicitProfil...

css实现简单矩形对话框

在前端做项目时,我们可能会遇到写对话框的需求,这次做视频会议页面就遇到了,记录下日后有个参照。//网页部分 &lt;divcla...

C.Net 配合小程序实现经过第三方服务器中转文件

某些时候,微信小程序前段上传文件的时候需要经过第三方服务器再将文件上传到客户的服务器;操作如下:1:(小程序内向中端服...

.Net实现QQ邮箱发送邮件功能

1、微软已经帮我们封装好了发送邮件的类MailMessage,MailMessage类构造一些邮件信息,然后通过SmtpClient进行邮件发送。Mai...

网页上传文件断点续传的实现,无视文件大小上传,以及datatables基本用法

首先明白js是客户带执行代码,c#是服务器上执行代码。本地文件需要用到js处理,服务器端接受c#代码处理1.HTML页面,文件信...

javascript阻止scroll事件多次执行的思路及实现

//测试代码 window.onscroll=function(){ alert(&quot;haha&quot;); }鼠标滑动之后一直点击提示框才可以,我想要的是鼠...

实现返回顶部效果

实现返回顶部效果2:http://www.tnblog.net/aojiancc2/article/details/2677实现的效果如下可以点击它返回到首页去html部分...

Vue.js+Layer实现表格数据绑定与更新

一:使用Vue.js绑定好数据与更新事件 使用v-on绑定好事件,在事件里边直接把该行数据传递进去,在更新方法里边就可以直接...

ASP.NET 使用Redis实现单点登录

Session介绍 session是用来记录客户端用户信息的,在客户端第一次向服务器发起请求的时候服务器会生成一个sessionid并返回...

Vue.js 实现省市联动

HTML代码&lt;divid=&quot;pro_citys&quot;&gt; 省:&lt;selectid=&quot;provice&quot;v-on:change=&quot;prochange()&quo...
没有个性,不需要签名
排名
41
文章
14
粉丝
3
评论
3
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术
犹豫,就会败北。