<八>實現consent頁面點選確定的跳轉邏輯
阿新 • • 發佈:2020-11-02
1、consent頁面(Index.cshtml)上新增相關按鈕(紅色部分程式碼)
@using CodeAuthMvc.Models; @model ConsentViewModel <p>Consent Page</p> <div class="row page-header"> <div class="col-sm-10"> @if(string.IsNullOrWhiteSpace(Model.ClientLogoUrl)) { <div><img src="@Model.ClientLogoUrl" /></div> } <h1> @Model.ClientName <small>希望使用您的賬戶</small> </h1> </div> </div> <div class="row"> <div class="=col-sm-8"> <form asp-action="Index"> <input type="hidden" asp-for="ReturnUrl" value="@Model.ReturnUrl" /> @if (Model.IdentityScopes.Any()) //輸出內容 { <div> <div class="panel-heading"> <span class="glyphicon glyphicon-user"></span> 使用者資訊</div> <ul class="list-group"> @foreach (var scope in Model.IdentityScopes) { @Html.Partial("_ScopeItemList", scope) } </ul> </div> } @if (Model.ResourceScopes.Any()) { <div> <div class="panel-heading"> <span class="glyphicon glyphicon-tasks"></span> 應用許可權 </div> <ul class="list-group"> @foreach (var scope in Model.ResourceScopes) { @Html.Partial("_ScopeItemList", scope) } </ul> </div> } <div> <label> <input type="checkbox" asp-for="RememberConsent" /> <strong>記住我的選擇</strong> </label> </div> <div> <input type="submit" value="yes" name="button" class="btn btn-primary" autofocus>同意</input> <input type="submit" value="no" name="button" >取消</input> </div> </form> </div> </div>
2、_ScopeItemList頁面新增相關程式碼(紅色部分) 當控制元件位disable時,該控制元件的值不會作為表單內容傳送,這裡做一下處理
@using CodeAuthMvc.Models; @model ScopeViewModel <li> <label> <input type="checkbox" name="ScopesConsented" id="[email protected]" value="@Model.Name" checked="@Model.Checked" disabled="@Model.Required" /> @if(@Model.Required) { <input type="hidden" name="ScopesConsented" value="@Model.Name" /> } <strong>@Model.Name</strong> @if (Model.Emphasize) { <span class="glyphicon glyphicon-exclamation-sign"></span> } </label> @if (string.IsNullOrWhiteSpace(Model.Description)) { <div> <label for="[email protected]">@Model.Description</label> </div> } </li>
3、新增一個登陸完成後接收表單資訊的inpuModel
public class ConsentInputModel { public string Button { get; set; } public IEnumerable<string> ScopesConsented { get; set; } public bool RememberConsent { get; set; } public string ReturnUrl { get; set; } }
4、由於當用戶點選取消或者出現錯誤的時候,需要儲存表單頁面的狀態,修改consentviewmodel
public class ConsentViewModel:ConsentInputModel { public string ClientId { get; set; } public string ClientName { get; set; } public string ClientLogoUrl { get; set; } public string ClientUrl { get; set; } /// <summary> /// Identity資源列表 /// </summary> public IEnumerable<ScopeViewModel> IdentityScopes { get; set; } /// <summary> /// Resource資源列表 /// </summary> public IEnumerable<ScopeViewModel> ResourceScopes { get; set; } }
5、新增點選按鈕的響應邏輯
public class ConsentController : Controller { private readonly IClientStore _clientStore; private readonly IResourceStore _resourceStore; private readonly IIdentityServerInteractionService _identityServerInteractionService; public ConsentController(IClientStore clientStore, IResourceStore resourceStore, IIdentityServerInteractionService identityServerInteractionService) { _clientStore = clientStore; _resourceStore = resourceStore; _identityServerInteractionService = identityServerInteractionService; } private async Task<ConsentViewModel> BuildConsentViewModel(string returnUrl) { var request = await _identityServerInteractionService.GetAuthorizationContextAsync(returnUrl); //通過url獲取請求資訊 if (request == null) return null; var client = await _clientStore.FindEnabledClientByIdAsync(request.Client.ClientId); //根據id獲取客戶端資訊 var resources = await _resourceStore.FindEnabledResourcesByScopeAsync(request.Client.AllowedScopes); //獲取resourse 的資訊 return CreateConsentViewModel(request, client, resources, returnUrl); } private ConsentViewModel CreateConsentViewModel(AuthorizationRequest request, Client client, Resources resources,string returnUrl) { var vm = new ConsentViewModel(); vm.ClientName = client.ClientName; vm.ClientLogoUrl = client.LogoUri; vm.ClientUrl = client.ClientUri; vm.RememberConsent = client.AllowRememberConsent; vm.IdentityScopes = resources.IdentityResources.Select(i => CreateScopeViewModel(i)); vm.ResourceScopes = resources.ApiScopes.Select(i => CreateScopeViewModel(i)); vm.ReturnUrl = returnUrl; return vm; } private ScopeViewModel CreateScopeViewModel(IdentityResource identityResource) { return new ScopeViewModel { Name = identityResource.Name, DisplayName = identityResource.DisplayName, Description = identityResource.Description, Required = identityResource.Required, Checked = identityResource.Required, Emphasize = identityResource.Emphasize }; } private ScopeViewModel CreateScopeViewModel(ApiScope scope) { return new ScopeViewModel { Name = scope.Name, DisplayName = scope.DisplayName, Description = scope.Description, Required = scope.Required, Checked = scope.Required, Emphasize = scope.Emphasize }; } [Route("consent")] [HttpGet] public async Task<IActionResult> Index(string returnUrl) { var model = await BuildConsentViewModel(returnUrl); return View(model); } [Route("Index")] [HttpPost] public async Task<IActionResult> Index(ConsentInputModel inputModel) { ConsentResponse consentResponse=null; if(inputModel.Button=="no") { // consentResponse = null; } else if(inputModel.Button == "yes") { if (inputModel.ScopesConsented != null&&inputModel.ScopesConsented.Any()) { consentResponse = new ConsentResponse { RememberConsent = inputModel.RememberConsent, ScopesValuesConsented = inputModel.ScopesConsented }; } } if (consentResponse != null) { //通過url拿到請求 var request =await _identityServerInteractionService.GetAuthorizationContextAsync(inputModel.ReturnUrl); await _identityServerInteractionService.GrantConsentAsync(request,consentResponse); //告訴identityserver 使用者做了哪些授權 return Redirect(inputModel.ReturnUrl); } else { var consentViewModel = await BuildConsentViewModel(inputModel.ReturnUrl); return View(consentViewModel); } }
8、執行訪問5004並登陸成功後顯示下圖
點選yes後跳轉到5004主頁。