#5 #4 处理枚举和 servers参数

This commit is contained in:
luoyunchong
2020-08-25 02:48:52 +08:00
parent 1d63f2c585
commit 8ea53827f5
28 changed files with 587 additions and 13 deletions

View File

@ -0,0 +1,57 @@
using System.Collections.Generic;
using IdentityServer4.Models;
using IdentityServer4.Test;
namespace OAuth2Integration.AuthServer
{
public static class Config
{
internal static IEnumerable<Client> Clients()
{
yield return new Client
{
ClientId = "test-id",
ClientName = "Test client (Code with PKCE)",
RedirectUris = new[] {
"http://localhost:55202/resource-server/swagger/oauth2-redirect.html", // IIS Express
"http://localhost:5000/resource-server/swagger/oauth2-redirect.html", // Kestrel
},
ClientSecrets = { new Secret("test-secret".Sha256()) },
RequireConsent = true,
AllowedGrantTypes = GrantTypes.Code,
RequirePkce = true,
AllowedScopes = new[] { "readAccess", "writeAccess" },
};
}
internal static IEnumerable<ApiResource> ApiResources()
{
yield return new ApiResource
{
Name = "api",
DisplayName = "API",
Scopes = new[]
{
new Scope("readAccess", "Access read operations"),
new Scope("writeAccess", "Access write operations")
}
};
}
internal static List<TestUser> TestUsers()
{
return new List<TestUser>
{
new TestUser
{
SubjectId = "joebloggs",
Username = "joebloggs",
Password = "pass123"
}
};
}
}
}

View File

@ -0,0 +1,54 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using IdentityServer4;
using IdentityServer4.Test;
namespace OAuth2Integration.AuthServer.Controllers
{
[ApiExplorerSettings(IgnoreApi = true)]
[Route("account")]
public class AccountController : Controller
{
private readonly TestUserStore _userStore;
public AccountController()
{
_userStore = new TestUserStore(Config.TestUsers());
}
[HttpGet("login")]
public IActionResult Login(string returnUrl)
{
var viewModel = new LoginViewModel { Username = "joebloggs", Password = "pass123", ReturnUrl = returnUrl };
return View("/AuthServer/Views/Login.cshtml", viewModel);
}
[HttpPost("login")]
public async Task<IActionResult> Login([FromForm]LoginViewModel viewModel)
{
if (!_userStore.ValidateCredentials(viewModel.Username, viewModel.Password))
{
ModelState.AddModelError("", "Invalid username or password");
viewModel.Password = string.Empty;
return View("/AuthServer/Views/Login.cshtml", viewModel);
}
// Use an IdentityServer-compatible ClaimsPrincipal
var identityServerUser = new IdentityServerUser(viewModel.Username);
identityServerUser.DisplayName = viewModel.Username;
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, identityServerUser.CreatePrincipal());
return Redirect(viewModel.ReturnUrl);
}
}
public class LoginViewModel
{
public string ReturnUrl { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
}

View File

@ -0,0 +1,68 @@
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using IdentityServer4.Stores;
using IdentityServer4.Services;
using IdentityServer4.Models;
namespace OAuth2Integration.AuthServer.Controllers
{
[ApiExplorerSettings(IgnoreApi = true)]
public class ConsentController : Controller
{
private readonly IIdentityServerInteractionService _interaction;
private readonly IClientStore _clientStore;
private readonly IResourceStore _resourceStore;
public ConsentController(
IIdentityServerInteractionService interaction,
IClientStore clientStore,
IResourceStore resourceStore)
{
_interaction = interaction;
_clientStore = clientStore;
_resourceStore = resourceStore;
}
[HttpGet("consent")]
public async Task<IActionResult> Consent(string returnUrl)
{
var request = await _interaction.GetAuthorizationContextAsync(returnUrl);
var client = await _clientStore.FindEnabledClientByIdAsync(request.ClientId);
var resource = await _resourceStore.FindApiResourceAsync("api");
var viewModel = new ConsentViewModel
{
ReturnUrl = returnUrl,
ClientName = client.ClientName,
ScopesRequested = resource.Scopes.Where(s => request.ScopesRequested.Contains(s.Name))
};
return View("/AuthServer/Views/Consent.cshtml", viewModel);
}
[HttpPost("consent")]
public async Task<IActionResult> Consent([FromForm]ConsentViewModel viewModel)
{
var request = await _interaction.GetAuthorizationContextAsync(viewModel.ReturnUrl);
// Communicate outcome of consent back to identityserver
var consentResponse = new ConsentResponse
{
ScopesConsented = viewModel.ScopesConsented
};
await _interaction.GrantConsentAsync(request, consentResponse);
return Redirect(viewModel.ReturnUrl);
}
}
public class ConsentViewModel
{
public string ReturnUrl { get; set; }
public string ClientName { get; set; }
public IEnumerable<Scope> ScopesRequested { get; set; }
public string[] ScopesConsented { get; set; }
}
}

View File

@ -0,0 +1,25 @@
@model OAuth2Integration.AuthServer.Controllers.ConsentViewModel
<style>
</style>
<h1>Consent</h1>
<p>
@Model.ClientName is requesting your permission to ...
</p>
<form asp-controller="Consent" asp-action="Consent">
<input type="hidden" asp-for="ReturnUrl" />
<fieldset>
<ul>
@foreach (var scope in Model.ScopesRequested)
{
<li>
<label>
<input name="ScopesConsented" type="checkbox" value="@scope.Name" checked />@scope.DisplayName
</label>
</li>
}
</ul>
</fieldset>
<button type="submit">Grant Access</button>
</form>

View File

@ -0,0 +1,23 @@
@model OAuth2Integration.AuthServer.Controllers.LoginViewModel
<style>
input {
display: block;
}
</style>
<h1>Login</h1>
<form asp-controller="Account" asp-action="Login">
<input type="hidden" asp-for="ReturnUrl" />
<fieldset>
<label>
Username:
<input type="text" asp-for="Username" />
</label>
<label>
Password:
<input type="text" asp-for="Password" />
</label>
</fieldset>
<button type="submit">Login</button>
</form>

View File

@ -0,0 +1 @@
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers