using Microsoft.AspNetCore; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; namespace Permission { public class Program { public static void Main(string[] args) { CreateWebHostBuilder(args).Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseUrls("http://localhost:5001/") .UseStartup<Startup>(); } public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddAuthentication("Bearer") .AddJwtBearer("Bearer", options => { options.Authority = "http://localhost:5000"; options.RequireHttpsMetadata = false; options.Audience = "api1"; }); services.AddSingleton<MemberStore>(); services.AddSingleton<IAuthorizationHandler, PermissionAuthorizationHandler>(); } public void Configure(IApplicationBuilder app) { app.UseAuthentication(); app.UseMvc(); } } public class Member { public int Id { get; set; } public string Name { get; set; } public string Password { get; set; } public bool Admin { get; set; } = false; public List<MemberPermission> Permissions { get; set; } = new List<MemberPermission>(); } public class MemberPermission { public int MemberId { get; set; } public string PermissionName { get; set; } } public class MemberStore { private static List<Member> _members = new List<Member> { new Member { Id = 1, Name = "alice", Password = "password", Admin = true, Permissions = new List<MemberPermission>() }, new Member { Id = 2, Name = "bob", Password = "password", Admin = false, Permissions = new List<MemberPermission> { new MemberPermission { MemberId = 2, PermissionName = "Member.Detail" }, new MemberPermission { MemberId = 2, PermissionName = "Member.Create" }, new MemberPermission { MemberId = 2, PermissionName = "Member.Update" } } } }; public bool HasPermission(int memberId, string permissionName) { var member = _members.FirstOrDefault(v => v.Id == memberId); if (member == null) return false; return member.Admin || member.Permissions.Any(v => permissionName.StartsWith(v.PermissionName)); } } public class PermissionAuthorizationRequirement : IAuthorizationRequirement { public string Name { get; set; } public PermissionAuthorizationRequirement(string name) { Name = name; } } public class PermissionAuthorizationHandler : AuthorizationHandler<PermissionAuthorizationRequirement> { private readonly MemberStore _memberStore; public PermissionAuthorizationHandler(MemberStore memberStore) { _memberStore = memberStore; } protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionAuthorizationRequirement requirement) { if (context.User != null) { var identifier = context.User.FindFirst(v => v.Type == ClaimTypes.NameIdentifier); if (identifier != null) { if (_memberStore.HasPermission(int.Parse(identifier.Value), requirement.Name)) { context.Succeed(requirement); } } } return Task.CompletedTask; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] public class PermissionAuthorizationFilter : Attribute, IAsyncAuthorizationFilter { public string Name { get; set; } public PermissionAuthorizationFilter(string name) { Name = name; } public async Task OnAuthorizationAsync(AuthorizationFilterContext context) { var service = context.HttpContext.RequestServices.GetRequiredService<IAuthorizationService>(); var result = await service.AuthorizeAsync(context.HttpContext.User, null, new PermissionAuthorizationRequirement(Name)); if (result.Succeeded == false) context.Result = new ForbidResult(); } } } namespace Permission.Controllers { [Authorize] [Route("member")] public class MemberController : ControllerBase { [HttpGet("detail")] [PermissionAuthorizationFilter("Member.Detail")] public IActionResult Detail() { return Ok(); } [HttpGet("create")] [PermissionAuthorizationFilter("Member.Create")] public IActionResult Create() { return Ok(); } [HttpGet("update")] [PermissionAuthorizationFilter("Member.Update")] public IActionResult Update() { return Ok(); } [HttpGet("delete")] [PermissionAuthorizationFilter("Member.Delete")] public IActionResult Delete() { return Ok(); } } }
using IdentityServer4.Models; using IdentityServer4.Test; using Microsoft.AspNetCore; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using System.Collections.Generic; namespace IdentityServer { public class Program { public static void Main(string[] args) { CreateWebHostBuilder(args).Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseUrls("http://localhost:5000/") .UseStartup<Startup>(); } public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddIdentityServer() .AddDeveloperSigningCredential() .AddInMemoryIdentityResources(Config.GetIdentityResources()) .AddInMemoryApiResources(Config.GetApiResources()) .AddInMemoryClients(Config.GetClients()) .AddTestUsers(Config.GetTestUsers()); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseIdentityServer(); app.UseMvcWithDefaultRoute(); } } public class Config { public static IEnumerable<IdentityResource> GetIdentityResources() { return new IdentityResource[] { new IdentityResources.OpenId() }; } public static IEnumerable<ApiResource> GetApiResources() { return new ApiResource[] { new ApiResource("api1", "") }; } public static IEnumerable<Client> GetClients() { return new Client[] { new Client { ClientId = "rop", AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, ClientSecrets = { new Secret("secret".Sha256()) }, AllowedScopes = { "api1" } } }; } public static List<TestUser> GetTestUsers() { return new List<TestUser> { new TestUser { SubjectId = "1", Username = "alice", Password = "password" }, new TestUser { SubjectId = "2", Username = "bob", Password = "password" } }; } } } // Install-Package IdentityServer4