授权

发布于 2020-03-11  205 次阅读


以下内容是老师上课整理的-(加上自己课后总结如果有错误联系站主及时改正)

WebAPI 提供接口 通过指定路由可以直接获取资源 不安全
身份认证--》授权 不是同一个个概念

身份验证要通过 根据身份--》权限--》授权去操作

身份验证(Authentication):确定用户是谁。

授权(Authorization):确定用户能做什么,不能做什么。

MVC 授权 自定义授权

----这里我么不是以MVC授权为主,所以简单了解即可,要了解详情可以点击这里了解--- .NET开发菜鸟

MVC简单过滤器介绍
--授权过滤器用于实现IAuthorizationFilter接口和做出关于是否执行操作方法(如执行身份验证或验证请求的属性)的安全策略。AuthorizeAttribute类继承了IAuthorizationFilter接口,是授权过滤器的示例。授权过滤器在任何其他过滤器之前运行。
 如果要自定义授权过滤器,只需要定义一个类继承自AuthorizeAttribute类,然后重写AuthorizeAttribute类里面的方法即可。 

身份验证:常用的Basic身份验证:
主要原理就是加密用户信息,生成票据,每次请求的时候将票据带过来验证。

 我们知道,认证的目的在于安全,那么如何能保证安全呢?常用的手段自然是加密。Basic认证也不例外,主要原理就是加密用户信息,生成票据,每次请求的时候将票据带过来验证。这样说可能有点抽象,我们详细分解每个步骤:

  1. 首先登陆的时候验证用户名、密码,如果登陆成功,则将用户名、密码按照一定的规则生成加密的票据信息Ticket,将票据信息返回到前端。
  2. 如果登陆成功,前端会收到票据信息,然后跳转到主界面,并且将票据信息也带到主界面的ActionResult里面(例如跳转的url可以这样写:/Home/Index?Ticket=Ticket)
  3. 在主界面的ActionResult里面通过参数得到票据信息Ticket,然后将Ticket信息保存到ViewBag里面传到前端。
  4. 在主界面的前端,发送Ajax请求的时候将票据信息加入到请求的Head里面,将票据信息随着请求一起发送到服务端去。
  5. 在WebApi服务里面定义一个类,继承AuthorizeAttribute类,然后重写父类的OnAuthorization方法,在OnAuthorization方法里面取到当前http请求的Head,从Head里面取到我们前端传过来的票据信息。解密票据信息,从解密的信息里面得到用户名和密码,然后验证用户名和密码是否正确。如果正确,表示验证通过,否则返回未验证的请求401。

详细介绍Basic

原理
用户输入用户名和密码,验证是否登陆成功,如果登陆成功,会生成一个新的token(令牌),用户在任何请求的过程中带着令牌进行一起发送到服务器,才可以获取相对应的资源-

--以下是使用guid生成一个不重复字符,来判断用户登录成功后令牌是否过期。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http; //引入命名空间
using System.Web.Http.Controllers;
using Webapi_Authorized.Models;
using System.Threading;
using System.Security.Principal;
namespace Webapi_Authorized.MyFilter
{
    public class MyGoodsFilterAttribute:AuthorizeAttribute  //1、要继承授权的类
     {
        /// <summary>
        /// 指示指定的控件是否已获得授权
        /// </summary>
        /// <param name="actionContext">上下文</param>
        /// <returns>如果获得授权,则true ,否则false</returns>
        protected override bool IsAuthorized(HttpActionContext actionContext)
        {
            //1、获取授权对象(请求头部中包含得Authrization对象)
            var auth = actionContext.Request.Headers.Authorization;
            if (auth!=null)
            {
                //不为空
                if (auth.Scheme.ToLower()=="basic"&&auth.Parameter!="")
                {
                    //认证的方式位basic认证,并且参数值不为空
                    //可以来进行验证你的令牌或者票据是否是正确的,如果正确返回true
                    //否则false
                    string token = auth.Parameter;
                   return CheckToken(token);
                }
                else
                {
                    return false;
                }
            }
            else
            {
                //为空 授权失败
                return false;
            }
               
        }
        //令牌或票据是在有效期内,如果过了有效期 则失效 不能授权
        //需要重新进行登录,然后重新生成新的票据/令牌
        //我们需要一个表 来存储对应用户的生成token
        /// <summary>
        /// 验证令牌或票据是否正确,而且是否在有效期内
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public bool CheckToken(string token)
        {
            DataClasses1DataContext goods = new DataClasses1DataContext();
            //可以来进行验证token值是否正确,如果正确还可以获取到对应的uid
            var rstoken = goods.TokenInfo.FirstOrDefault(x => x.Token == token);
            if (rstoken!=null)
            {
                //不为空,意味着查询到,但是不知道是否过期
                if (rstoken.ExpireData>DateTime.Now)
                {
                    //验证是否过了有效期 在有效期内
                    //还可以来进一步设置一个传递一个身份的id
                    //利用线程中的身份表示来存储用户信息(id)
                    Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(rstoken.Uid.ToString()), null);
                   
                        return true;
                }
                else
                {
                  
                    return false;
                }
            }
            else
            {
                //token错误
                return false;
            }
        
        }
    }
}

注意:
1.在登陆的时候是不进行过滤的,(因为还没有登陆,就进行过会,肯定是不会成功)
2.登陆之后的一些其他操作会用到过滤(授权) 这个时候就会验证你的请求头部(Request Head)中是否带有授权Authorization ,
2.1如果不为空,则进一步验证身份方式(basic),以及是否带有参数(token),
2.2如果授权的对象不为空,则还需要进一步验证 token是否有存在(linq 语句了来就进行查询,)
2.3如果存在该token的对象,还需要进一步判断是否过期(有效期,和当前的系统日期进行比较)
如果上述一系列操作都有效,返回true,则表示验证通过,可以进行操作

可以自定义过滤器,来进行授权
注意:
1.自定义的过滤器类名称要以Attribute 结尾

2.自定义的类(普通类)--》带有特性的类,需要集成授权特性AuthorizeAttribute


要引用名称空间 System.Web.Http


3.需要重写父类的方法

https://www.cnblogs.com/zhoutuan/p/9489043.html      

 授权 相关资料

暂时更新到此,以后会慢慢补充内容!