# 基于Session/Cookies的权限认证

借助ActionFilter在请求某个Action之前做校验,验证当前操作者是否登录

//登录时将用户信息保存到Session或者Cookie中

//单个Action配置
public class IndexController:Controller{
	[myAuthorizationActionFilter]
	public IActionResult Index(){
		return view();
	}
}

public class myAuthorizationActionFilter:Attribute, IActionFilter{
	public void OnActionExecuted(ActionExcutedContext context){
		
	}
	public void OnActionExecuting(ActionExecuting context){
		CurrentUser currentUser=context.HttpContext.GetCurrentUserBySession();
		if(currentUser==null){
			if(this.IsAjaxRequest(context.HttpContext.Request)){
				context.Result=new JsonResult(new{
					Sucess=false,
				    Message="没有权限"
				})
			}
			context.Result=new RedirectResult("`/Login");
		}
	}
}

//全局配置
services.AddMvc(options =>{
	options.Filters.Add<myAuthorizationActionFilter>();
})

//某个Action不需要验证的方法
public class IndexController:Controller{
	[classmyAllowAnonymousAttribute]
	public IActionResult Login(){
		return view();
	}
}

public classmyAllowAnonymousAttribute:Attribute{
	
}

public class myAuthorizationActionFilter:Attribute, IActionFilter{
	public void OnActionExecuted(ActionExcutedContext context){
		
	}
	public void OnActionExecuting(ActionExecuting context){
		//判断是否有classmyAllowAnonymousAttribute特性
		if(context.ActionDescriptor.EndpointMetedata.Any(item=>
		                  item is myAuthorizationActionFilter))
        {
			return;
		}
		
		CurrentUser currentUser=context.HttpContext.GetCurrentUserBySession();
		if(currentUser==null){
			if(this.IsAjaxRequest(context.HttpContext.Request)){
				context.Result=new JsonResult(new{
					Sucess=false,
				    Message="没有权限"
				})
			}
			context.Result=new RedirectResult("`/Login");
		}
	}
}

# 基本的签权授权

# 生成Token

//创建声明数组
var claims=new List<claims>(){
	new Claim(ClaimTypes.Role,"Admin"),
	new Claim(ClaimTypes.Name,name),
	new Claim("password",pass),
	new Claim("role","admin")
};
//实例化Token对象
var token=new JwtSecurltyToken(
	claim:claim
);

//生成Token
var jwtToken=new JwtSecurltyTokenHandle().WriteToken(token);

//但此时的Token是无效的,一没有数字签名,而没有加密算法

# 第一步

在app.UseRouting()之后,app.UseEndpoints()之前

app.UseAuthentication();//认证
app.UseAuthorization();//授权

# 第二步

在ConfigureSevices中

//默认Cookie的方式
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options=>{
	options.LoginPath=new PathString("/Login");
})

# 第三步

public class IndexController:Controller{
	[Authorize]
	[AllAnonymousAttribute]//不需要授权
	public IActionResult Index(){
		return view();
	}
}

//全局注册
public IServiceProvider ConfigureServices(IServiceCollection services){
    services.AddMvc(options => options.Filters.Add(new AuthorizeFilter()))
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

# 第四步

public IActionResult Login(string name,string pass){
	if(name==true&&pass==true){
		//创建声明数组
		var claims=new List<claims>(){
			new Claim(ClaimTypes.Role,"Admin"),
			new Claim(ClaimTypes.Name,name),
			new Claim("password",pass),
			new Claim("role","admin")
		};
		
		ClaimPrincipal userPrincipal=new ClaimPrincipal(
		      new ClaimIdentity(claims,"Customer")
		);
		HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
		                        userPrincipal,
								new AuthenticationProperties(
								  ExpiresUtc=DateTime.UtcNow.AddMinutes(30),
								)).Wait();
								
		//var user=HttpContext.User;
		return base.Redirect("Index");
	}
}

# 角色授权 Policy

用户登录时添加用户的角色到Claim

public IActionResult Login(string name,string pass){
	if(name==true&&pass==true){
		//登陆成功后的用户角色
		var roleList=new List<string>(){
			"Admin",
			"Teacher",
			"Student"
		};
		var claims=new List<claims>(){
			new Claim(ClaimTypes.Role,"Admin"),
			new Claim(ClaimTypes.Name,name),
			new Claim("password",pass),
			new Claim("role","admin")
		};
		foreach(var role in rolelist){
			claims.add(new Claim(ClaimTypes.Role,role));
		}
		ClaimPrincipal userPrincipal=new ClaimPrincipal(
		      new ClaimIdentity(claims,"Customer")
		);
		HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
		                        userPrincipal,
								new AuthenticationProperties(
								  ExpiresUtc=DateTime.UtcNow.AddMinutes(30),
								)).Wait();
								
		//var user=HttpContext.User;
		return base.Redirect("Index");
	}
}
services.AddAuthorization(options=>{
	//单独角色
	options.AddPolicy("Admin", policy => policy.RequireRole("Admin").Build());
	//或的关系
	options.AddPolicy("AdminOrTeacher", policy => policy.RequireRole("Admin", "Teacher"));
	//且的关系
	options.AddPolicy("AdminAndTeacher", policy =>
	                       policy.RequireRole("Admin").RequireRole("Teacher"));
});

//使用
public class IndexController:Controller{
	//满足任一个角色即可
	[Authorize(Roles="Admin,Teacher,Student")]
	//需要满足所有角色
	[Authorize(Roles="Admin")]
	[Authorize(Roles="Teacher")]
	[Authorize(Roles="Student")]
	public IActionResult Index(){
		return view();
	}
}

# 策略授权

# 第一步

增加CustomAuthorizationHandler,用于检验逻辑。要求继承自AuthorizationHandler<>泛型抽象类

//AuthorizationHandler 抽象类继承自接口IAuthorizationRequirement
public class MyAuthorizationHandler:AuthorizationHandler<MyAuthorizationRequirement>{
	public MyAuthorizationHandler(){}
	protected override Task HandleReuqirementAsync(AuthorizationHandlerContext context,
	                                          MyAuthorizationRequirement requirement)
	{
		if(requirement.Name=="Policy01"){
			//策略1的逻辑
		}
	    if(requirement.Name=="Policy02"){
		    //策略2的逻辑
	    }
		if(true){
			context.Succeed(requirement);
		}else{
			Task.CompletedTask;
		}
	}
}

# 第二步

增加MyAuthorizationRequirement实现接口IAuthorizationRequirement

public class MyAuthorizationRequirement:IAuthorizationRequirement{
	//可以定义多个属性
	public string name{get;set;}
	public MyAuthorizationRequirement(string policyname){
		this.name=policyname;
	}
}

# 第三步

services.AddSingleton<iAuthorizationHandler,MyAuthorizationHandler>();

services.AddAuthorization(options=>{
	options.AddPolicy("myPolicy",polic=>{
		polic.AddRequirements(new MyAuthorizationRequirement("Policy01"));
	});
	options.AddPolicy("myPolicy01",polic=>{
		polic.AddRequirements(new MyAuthorizationRequirement("Policy02"));
	});
	//或者
	options.AddPolicy("myPolicy01",polic=>
	        policy.Requirements.Add(new MyAuthorizationRequirement("Policy02")));
	
});

# 第四步

public class IndexController:Controller{
	[Authorize(Policy:"myPolicy")]
	public IActionResult Index(){
		return view();
	}
}