.Net WebApi Swagger+AutoFac+JWT的實現(三)

本章講下關於JWT身份驗證的實現

1、Net.WebApi 項目 從Nuget中搜索安裝JWT

2、Net.WebApi 項目添加文件夾AuthAttributes,且創建ApiAuthorizeAttribute.cs類

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
using JWT;
using JWT.Serializers;
using System.Text;
using System.Net;
using System.Net.Http;
using Net.Repository.Common;

namespace Net.WebApi.AuthAttributes
{
    /// <summary>
    /// 身份認證攔截器
    /// </summary>
    public class ApiAuthorizeAttribute: AuthorizeAttribute
    {
        /// <summary>
        /// 指示指定的控件是否已獲得授權
        /// </summary>
        /// <param name="actionContext"></param>
        /// <returns></returns>
        protected override bool IsAuthorized(HttpActionContext actionContext)
        {
            //前端請求api時會將token存放在名爲"auth"的請求頭中
            var authHeader = from t in actionContext.Request.Headers where t.Key == "auth" select t.Value.FirstOrDefault();
            if (authHeader != null)
            {
                const string secretKey = "Hello World";//加密祕鑰
                string token = authHeader.FirstOrDefault();//獲取token
                if (!string.IsNullOrEmpty(token))
                {
                    try
                    {
                        byte[] key = Encoding.UTF8.GetBytes(secretKey);
                        IJsonSerializer serializer = new JsonNetSerializer();
                        IDateTimeProvider provider = new UtcDateTimeProvider();
                        IJwtValidator validator = new JwtValidator(serializer, provider);
                        IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
                        IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder);
                        //解密
                        var json = decoder.DecodeToObject<JWTAuthInfo>(token, key, verify: true);
                        if (json != null)
                        {
                            //判斷口令過期時間
                            if (json.ExpiryDateTime < DateTime.Now)
                            {
                                return false;
                            }
                            actionContext.RequestContext.RouteData.Values.Add("auth", json);
                            return true;
                        }
                        return false;
                    }
                    catch (Exception ex)
                    {
                        return false;
                    }
                }
            }
            return false;
        }

        /// <summary>
        /// 處理授權失敗的請求
        /// </summary>
        /// <param name="actionContext"></param>
        protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
        {
            var erModel = new
            {
                Success="false",
                ErrorCode="401"
            };
            actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.OK, erModel, "application/json");
        }

        /// <summary>
        ///  爲操作授權時調用
        /// </summary>
        /// <param name="actionContext"></param>
        //public override void OnAuthorization(HttpActionContext actionContext)
        //{
          
        //}
    }
}

3、添加 LoginController控制器

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
//using System.Web.Mvc;
using System.Text;
using JWT;
using JWT.Algorithms;
using JWT.Serializers;
using Net.Repository.RequestEntity;
using Net.Repository.Common;
using Net.Repository;
using Net.IApp;

namespace Net.WebApi.Controllers
{
    /// <summary>
    /// 登錄
    /// </summary>
    [RoutePrefix("api/[controller]/[action]")]
    public class LoginController : ApiController
    {
        private readonly IUserInfoApp userInfoApp;
        public LoginController(IUserInfoApp _userInfoApp)
        {
            userInfoApp = _userInfoApp;
        }
        /// <summary>
        /// 登錄
        /// </summary>
        /// <param name="loginRequest"></param>
        /// <returns></returns>
        [HttpPost]
        public ResponseResult Login([FromBody] LoginRequest loginRequest)
        {
            if (loginRequest != null)
            {
                var userInfo = userInfoApp.Login(loginRequest.UserName, loginRequest.PassWord);
                if (userInfo != null)
                {
                    bool isAdmin = (loginRequest.UserName == "admin") ? true : false;
                    //身份驗證信息
                    JWTAuthInfo authInfo = new JWTAuthInfo { UserName = userInfo.UserName, Roles = new List<string> { "admin", "commonrole" }, IsAdmin = isAdmin, ExpiryDateTime = DateTime.Now.AddHours(2) };
                    const string secretKey = "Hello World";//口令加密祕鑰
                    try
                    {
                        byte[] key = Encoding.UTF8.GetBytes(secretKey);
                        IJwtAlgorithm algorithm = new HMACSHA256Algorithm();//加密方式
                        IJsonSerializer serializer = new JsonNetSerializer();//序列化Json
                        IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();//base64加解密
                        IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);//JWT編碼
                        var token = encoder.Encode(authInfo, key);//生成令牌
                        return new ResponseResult() { Message = "登陸成功", Data = token };
                    }
                    catch (Exception ex)
                    {
                        return new ResponseResult() { Code = 505, Message = "服務器錯誤:" + ex.Message.ToString() };
                    }
                }
                else
                {
                    return new ResponseResult() { Code = 201, Message = "用戶名或密碼錯誤" };
                }             
            }
            else
            {
                return new ResponseResult() { Code = 201, Message = "用戶名或密碼錯誤"};
            }
        }
    }
}
using System;
using System.Collections.Generic;
using System.Text;

namespace Net.Repository.Common
{
    /// <summary>
    /// JWT驗證配置信息
    /// </summary>
    public class JWTAuthInfo
    {
        /// <summary>
        /// 用戶名
        /// </summary>
        public string UserName { get; set; }

        /// <summary>
        /// 角色
        /// </summary>
        public List<string> Roles { get; set; }

        /// <summary>
        /// 是否管理員
        /// </summary>
        public bool IsAdmin { get; set; }

        /// <summary>
        /// 口令過期時間
        /// </summary>
        public DateTime? ExpiryDateTime { get; set; }
    }
}

通過PostMan調用此接口獲取登錄口令

在UserInfoController 中添加 [ApiAuthorize] 身份驗證

/// 用戶信息
    /// </summary>
    [RoutePrefix("api/[controller]/[action]")]
    [ApiAuthorize]
    public class UserInfoController : ApiController

完整代碼下載地址:https://download.csdn.net/download/liwan09/11720168

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章