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
相關文章
ASP.NET Core分布式項目實戰(運行Consent Page)--學習筆記
ASP.NET Core分布式項目實戰(Consent Controller Get請求邏輯實現)--學習筆記
ASP.NET Core分布式項目實戰(Consent視圖制作)--學習筆記
ASP.NET Core分布式項目實戰(Identity Server 4回顧,Consent 實現思路介紹)--學習筆記
ASP.NET Core分布式項目實戰(oauth2 + oidc 實現 client部分)--學習筆記
ASP.NET Core分布式項目實戰(oauth2 + oidc 實現 server部分)--學習筆記
ASP.NET Core分布式項目實戰(oauth2與open id connect 對比)--學習筆記
ASP.NET Core分布式項目實戰(詳解oauth2授權碼流程)--學習筆記
ASP.NET Core分布式項目實戰(oauth密碼模式identity server4實現)--學習筆記
ASP.NET Core分布式項目實戰(第三方ClientCredential模式調用)--學習筆記
ASP.NET Core分布式項目實戰(客戶端集成IdentityServer)--學習筆記
ASP.NET Core分布式項目實戰(業務介紹,架構設計,oAuth2,IdentityServer4)--學習筆記
ASP.NET Core分布式項目實戰(課程介紹,MVP,瀑布與敏捷)--學習筆記
ASP.NET Core快速入門 -- 學習筆記匯總
總結
以上是生活随笔為你收集整理的ASP.NET Core分布式项目实战(Consent 确认逻辑实现)--学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: X-lab 开放实验室开源创新的故事
- 下一篇: 使用PInvoke互操作,让C#和C++