1. 程式人生 > 實用技巧 ><八>實現consent頁面點選確定的跳轉邏輯

<八>實現consent頁面點選確定的跳轉邏輯

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主頁。