接口 Swagger 03 基于Token的身份认证

原文:https://www.cnblogs.com/guogangj/archive/2013/01/18/2866537.html
原文:https://www.cnblogs.com/guyun/p/4589125.html#authentication-authorization
原文:https://www.cnblogs.com/w5942066/p/12055542.html
原文:https://www.cnblogs.com/XiongMaoMengNan/p/6785155.html
原文:https://www.cnblogs.com/wangyulong/p/8727683.html
原文:https://blog.csdn.net/ao123056/article/details/100160981



mark:一种简单的认证方式

一、添加model


1、用于存储用户信息

public class UserInfo
{      
    public int userid { get; set; }
    public string user { get; set; }      
    public string Created { get; set; }
    public string pwd { get; set; }
    public object userModel { get; set; }
}

2、用于在ApiController中,获取自定义的当前用户信息

public class FormsPrincipal : IPrincipal
{
    public IIdentity Identity { get; set; }
    public UserInfo UserData { get; set; }
    public bool IsInRole(string role)
    {
        throw new NotImplementedException();
    }
}



二、添加过滤器

添加类TokenAuthorizeAttribute,主要是验证和解析token,对当前登录用户赋值等

public class TokenAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(HttpActionContext actionContext)
    {
        try
        {
            var token = HttpContext.Current.Request.Headers["Authorization"] ?? ""; //获取token(请求头里面的值)
            if ((token == null) || string.IsNullOrWhiteSpace(token.ToString()))
            {
                //是否允许匿名访问
                var attributes = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
                bool isAnonymous = attributes.Any(a => a is AllowAnonymousAttribute);
                if (isAnonymous)
                {
                    base.OnAuthorization(actionContext);
                    return;
                }
                else
                {
                    throw new Exception("token不能为空!");
                }
            }

            FormsAuthenticationTicket formTicket = null;
            try
            {
                formTicket = FormsAuthentication.Decrypt(token.ToString());//解密Ticket
            }
            catch (Exception ex)
            {
                throw new Exception("token异常!");
            }
            if (formTicket.Expired)
            {
                throw new Exception("token已失效!");
            }

            var userInfo = JsonConvert.DeserializeObject<UserInfo>(formTicket.UserData);
            var user = new FormsPrincipal();
            user.UserData = userInfo;
            user.Identity = new FormsIdentity(formTicket);
            HttpContext.Current.User = user;

            base.IsAuthorized(actionContext);
        }
        catch (Exception ex)
        {
            SendErrorMsg(actionContext, ex.Message);
        }
    }


    private void SendErrorMsg(HttpActionContext filterContext, string msg)
    {
        base.HandleUnauthorizedRequest(filterContext);
        var response = filterContext.Response = filterContext.Response ?? new HttpResponseMessage();
        response.StatusCode = HttpStatusCode.Forbidden;
        var content = new
        {
            success = false,
            errs = new[] { "服务端拒绝访问," + msg }
        };
        response.Content = new StringContent(JsonConvert.SerializeObject(content), Encoding.UTF8, "application/json");
    }
}



三、生成token

HomeApiController中,添加如下代码:

[HttpGet]
public IHttpActionResult Login(int id, string username)
{    
    UserInfo userInfo = new UserInfo { userid = id, user = username };
    string userData = JsonConvert.SerializeObject(userInfo);
    FormsAuthenticationTicket token = new FormsAuthenticationTicket(0, username, DateTime.Now, DateTime.Now.AddDays(30), true, userData, FormsAuthentication.FormsCookiePath);
    string _token = FormsAuthentication.Encrypt(token);//加密
    return Json(new { ret = 1, data = _token, msg = "登录成功!" });
}



四、获取token信息

HomeApiController中,添加如下代码:

[TokenAuthorize]
public IHttpActionResult GetUserInfo()
{
    var userInfo = (User as FormsPrincipal).UserData;
    return Json(userInfo);
}



五、配置Swagger,让其支持header携带token


1、在App_Start中,添加类SwaggerHttpAuthHeaderFilter,代码如下:

public class SwaggerHttpAuthHeaderFilter : IOperationFilter
{
    void IOperationFilter.Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
        if (operation.parameters == null)
        {
            operation.parameters = new List<Parameter>();
        }
        var filterPipeline = apiDescription.ActionDescriptor.GetFilterPipeline(); //判断是否添加权限过滤器
        var allowAnonymous = apiDescription.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any();
        var actionFilter = apiDescription.ActionDescriptor.GetCustomAttributes<TokenAuthorizeAttribute>().Any();
        var controllerFilter = apiDescription.ActionDescriptor.ControllerDescriptor.GetCustomAttributes<TokenAuthorizeAttribute>(true).Any();
        if (allowAnonymous)
        {
            return;
        }
        else if (actionFilter || controllerFilter)
        {
            operation.parameters.Add(new Parameter { name = "Authorization", @in = "header", description = "令牌", required = true, type = "string" });
        }
    }
}

2、修改SwaggerConfig

取消注释
c.OperationFilter<AssignOAuth2SecurityRequirements>();

修改为
c.OperationFilter<App_Start.SwaggerHttpAuthHeaderFilter>();

posted @ 2020-05-11 10:11  古兴越  阅读(1639)  评论(0编辑  收藏  举报