[聚合文章] asp.net web api use json web token

c# 2017-07-27 28 阅读

https://stackoverflow.com/que...


  • 安装nuget包 System.IdentityModel.Tokens.Jwt

Install-Package System.IdentityModel.Tokens.Jwt

  • JwtManager工具类

public static class JwtManager
{
    public static readonly string Secret = System.Configuration.ConfigurationManager.AppSettings["TokenSecret"];

    public static string GenerateToken(string username, int expireMinutes = 20)
    {
        var symmetricKey = Convert.FromBase64String(Secret);
        var tokenHandler = new JwtSecurityTokenHandler();

        var now = DateTime.UtcNow;
        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(new[]
                    {
                    new Claim(ClaimTypes.Name, username)
                }),

            Expires = now.AddMinutes(expireMinutes),

            SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(symmetricKey), SecurityAlgorithms.HmacSha256Signature)
        };

        var stoken = tokenHandler.CreateToken(tokenDescriptor);
        var token = tokenHandler.WriteToken(stoken);

        return token;
    }

    public static bool ValidateToken(string token, out string username)
    {
        username = null;

        var simplePrinciple = JwtManager.GetPrincipal(token);
        var identity = simplePrinciple.Identity as ClaimsIdentity;

        if (identity == null)
            return false;

        if (!identity.IsAuthenticated)
            return false;

        var usernameClaim = identity.FindFirst(ClaimTypes.Name);
        username = usernameClaim?.Value;

        if (string.IsNullOrEmpty(username))
            return false;

        // More validate to check whether username exists in system

        return true;
    }

    public static ClaimsPrincipal GetPrincipal(string token)
    {
        try
        {
            var tokenHandler = new JwtSecurityTokenHandler();
            var jwtToken = tokenHandler.ReadToken(token) as JwtSecurityToken;

            if (jwtToken == null)
                return null;

            var symmetricKey = Convert.FromBase64String(Secret);

            var validationParameters = new TokenValidationParameters()
            {
                RequireExpirationTime = true,
                ValidateIssuer = false,
                ValidateAudience = false,
                IssuerSigningKey = new SymmetricSecurityKey(symmetricKey)
            };

            SecurityToken securityToken;
            var principal = tokenHandler.ValidateToken(token, validationParameters, out securityToken);

            return principal;
        }
        catch (Exception)
        {
            //should write log
            return null;
        }
    }
}

  • 添加ActionFilter

public class JwtAuthActionFilter : ActionFilterAttribute
{
    public static readonly TopException TOKEN_ERROR = new TopException(401, "token not auth");

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>(false).Count > 0)
        {
            //no auth
            return;
        }

        var authorization = actionContext.Request.Headers.Authorization;

        if (authorization == null || authorization.Scheme != "Bearer")
        {
            throw TOKEN_ERROR;
        }
        else
        {
            string username;

            var token = authorization.Parameter;

            if (!JwtManager.ValidateToken(token, out username))
            {
                throw TOKEN_ERROR;
            }
        }

        base.OnActionExecuting(actionContext);
    }

    private static void setErrorResponse(HttpActionContext actionContext, string message)
    {
        var response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, message);
        actionContext.Response = response;
    }
}

  • 随机TokenSecret

function _arrayBufferToBase64(buffer) {
    var binary = '';
    var bytes = buffer;
    var len = bytes.byteLength;
    for (var i = 0; i < len; i++) {
        binary += String.fromCharCode(bytes[i]);
    }
    return window.btoa(binary);
}

function GetTokenSecret(len = 24) {
    let buf = new ArrayBuffer(len)

    for (let i = 0; i < len; i++) {
        buf[i] = parseInt(Math.random() * 1000 % 255, 10)
    }

    return _arrayBufferToBase64(buf)
}

注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。