交流QQ群:555913397
有什么问题可以加群大家一起交流
先创建存储许可的属性类
namespace CoreMvc.Utinity.Models
{
///
/// 许可项
///
public class PermissionItem
{
///
/// 用户名称
///
public virtual string Name { get; set; }
///
/// 控制器名称
///
public virtual string ControllerName { get; set; }
///
/// 功能名称
///
public virtual string ActionName { get; set; }
}
}
存储授权信息的缓存类
using System.Collections.Generic;
using CoreMvc.Utinity.Models;
namespace CoreMvc.Utinity
{
public class PermissionDictionary
{
private static Dictionary> dictionary = new Dictionary>();
public static void Add(string name, List permissionItems)
{
if (null == dictionary.GetValueOrDefault(name))
{
dictionary.Add(name, permissionItems);
}
}
public static List Get(string name)
{
return dictionary.GetValueOrDefault(name, null);
}
}
}
创建许可条件
using System;
using Microsoft.AspNetCore.Authorization;
namespace CoreMvc.Utinity.Authentications.Requirement
{
///
/// 许可条件
///
public class PermissionRequirement : IAuthorizationRequirement
{
public string DeniedAction { get; set; }
public string LoginPath { get; set; }
public string ClaimType { get; set; }
public TimeSpan Expiration { get; set; }
public PermissionRequirement(string deniedAction, string loginPath, string claimType, TimeSpan expiration)
{
DeniedAction = deniedAction;
LoginPath = loginPath;
ClaimType = claimType;
Expiration = expiration;
}
}
}
许可授权Handler
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CoreMvc.Utinity.Authentications.Requirement;
using CoreMvc.Utinity.Models;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Controllers;
namespace CoreMvc.Utinity.Authentications
{
public class PermissionAuthnenticationHandler : AuthorizationHandler
{
public IAuthenticationSchemeProvider Scheme;
private readonly IHttpContextAccessor _httpContextAccessor;
public PermissionAuthnenticationHandler(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
{
//.net core 3就改成了endpoint了,这里算是一个不小的坑
if (context.Resource is Endpoint endpoint)
{
var controllActionDesription = endpoint.Metadata.GetMetadata();
string controllerName = controllActionDesription.RouteValues["Controller"].ToLower();
string actionName = controllActionDesription.RouteValues["Action"].ToLower();
context.Succeed(requirement);
List permissionList = PermissionDictionary.Get(context.User.Identity.Name);
if (permissionList.Where(w => w.ControllerName == controllerName && w.ActionName == actionName).Count() > 0)
{
//验证通过就正常执行
context.Succeed(requirement);
}
else
{
//不通过就失败
context.Fail();
}
}
await Task.CompletedTask;
}
}
}
创建Login,Action提供登陆授权
[AllowAnonymous]
public async Task Login()
{
ClaimsIdentity claimsIdentity = new ClaimsIdentity(new List
{
new Claim(ClaimTypes.Name, "fqydhk"),
new Claim(ClaimTypes.MobilePhone, "1315********"),
new Claim(ClaimTypes.Email,"[email protected]")
}, CookieAuthenticationDefaults.AuthenticationScheme);
var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, claimsPrincipal);
//登陆成功创建权限信息
List permissionList = new List();
permissionList.Add(new PermissionItem() { Role = "fqydhk", ControllName = "home", ActionName = "authorization" });
PermissionDictionary.Add("fqydhk", permissionList);
string url = HttpContext.Request.Query["ReturnUrl"].ToString();
HttpContext.Response.Redirect(url);
return View();
}
创建一个需要授权才能访问的action
[Authorize(Policy = "permission")]
public IActionResult Authorization()
{
ViewBag.Name = HttpContext.User.Identity.Name ?? "未登录,请登录";
return View();
}
下面是 重中之重 在Startup.cs的ConfigureServices(IServiceCollection services)添加下面代码
PermissionRequirement permissionRequirement = new PermissionRequirement(
deniedAction: "/home/denied",
loginPath: "/home/login",
claimType: ClaimTypes.Name,
TimeSpan.FromSeconds(60 * 5));
//添加授权支持
services.AddAuthorization(options =>
{
//创建策略支持
options.AddPolicy("Permission", policy =>
{
policy.Requirements.Add(permissionRequirement);
});
//添加鉴权支持
}).AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
//添加cookie支持
}).AddCookie(options =>
{
options.LoginPath = new PathString("/home/login");
options.AccessDeniedPath = new PathString("/home/denied");
options.ClaimsIssuer = "Cookie";
});
在Startup.cs的Configure(IApplicationBuilder app, IWebHostEnvironment env)添加启用授权,非常重要,这算是一个小坑…
app.UseAuthentication();
app.UseAuthorization();
app.UseCookiePolicy();