.NetCore JWT认证

.NetCore JWT认证

1、创建.net core web api项目:

Create a Web API with ASP.NET Core and Visual Studio

按照上面链接创建项目。

2、添加JWT(Bearer Token)认证

  • 在项目的Startup.cs文件中的ConfigureServices方法添加以下代码添加并配置JWT认证:
            //添加jwt验证:services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options => {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,//是否验证Issuer
            ValidateAudience = true,//是否验证Audience
            ValidateLifetime = true,//是否验证失效时间
            ValidateIssuerSigningKey = true,//是否验证SecurityKey
            ValidAudience = Configuration["audience"],//Audience
            ValidIssuer = Configuration["issuer"],//Issuer,这两项和签发jwt的设置一致
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["SecurityKey"]))//拿到SecurityKey
        };
     });

其中 Configuration[“audience”]、Configuration[“issuer”]、Configuration[“SecurityKey”]为读取项目中appsettings.json文件中的自定义字符串。

appsettings.json文件:

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "SecurityKey": "dd%88*377f6d&f£$£$#$%#$%#$FF33fssDG^!3",
  "issuer": "guetServer",
  "audience": "guetClient"
}
  • 在项目的Startup.cs文件中的Configure方法添加以下代码配置授权:
app.UseAuthentication();//配置授权
  • 签发JWT

首先自定义API连接返回的数据类型在项目的Models文件夹添加RestfulData类,新建类文件,对应命名空间里面定义三个类,代码如下:

    public class RestfulData
    {
        /// <summary>
        /// <![CDATA[错误码]]>
        /// </summary>
        public int code { get; set; }

        /// <summary>
        ///<![CDATA[消息]]>
        /// </summary>
        public string message { get; set; }

        /// <summary>
        /// <![CDATA[相关的链接帮助地址]]>
        /// </summary>
        public string url { get; set; }

    }

    /// <summary>
    ///
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class RestfulData<T> : RestfulData
    {
        /// <summary>
        /// <![CDATA[数据]]>
        /// </summary>
        public virtual T data { get; set; }
    }

    /// <summary>
    /// <![CDATA[返回数组]]>
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class RestfulArray<T> : RestfulData<IEnumerable<T>>
    {

    }

在项目中Models文件夹新建TokenObj类,代码如下

    public class TokenObj
    {
        public string token { get; set; }//token内容

        public long expires { get; set; }//过期时间
    }

做好以上准备之后在项目的Controllers文件夹里面新建一个API控制器类,如下图:

命名为OAuthController.cs。

将里面的方法全部删除,添加入以下代码

        private readonly IConfiguration _configuration;
  
        public OAuthController(IConfiguration configuration)
        {
            _configuration = configuration;
        }

        /// <summary>
        /// <![CDATA[获取访问令牌]]>
        /// </summary>
        /// <param name="user"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<RestfulData<TokenObj>> Token(string user, string password)//同步方法
        {
            var result = new RestfulData<TokenObj>();
            try
            {
                if (string.IsNullOrEmpty(user)) throw new ArgumentNullException("user", "用户名不能为空!");
                if (string.IsNullOrEmpty(password)) throw new ArgumentNullException("password", "密码不能为空!");

                //验证数据库用户名和密码
                //var userInfo = await _UserService.CheckUserAndPassword(user,  password);
                var claims = new Claim[]
                {
                    new Claim(ClaimTypes.Name,user),
                    new Claim(ClaimTypes.NameIdentifier,password),
                };

                var key = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(_configuration["SecurityKey"]));
                var expires = DateTime.Now.AddDays(30);//
                var token = new JwtSecurityToken(
                            issuer: _configuration["issuer"],
                            audience: _configuration["audience"],
                            claims: claims,
                            notBefore: DateTime.Now,
                            expires: expires,
                            signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256));

                //生成Token
                string jwtToken = new JwtSecurityTokenHandler().WriteToken(token);
                result.code = 200;
                result.data = new TokenObj() { token = jwtToken, expires = expires.ToFileTimeUtc() };
                result.message = "授权成功!";
                return result;
            }
            catch (Exception ex)
            {
                result.message = ex.Message;
                result.code = 400;
                // logger.Error("获取访问令牌时发生错误!", ex);
                return result;
            }
        }

下面添加Swagger UI并验证JWT认证。

3、添加Swashbuckle

Get started with Swashbuckle and ASP.NET Core

按照上面链接添加Swagger UI

  • 在Swagger中添加JWT认证功能

在startup.cs文件中的ConfigureServices方法中的services.AddSwaggerGen配置末尾添加以下代码

                c.AddSecurityDefinition("Bearer", 
                    new ApiKeyScheme {
                        In = "header",
                        Description = "请输入OAuth接口返回的Token,前置Bearer。示例:Bearer {Roken}",
                        Name = "Authorization",
                        Type = "apiKey"
                    });
                c.AddSecurityRequirement(
                    new Dictionary<string, IEnumerable<string>>
                    {
                        { "Bearer",
                          Enumerable.Empty<string>()
                        },
                    });

4、调试

在项目内置的ValuesController中给Get方法添加[Authorize]标签,如下图所示:

调试项目,进入Swagger UI页面,url为http://localhost:<port>/swagger进行调试。

直接请求GET  /api/Values

点击Try it out,再点Execute可见Server response的code是401,未授权: (Unauthorized)

我们尝试OAuth接口获取Token,user password随便输入,可以看到返回的数据有一个token。我们将它复制备用。

点击页面上端的Authorize按钮,按如下图格式输入我们刚刚复制的token,前面带有Bearer,与复制的token间隔一个空格。

再点击Authorize按钮,关闭对话框,然后再去尝试GET  /api/Values接口吧!

返回结果正确,DONE!!!!

生成的token超长,尚未知道如何刷新token。

 

chenj

评论已关闭。