ASP.NET Core分布式项目实战(Consent 确认逻辑实现)--学习笔记
任务22:Consent 确认逻辑实现
接下来,我们会在上一节的基础上添加两个按钮,同意和不同意,点击之后会把请求 post 到 ConsentController 处理,如果同意会通过 return url 跳转到客户端,如果不同意就会取消,同时客户端也会进行处理
首先完善 ViewModel,我们接收的是按钮,同意或者不同意,以及勾选的 checkbox,最终以 ScopesConsented 的形式返回,一个 string,value 是选中的 scope 的名称
在 ViewModels 下新建 InputConsentViewModel,用于接收 Consented 信息
InputConsentViewModel
public class InputConsentViewModel
{
public string Button { get; set; }
public IEnumerable<string> ScopesConsented { get; set; }
public bool RememberConsent { get; set; }
public string ReturnUrl { get; set; }
}
ReturnUrl 是 AccountController 传到 ConsentController 的,它们之间是通过 get 来传的,传完之后我们在 ConsentController 的 Index 中拿到,我们需要把它绑定到 ConsentViewModel,因为它最终需要通过 post 发回来
ConsentController
[HttpPost]
public async Task<IActionResult> Index(InputConsentViewModel viewModel)
{
viewModel.ReturnUrl
}
这里面可以拿到 ReturnUrl,那它是怎么过来的呢,我们需要在 Consent 的 view 表单 index.cshtml 里面把它填过了,至少需要一个比如 hidden 控件,它里面需要有一个 ReturnUrl
index.cshtml
<form asp-action="Index" method="post">
<input type="hidden" asp-for="ReturnUrl"/>
同时需要在 ConsentViewModel 中加入 ReturnUrl
ConsentViewModel
public string ReturnUrl { get; set; }
接着可以在 ConsentController 的 BuildConsentViewModel 中给 Viewmodel 赋值 ReturnUrl
ConsentController
var vm = CreateConsentViewModel(request, client, resources);
vm.ReturnUrl = returnUrl;
return vm;
完成之后客户端就可以 index.cshtml 中展示的时候有一个隐藏的 ReturnUrl,它最终在 post 的时候会被包含到整个 Form 表单,所以我们可以在 ConsentController 的 Index 中拿到 viewModel 的 ReturnUrl
当我们点击“是”之后会跳转到客户端,如果点击“否”,也会跳转回去,所以我们需要在 ConsentController 的 index 中接收,然后 Redirect 到一个 url,那么在什么地方拿这个 url 呢,我们会用到之前讲到 InteractionService
ConsentController
[HttpPost]
public async Task<IActionResult> Index(InputConsentViewModel viewModel)
{
ConsentResponse consentResponse = null;
if (viewModel.Button == "no")
{
consentResponse = ConsentResponse.Denied;
}
else if (viewModel.Button == "yes")
{
if (viewModel.ScopesConsented != null && viewModel.ScopesConsented.Any())
{
consentResponse = new ConsentResponse
{
RememberConsent = viewModel.RememberConsent,
ScopesConsented = viewModel.ScopesConsented,
};
}
}
if (consentResponse != null)
{
var request = await _identityServerInteractionService.GetAuthorizationContextAsync(viewModel.ReturnUrl);
await _identityServerInteractionService.GrantConsentAsync(request, consentResponse);
return Redirect(viewModel.ReturnUrl);
}
return View();
}
接着在 Consent 的视图中补充显示同意按钮,以及 Remember
Index.cshtml
<div class="row">
<div class="col-sm-8">
<form asp-action="Index" method="post">
<input type="hidden" asp-for="ReturnUrl"/>
@if (Model.IdentityScopes.Any())
{
<div class="panel">
<div class="panel-heading">
<span class="glyphicon glyphicon-user"></span>
用户信息
</div>
<ul class="list-group">
@foreach (var scope in Model.IdentityScopes)
{
@Html.Partial("_ScopeListitem", scope)
}
</ul>
</div>
}
@if (Model.ResourceScopes.Any())
{
<div class="panel">
<div class="panel-heading">
<span class="glyphicon glyphicon-tasks"></span>
应用权限
</div>
<ul class="list-group">
@foreach (var scope in Model.IdentityScopes)
{
@Html.Partial("_ScopeListitem", scope)
}
</ul>
</div>
}
<div>
<label>
<input type="checkbox" asp-for="RememberConsent"/>
<strong>记住我的选择</strong>
</label>
</div>
<div>
<button name="button" value="yes" class="btn btn-primary" autofocus>同意</button>
<button name="button" value="no">取消</button>
@if (!string.IsNullOrEmpty(Model.ClientUrl))
{
<a href="@Model.ClientUrl" class="pull-right btn btn-default">
<span class="glyphicon glyphicon-info-sign"></span>
<strong>@Model.ClientUrl</strong>
</a>
}
</div>
</form>
</div>
</div>
因为最终 AllowRemeberConsent 的 checkbox 需要 psot 回去,就是在 InputConsentViewModel 中有一个 RememberConsent,所以我们需要把 ConsentViewModel 的 AllowRemeberConsent 改为 RememberConsent,
因为 RememberConsent 与 ReturnUrl 这两个属性与 InputConsentViewModel 中一致,所以直接继承
ConsentViewModel
public class ConsentViewModel : InputConsentViewModel
{
public string ClientId { get; set; }
public string ClientName { get; set; }
public string ClientLogoUrl { get; set; }
public string ClientUrl { get; set; }
// 对两种用户分别做出选择
public IEnumerable<ScopeViewModel> IdentityScopes { get; set; }
public IEnumerable<ScopeViewModel> ResourceScopes { get; set; }
}
ConsentController
vm.RememberConsent = client.AllowRememberConsent;
因为在 Config.cs 中传了两个 Resources
Config
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.OpenId,
OpenId 是必须需要的,因为客户端接收的时候使用的是 oidc,它会根据 OpenId 获取用户信息
Startup
.AddOpenIdConnect("oidc", options =>
所以我们需要在 _ScopeListitem.cshtml 中把选中的 scope 传回去
_ScopeListitem.cshtml
<input type="checkbox"
name="ScopesConsented"
id="scopes_@Model.Name"
value="@Model.Name"
checked="@Model.Checked"
disabled="@Model.Required"/>
@if (Model.Required)
{
<input type="hidden" name="ScopesConsented" value="@Model.Name"/>
}
在 Conifg 中添加上 Claims
Conifg
public static List<TestUser> GetTestUsers()
{
return new List<TestUser>
{
new TestUser
{
SubjectId = "1",
Username = "mingsonzheng",
Password = "123456",
Claims = new List<Claim>
{
new Claim("name", "mingson"),
new Claim("website", "https://www.cnblogs.com/MingsonZheng/"),
}
}
};
}
启动服务端,再启动客户端,访问 http://localhost:5001/
自动跳转到 5000 登录
登录之后进入授权界面
勾选 profile ,点击同意,跳转到 5001,说明登录成功
点击 About,查看返回信息
可以看到带回来了 Conifg 里面的信息,这些信息包含在 Profile 中返回回来的
Conifg
new IdentityResources.Profile(),
现在我们已经走完了流程,后面会在这个基础之上进行重构
课程链接
http://video.jessetalk.cn/course/explore
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。
如有任何疑问,请与我联系 (MingsonZheng@outlook.com) 。
ASP.NET Core分布式项目实战(Consent 确认逻辑实现)--学习笔记的更多相关文章
- ASP.NET Core分布式项目实战
ASP.NET Core开发者成长路线图 asp.net core 官方文档 https://docs.microsoft.com/zh-cn/aspnet/core/getting-started/ ...
- 【笔记目录1】ASP.NET Core分布式项目实战
当前标签: ASP.NET Core分布式项目实战 共2页: 1 2 下一页 35.Docker安装Mysql挂载Host Volume GASA 2019-06-20 22:02 阅读:51 评论 ...
- 【笔记目录2】ASP.NET Core分布式项目实战
当前标签: ASP.NET Core分布式项目实战 共2页: 上一页 1 2 11.ClientCredential模式总结 GASA 2019-03-11 12:59 阅读:26 评论:0 10. ...
- 【ASP.NET Core分布式项目实战】(三)整理IdentityServer4 MVC授权、Consent功能实现
本博客根据http://video.jessetalk.cn/my/course/5视频整理(内容可能会有部分,推荐看源视频学习) 前言 由于之前的博客都是基于其他的博客进行开发,现在重新整理一下方便 ...
- ASP.NET Core分布式项目实战-目录
前言 今年是2018年,发现已经有4年没有写博客了,在这4年的时光里,接触了很多的.NET技术,自己的技术也得到很大的进步.在这段时光里面很感谢张队长以及其他开发者一直对.NET Core开源社区做出 ...
- 【ASP.NET Core分布式项目实战】(二)oauth2 + oidc 实现 server部分
本博客根据http://video.jessetalk.cn/my/course/5视频整理(内容可能会有部分,推荐看源视频学习) 资料 我们基于之前的MvcCookieAuthSample来做开发 ...
- 【ASP.NET Core分布式项目实战】(一)IdentityServer4登录中心、oauth密码模式identity server4实现
本博客根据http://video.jessetalk.cn/my/course/5视频整理 资料 OAuth2 流程:http://www.ruanyifeng.com/blog/2014/05/o ...
- 【ASP.NET Core分布式项目实战】(五)Docker制作dotnet core控制台程序镜像
Docker制作dotnet core控制台程序镜像 基于dotnet SDK 新建控制台程序 mkdir /home/console cd /home/console dotnet new cons ...
- 【ASP.NET Core分布式项目实战】(六)Gitlab安装
Gitlab GitLab是由GitLabInc.开发,使用MIT许可证的基于网络的Git仓库管理工具,且具有wiki和issue跟踪功能.使用Git作为代码管理工具,并在此基础上搭建起来的web服务 ...
- 【ASP.NET Core分布式项目实战】(四)使用mysql/mysql-server安装mysql
Docker安装Mysql 拉取镜像 docker pull mysql/mysql-server 运行mysql docker run -d -p : --name mysql01 mysql/my ...
随机推荐
- 如果诸葛亮会编程,用Java写出师表...
继上一篇 "如果诸葛亮用C#写出师表..."后,站长想自己的第一语言是Java,虽然平时工作上用的不多,也用Java实现一遍吧,改改就是了,无非就是: C#的Console.Wri ...
- C#/.Net Core/WPF框架初建(国际化、主题色)
C#/.Net Core/WPF框架初建(国际化.主题色) English | 简体中文 作为 TerminalMACS 的一个子进程模块 - WPF管理端,目前搭建框架部分功能:本地化.国际化.主题 ...
- css - 编写 兼容到ie7的导航
1, index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...
- Blazor SSR/WASM IDS/OIDC 单点登录授权实例5 - Winform 端授权
目录: OpenID 与 OAuth2 基础知识 Blazor wasm Google 登录 Blazor wasm Gitee 码云登录 Blazor SSR/WASM IDS/OIDC 单点登录授 ...
- jcmd的简要分析命令
jcmd的简要分析命令 背景 端午加班一整天. 回到家同事让他们抓取一下堆栈信息好进行分析 连上VPN后就进行了一下处理. 自己简单看了下堆栈的总数等信息. 同事使用工具进行了分析. 我这边其实下过很 ...
- [转帖]Linux磁盘I/O(一):Cache,Buffer和sync
Cache和Buffer的区别 磁盘是一个块设备,可以划分为不同的分区:在分区之上再创建文件系统,挂载到某个目录,之后才可以在这个目录中读写文件.Linux 中"一切皆文件",我们 ...
- [转帖]内存随机访问也比顺序慢,带你深入理解内存IO过程
https://zhuanlan.zhihu.com/p/86513504 平时大家都知道内存访问很快,今天来让我们来思考两个问题: 问题1: 内存访问一次延时到底是多少?你是否会进行大概的估算? 例 ...
- Linux执行SQLSERVER语句的简单方法
背景 因为WTF的原因.经常有人让执行各种乱七八槽的删除语句 因为产品支持了10多种数据库. 这个工作量非常复杂. 为了简单起见,想着能够批量执行部分SQL. 其他的都处理过了,但是SQLSERVER ...
- 一次OOM事故的学习过程
事故过程 周二下午得到消息, 希望帮忙分析dump文件. 告知dump大小为42G大小. 一般机器没这么大的内存进行处理. 建议现场上传到百度云盘, 然后我这边进行下载. 时间进度为: 11.57创建 ...
- pycharm提交代码到gitee
1.在pycharm中下载gitee插件,打开pycharm进入settings页面,查看当前页面version control下是否 有gitee,要是没有点击plugins,在搜索框中搜索gite ...