Created
February 18, 2017 21:35
-
-
Save aggieben/df9a18d4fc0863298ad45ba22d4d29f9 to your computer and use it in GitHub Desktop.
A consent controller with business logic
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using System.Threading.Tasks; | |
using Microsoft.AspNetCore.Authorization; | |
using Microsoft.AspNetCore.Mvc; | |
using Microsoft.Extensions.Logging; | |
using IdentityServer4.Services; | |
using IdentityServer4.Stores; | |
using IdentityServer4.Models; | |
namespace MyProject.Web | |
{ | |
[Authorize] | |
[Route("consent")] | |
public class ConsentController : Controller | |
{ | |
private readonly ILogger _logger; | |
private readonly IIdentityServerInteractionService _identityService; | |
private readonly IClientStore _clientStore; | |
private readonly IResourceStore _resourceStore; | |
public ConsentController(ILogger<ConsentController> logger, | |
IIdentityServerInteractionService identityService, | |
IClientStore clientStore, | |
IResourceStore resourceStore) | |
{ | |
_logger = logger; | |
_identityService = identityService; | |
_clientStore = clientStore; | |
_resourceStore = resourceStore; | |
} | |
public async Task<IActionResult> Index(string returnUrl) | |
{ | |
var vm = await BuildViewModelAsync(returnUrl); | |
if (vm != null) | |
return View("Error"); | |
return View(vm); | |
} | |
[HttpPost] | |
[ValidateAntiForgeryToken] | |
public async Task<IActionResult> Index(ConsentInputModel model) | |
{ | |
if (model == null || !ModelState.IsValid) | |
{ | |
return View(model); | |
} | |
var request = await _identityService.GetAuthorizationContextAsync(model.ReturnUrl); | |
ConsentResponse response = null; | |
// the button values here are specific to the controls on my consent form - you just need to collect whatever input you need | |
// to make a decision about consent. | |
if (model.Button == "no") | |
{ | |
response = ConsentResponse.Denied; | |
} | |
else if (model.Button == "yes" && model.HasValue()) | |
{ | |
if (model.ResourcesConsented.HasValue()) | |
{ | |
response = new ConsentResponse | |
{ | |
RememberConsent = model.RememberConsent, | |
ScopesConsented = model.ScopesConsented | |
}; | |
} | |
else | |
{ | |
ModelState.AddModelError("", "You must pick at least one permission."); | |
} | |
} | |
else | |
{ | |
ModelState.AddModelError("", "Invalid selection"); | |
} | |
if (response.HasValue()) | |
{ | |
await _identityService.GrantConsentAsync(request, response); | |
return Redirect(model.ReturnUrl); | |
} | |
var vm = await BuildViewModelAsync(model.ReturnUrl, model); | |
if (vm != null) | |
return View(vm); | |
throw new Exception("Unknown error occurred during consent."); | |
} | |
private async Task<ConsentViewModel> BuildViewModelAsync(string returnUrl, ConsentInputModel model = null) | |
{ | |
var request = await _identityService.GetAuthorizationContextAsync(returnUrl); | |
if (request == null) | |
{ | |
_logger.LogError("No consent request matching request: {0}", returnUrl); | |
return null; | |
} | |
var client = await _clientStore.FindEnabledClientByIdAsync(request.ClientId); | |
if (client == null) | |
{ | |
_logger.LogError("Invalid client id: {0}", request.ClientId); | |
return null; | |
} | |
var resources = await _resourceStore.FindEnabledResourcesByScopeAsync(request.ScopesRequested); | |
if (resources == null || (!resources.ApiResources.Any() && resources.IdentityResources.Any())) | |
{ | |
_logger.LogError("No resources in scopes: {0}", request.ScopesRequested); | |
return null; | |
} | |
return new ConsentViewModel(model, returnUrl, request, client, resources); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment