接上一篇:IdentityServer4实现OAuth2.0四种模式之隐藏模式

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

一,服务端配置

1,添加客户端

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

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

二,MVC客户端配置

  • 由于和隐藏模式返回token用瞄点的方式不同,授权码是url参数化传递过来的。所以修改一下需要修改一下HTML代码,使其可以显示出参数化的授权码。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script type="text/javascript">
var content = "";
window.onload = function () {
var url = window.location.href; var array = url.split("#");
if (array.length > 1) {
content = array[1];
}
var search = window.location.search;
if (search) {
search = search.substr(1);
var paras = search.split("&");
paras.forEach(element => {
content += element;
content+=";"
});
}
document.getElementById("content").innerHTML = content;
}
</script>
</head>
<body>
<div id="content"></div>
</body>
</html>

三,获取授权码  

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

client_id:客户端Id
redirect_uri=重定向Url,用户登录成功后跳回此地址
response_type=code,固定值,表示获取授权码
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

可以看到已经取到了code。

四,访问被保护的API

1,通过后台访问

 public async Task<IActionResult> GetData(string type,string userName,string password,string code)
{
type = type ?? "client";
var client = new HttpClient();
var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000");
if (disco.IsError)
return new JsonResult(new { err=disco.Error});
TokenResponse token = null;
switch (type)
{
case "client":
token = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest()
{
//获取Token的地址
Address = disco.TokenEndpoint,
//客户端Id
ClientId = "apiClientCd",
//客户端密码
ClientSecret = "apiSecret",
//要访问的api资源
Scope = "secretapi"
});
break;
case "password":
token = await client.RequestPasswordTokenAsync(new PasswordTokenRequest()
{
//获取Token的地址
Address = disco.TokenEndpoint,
//客户端Id
ClientId = "apiClientPassword",
//客户端密码
ClientSecret = "apiSecret",
//要访问的api资源
Scope = "secretapi",
UserName =userName,
Password = password
});
break;
case "code":
token = await client.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest()
{
Address = disco.TokenEndpoint,
ClientId = "apiClientCode",
//客户端密码
ClientSecret = "apiSecret",
Code = code,
RedirectUri = "https://localhost:5002/auth.html"
});
break;
}
if (token.IsError)
return new JsonResult(new { err = token.Error });
client.SetBearerToken(token.AccessToken);
string data = await client.GetStringAsync("https://localhost:5001/api/identity");
JArray json = JArray.Parse(data);
return new JsonResult(json);
}

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

2,通过原生Http请求访问

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

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

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

四种模式讲完,IdentityServer.Config.GetIdentityResouce还没用上呢!因为这四种模式只涉及到IdentityServer4的OAuth2.0特性,OpenId部分还没有涉及,请看下一篇

IdentityServer4:OpenIdConnect

IdentityServer4实现OAuth2.0四种模式之授权码模式的更多相关文章

  1. IdentityServer4 实现OAuth2.0四种模式之密码模式

    接上一篇:IdentityServer4 实现OAuth2.0四种模式之客户端模式,这一篇讲IdentityServer4 使用密码模式保护API访问. 一,IdentityServer配置 1,添加 ...

  2. IdentityServer4实现Oauth2.0四种模式之隐藏模式

      接上一篇:IdentityServer4实现OAuth2.0四种模式之密码模式,密码模式将用户的密码暴露给了客户端,这无疑是不安全的,隐藏模式可以解决这个问题,由用户自己在IdentityServ ...

  3. IdentityServer4实现OAuth2.0四种模式之客户端模式

    一,准备内容 IdentityServer4 是Asp.net core的一个中间件,用于添加符合OpenId Connect和OAuth2.0规范的终端到Asp.net Core应用.在这里简单介绍 ...

  4. Oauth2认证模式之授权码模式实现

    Oauth2认证模式之授权码模式(authorization code) 本示例实现了Oauth2之授权码模式,授权码模式(authorization code)是功能最完整.流程最严密的授权模式.它 ...

  5. Owin + WebApi + OAuth2 搭建授权模式(授权码模式 Part I)

    绪 最近想要整理自己代码封装成库,也十分想把自己的设计思路贴出来让大家指正,奈何时间真的不随人意. 想要使用 OWIN 做中间件服务,该服务中包含 管线.授权 两部分.于是决定使用 webapi .O ...

  6. OAuth2.0 四种授权模式

    OAuth2.0简单笔记(四种授权模式) 金天:坚持写东西,不是一件容易的事,换句话说其实坚持本身都不是一件容易的事.如果学习有捷径,那就是不断实践,不断积累.写笔记,其实是给自己看的,是体现积累的一 ...

  7. Oauth2.0认证---授权码模式

    目录: 1.功能描述 2.客户端的授权模式 3.授权模式认证流程 4.代码实现 1.功能描述 OAuth在"客户端"与"服务提供商"之间,设置了一个授权层(au ...

  8. oauth2.0授权码模式详解

    授权码模式原理 授权码模式(authorization code)是功能最完整.流程最严密的授权模式.它的特点就是通过客户端的后台服务器,与"服务提供商"的认证服务器进行互动. 它 ...

  9. IdentityServer4系列 | 授权码模式

    一.前言 在上一篇关于简化模式中,通过客户端以浏览器的形式请求IdentityServer服务获取访问令牌,从而请求获取受保护的资源,但由于token携带在url中,安全性方面不能保证.因此,我们可以 ...

随机推荐

  1. firewalld添加/删除服务service,端口port

    启动CentOS/RHEL 7后,防火墙规则设置由firewalld服务进程默认管理. 一个叫做firewall-cmd的命令行客户端支持和这个守护进程通信以永久修改防火墙规则. # firewall ...

  2. D3.js的v5版本入门教程(第九章)——完整的柱状图

    D3.js的v5版本入门教程(第九章) 一个完整的柱状图应该包括的元素有——矩形.文字.坐标轴,现在,我们就来一一绘制它们,这章是前面几章的综合,这一章只有少量新的知识点,它们是 d3.scaleBa ...

  3. [Beta]第八次 Scrum Meeting

    [Beta]第八次 Scrum Meeting 写在前面 会议时间 会议时长 会议地点 2019/5/18 22:00 10min 大运村公寓6F寝室 附Github仓库:WEDO 例会照片 工作情况 ...

  4. javassist使用全解析

    Java 字节码以二进制的形式存储在 .class 文件中,每一个 .class 文件包含一个 Java 类或接口.Javaassist 就是一个用来 处理 Java 字节码的类库.它可以在一个已经编 ...

  5. 【转】vue中样式被覆盖的问题,vue中的style不生效

    转载:http://www.cnblogs.com/shangjun6/p/11416054.html 在我们引入外部的样式时,发现自己无论如何都改不了外部的样式,自己的样式老被覆盖,究其原因还是我们 ...

  6. 解决vs2010按ctrl+f5,调试窗口一闪而过的方法

    vs2010调试按F5与按Ctrl+F5有什么区别 Ctrl F5测试运行后不自动推出控制台,直接按F5会自动退出去 解决vs2010按ctrl+f5,调试窗口一闪而过的方法 http://hi.ba ...

  7. 数据库sql优化总结之5--数据库SQL优化大总结

    数据库SQL优化大总结 小编最近几天一直未出新技术点,是因为小编在忙着总结整理数据库的一些优化方案,特此奉上,优化总结较多,建议分段去消化,一口吃不成pang(胖)纸 一.百万级数据库优化方案 1.对 ...

  8. 在evernote中如何使序号正常连续?

    答: 在二级内容之前按Shift + Enter键,再次换行即可序号正常,示例如下: 1. 第一行(在此处按下Shift+Enter键) 第一行第一列(在此处按下Shift+Enter键) 第一行第二 ...

  9. Python将print输出内容保存到指定文件中

    #!/usr/bin/python # -*- coding: utf- -*- import sys import os class Logger(object): def __init__(sel ...

  10. 《精通CSS第3版》(6)内容布局(定位+水平布局)