mirror of
https://github.com/nsnail/IGeekFan.AspNetCore.Knife4jUI.git
synced 2025-08-03 08:57:58 +08:00
57
test/WebSites/OAuth2Integration/AuthServer/Config.cs
Normal file
57
test/WebSites/OAuth2Integration/AuthServer/Config.cs
Normal 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"
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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>
|
@ -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>
|
@ -0,0 +1 @@
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
Reference in New Issue
Block a user