授权同意页面与登录一样首先要分析页面的需要什么模型元素后建立相关的模型类

界面的话就 记住选择  、按钮、RuturnUrl、以及选择的资源Scope

 /// <summary>/// 主要绑定Consent界面上的一些模型/// </summary>public class ConsentViewModel{public string ReturnUrl { get; set; }public bool RememberConsent { get; set; }public string Button { get; set; }public IEnumerable<string> ScopesConsented { get; set; }}

ConsentViewModel

这里可以注意到还有Idr4的对应数据 比如客户端的一些信息,如名称、Logo、客户端的授权Scope等等、这里根据需要可以多写一些

/// <summary>/// 主要绑定Idr4中关于Consent界面交互的实体字段/// </summary>public class Idr4ConsentViewModel : ConsentViewModel{public string ClientName { get; set; }public string ClientUrl { get; set; }public string ClientLogoUrl { get; set; }public bool AllowRememberConsent { get; set; }public IEnumerable<Idr4ScopeViewModel> IdentityScopes { get; set; }public IEnumerable<Idr4ScopeViewModel> ResouceScopes { get; set; }}

Idr4ConsentViewModel

这里同样需要构建Idr4Consent页面展示模型

 private async Task<Idr4ConsentViewModel> CreateIdr4ConsentViewModelAsync(string ReturnUrl){var request = await _identityServerInteractionService.GetAuthorizationContextAsync(ReturnUrl);if (request != null){//通过客户端id获取客户端信息var clientModel = await _clientStore.FindEnabledClientByIdAsync(request.ClientId);if (clientModel != null){//获取资源Scope信息 这里包括了两种 一种是IdentityResource 和ApiResourcevar resources = await _resourceStore.FindEnabledResourcesByScopeAsync(request.ScopesRequested);//获取所有的权限// var resources = await _resourceStore.FindEnabledResourcesByScopeAsync(clientModel.AllowedScopes);if (resources != null && (resources.ApiResources.Any() || resources.IdentityResources.Any())){//构造界面需要的模型var vm = new Idr4ConsentViewModel();//界面初始化时候vm.RememberConsent = true; //默认truevm.ScopesConsented = Enumerable.Empty<string>();vm.ReturnUrl = ReturnUrl;//构建关于Client的信息vm.ClientName = clientModel.ClientName;vm.ClientUrl = clientModel.ClientUri;vm.ClientLogoUrl = clientModel.LogoUri;vm.AllowRememberConsent = clientModel.AllowRememberConsent;vm.IdentityScopes = resources.IdentityResources.Select(x => new Idr4ScopeViewModel{Name = x.Name,DisplayName = x.DisplayName,Description = x.Description,Emphasize = x.Emphasize,Required = x.Required,Checked = vm.ScopesConsented.Contains(x.Name) || x.Required}).ToArray();vm.ResouceScopes = resources.ApiResources.SelectMany(x => x.Scopes).Select(k => new Idr4ScopeViewModel{Name = k.Name,DisplayName = k.DisplayName,Description = k.Description,Emphasize = k.Emphasize,Required = k.Required,Checked = vm.ScopesConsented.Contains(k.Name) || k.Required}).ToArray();//离线if (ConsentOptions.EnableOfflineAccess && resources.OfflineAccess){vm.ResouceScopes = vm.ResouceScopes.Union(new Idr4ScopeViewModel[] {new Idr4ScopeViewModel{Name = IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess,DisplayName = ConsentOptions.OfflineAccessDisplayName,Description = ConsentOptions.OfflineAccessDescription,Emphasize = true,Checked = vm.ScopesConsented.Contains(IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess)}});}return vm;}else{//客户端Scope不存在 可以在界面提示并记录日志return null;}}else{//客户端不存在 可以在界面提示并记录日志return null;}}return null;}

CreateIdr4ConsentViewModelAsync

里面具体的话无非就是获取更具ReturnUrl地址获取用户交互接口相关的数据信息以及页面Scope绑定以及获取

值得注意的 选项required这种情况在界面上是 disabled属性 后台Action中是获取不到的,所以需要加一些影藏域

这里是Get Consent

 [HttpGet]public async Task<IActionResult> Consent(string ReturnUrl){//获取请求授权信息var vm = await CreateIdr4ConsentViewModelAsync(ReturnUrl);if (vm != null){return View(vm);}return View();}

Consent Get

[HttpPost][ValidateAntiForgeryToken]public async Task<IActionResult> Consent(Idr4ConsentViewModel model){ConsentResponse consentResponse = null;if (model == null){ModelState.AddModelError("", "数据发送异常");}//有没有选择授权if (model.ScopesConsented == null || model.ScopesConsented.Count() == 0){ModelState.AddModelError("", "请至少选择一个权限");}//同意授权if (model.Button == "yes"){//选择了授权Scopeif (model.ScopesConsented != null && model.ScopesConsented.Any()){var scopes = model.ScopesConsented;if (ConsentOptions.EnableOfflineAccess == false){scopes = scopes.Where(x => x != IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess);}consentResponse = new ConsentResponse{RememberConsent = model.RememberConsent,ScopesConsented = scopes};}}//不同意授权else if (model.Button == "no"){consentResponse = ConsentResponse.Denied;}else{var vm1 = await CreateIdr4ConsentViewModelAsync(model.ReturnUrl);return View(vm1);}//无论同意还是不同意都是需要跳转if (consentResponse != null){var request = await _identityServerInteractionService.GetAuthorizationContextAsync(model.ReturnUrl);if (request == null){ModelState.AddModelError("", "客户端登录验证不匹配");}//if (consentResponse == ConsentResponse.Denied)//{//    string url = new Uri(request.RedirectUri).Authority;//    return Redirect(url);//}//沟通Idr4服务端实现授权await _identityServerInteractionService.GrantConsentAsync(request, consentResponse);return Redirect(model.ReturnUrl);}var vm = await CreateIdr4ConsentViewModelAsync(model.ReturnUrl);if (vm != null){return View(vm);}return View();}

Consent Post

@using SSOServer.Models;
@model Idr4ConsentViewModel
@{Layout = null;
}<!DOCTYPE html><html>
<head><meta name="viewport" content="width=device-width" /><title>确认授权页面</title>
</head>
<body><div><div><img src="@Model.ClientLogoUrl" width="100" height="100" /></div><div>@Model.ClientName</div><div><a href="@Model.ClientUrl" target="_blank"> @Model.ClientUrl</a></div></div><div><div asp-validation-summary="All"></div><form asp-action="Consent" class="consent-form"><input type="hidden" asp-for="ReturnUrl" /><div>请求你的授权</div>@if (Model.IdentityScopes.Any()){<div class="panel panel-default consent-buttons"><div class="panel-heading"><span class="glyphicon glyphicon-user"></span>个人信息</div><ul class="list-group">@foreach (var scope in Model.IdentityScopes){<li class="list-group-item"><label><input class="consent-scopecheck"type="checkbox"name="ScopesConsented"id="scopes_@scope.Name"value="@scope.Name"checked="@scope.Checked"disabled="@scope.Required" />@if (scope.Required){<input type="hidden"name="ScopesConsented"value="@scope.Name" />}<strong>@scope.DisplayName</strong>@if (scope.Emphasize){<span class="glyphicon glyphicon-exclamation-sign"></span>}</label>@if (scope.Required){<span><em>(必需)</em></span>}@if (scope.Description != null){<div class="consent-description"><label for="scopes_@scope.Name">@scope.Description</label></div>}</li>}</ul></div>}@if (Model.ResouceScopes.Any()){<div class="panel panel-default"><div class="panel-heading"><span class="glyphicon glyphicon-tasks"></span>应用授权</div><ul class="list-group">@foreach (var scope in Model.ResouceScopes){<li class="list-group-item"><label><input class="consent-scopecheck"type="checkbox"name="ScopesConsented"id="scopes_@scope.Name"value="@scope.Name"checked="@scope.Checked"disabled="@scope.Required" />@if (scope.Required){<input type="hidden"name="ScopesConsented"value="@scope.Name" />}<strong>@scope.DisplayName</strong>@if (scope.Emphasize){<span class="glyphicon glyphicon-exclamation-sign"></span>}</label>@if (scope.Required){<span><em>(必需)</em></span>}@if (scope.Description != null){<div class="consent-description"><label for="scopes_@scope.Name">@scope.Description</label></div>}</li>}</ul></div>}@if (Model.AllowRememberConsent){<div class="consent-remember"><label><input class="consent-scopecheck" asp-for="RememberConsent" /><strong>记住选择</strong></label></div>}<div class="consent-buttons"><button name="button"  value="yes" class="btn btn-primary" autofocus>是, 允许</button><button name="button" value="no" class="btn">否,不允许</button></div></form></div></body>
</html>

Consent View

转载于:https://www.cnblogs.com/liyouming/p/8857456.html

IdentityServer4揭秘---Consent(同意页面)相关推荐

  1. IdentityServer4揭秘---登录

    IdentityServer4默认提供了的登录地址是Account/Index 同意页面是Consent/Index 这里我们可以通过IdentittyServer4的用户交互自定义配置设置 在Con ...

  2. 凹凸技术揭秘·羚珑页面可视化·成长蜕变之路

    作者: 凹凸曼 前言 京东零售集团 · 用户体验设计部打造的「羚珑智能设计平台」于 2019 年 5 月为内部运营及商家推出了智能页面设计工具,羚珑智能页面设计是一款在线可视化页面搭建平台,拥有在线搭 ...

  3. IdentityServer4关于多客户端和API的最佳实践【含多类型客户端和API资源,以及客户端分组实践】【中】...

    上一篇文章中,我们已经完成了服务端数据库的搭建,本篇主要处理多[传统HTTP][依赖CORE环境]客户端之间协同在线[SSO]以及不需要SSO的场景处理. 目标: 1)实现多类型客户端接入Identi ...

  4. 凹凸技术揭秘 · Tide 研发平台 · 布局研发新基建

    背景 随着前端技术领域的高速发展,前端开发也变得越来越复杂.业务扩张,小程序平台井喷式增加,都导致开发者肩上的负担越来越重.为了提升研发效率,减少人力浪费,我们开发了开放式跨端跨框架解决方案 Taro ...

  5. 在PHP中创建Google登录页面

    在本文中,我将解释如何在您的PHP网站中集成Google登录. 我们将使用Google OAuth API,这是一种将Google登录名添加到您的网站的简便而强大的方法. 作为Web用户,您可能已经经 ...

  6. 凹凸技术揭秘 · 夸克设计资产 · 打造全矩阵优质物料

    1.诞生背景 近几年围绕业务中台化的场景,涌现了很多中台,有面向开发者的,有面向产品的,有面向运营团队的,但是却缺少一个可以提供给设计师协作的中台,设计师与开发.交互的协作仍处于源文件交换的原始刀耕火 ...

  7. 凹凸技术揭秘 · Taro · 开放式跨端跨框架之路

    承载 Web 的主战场转移 2017 年 1 月 9 日凌晨,微信正式推出小程序,为移动端家族增加了新的业务形态和玩法,当大家还在探讨这一新兴平台能做什么的时候,京东率先上线了「京东购物」小程序,随后 ...

  8. 【实战 Ids4】小技巧篇:自定义登录页操作

    今天的内容很简单,1分钟就能看完,5分钟就能学会,但是却是在我们平时开发中必须要学会的一个小知识点,我就不让大家走弯路了,直接看操作. 在平时的IdentityServer4开发中呢,我们都是根据官方 ...

  9. indetityserver4-implicit-grant-types-请求流程叙述-上篇

    说明:使用项目代码是这个,做了一点体力活:将 implicit grant types(简化授权类型)的页面跳转流程抓了个包. QuickstartIdentityServer 项目的发布地址:127 ...

  10. Identity Server 4 - Hybrid Flow - Claims

    前一篇 Identity Server 4 - Hybrid Flow - MVC客户端身份验证: https://www.cnblogs.com/cgzl/p/9253667.html Claims ...

最新文章

  1. nginx安装-添加MP4播放模块
  2. 准确率不变 损失率下降_最新斯诺克排名奥沙利文排在第二,丁俊晖排第十,第一保持不变...
  3. java将clob类型文件写到磁盘_Java对Oracle中Clob类型数据的读取和写入
  4. python模块初始与time、datetime及random
  5. C++中使用new和delete运算符实现二维数组的操作
  6. MongoDB数据库(4.mongodb数据库的备份和恢复)
  7. 微信小程序开发之路(一)
  8. Exchange Server 2013多域名证书申请
  9. C# CollectionBase,ICloneeable
  10. 最好用16进制工具wxHexEditor
  11. Matlab自编函数实现Sobel边缘检测
  12. 联想小新锁屏壁纸怎么换_联想_ThinkPad|ThinkCentre|ThinkStation服务与驱动下载_常见问题...
  13. 完全卸载chrome
  14. mybatis 逆向工程 思维导图
  15. 2020-12-14读书笔记《日日是好日》
  16. 【高登世德:为资产证券化引入区块链技术】GBCAX
  17. 程序员如何改善精神内耗?
  18. 【Codeforces 869 C The Intriguing Obsession】 组合数学 思维
  19. Docker--容器挂载
  20. lycos搜索引擎_搜索元老Lycos计划在2013年推全新搜索引擎

热门文章

  1. 6.torchvision
  2. 比伯女友首谈私生子事件 挺男友:事实胜于诡辩
  3. 服务器有时候显示美国,美国服务器不通的情况解决方法
  4. git简明教程 - 协作篇
  5. 尚福林:建立集团诉讼和股东代表诉讼制度
  6. 安装系统跳过创建用户,直接以超级管理员身份进入系统
  7. android实现刷卡功能,Android 实现银联刷卡机消费后手动签名的功能(示例代码)
  8. 2018年全国国家级自然保护区功能区划空间分布
  9. vs2015软件系统开源_2015年最佳开源游戏
  10. 商汤内推:2023届(AI先锋/校园招聘)