.Net Core 3.0 Api json web token 中间件签权验证和 Cors 中间件处理跨域请求

第一步:在Nuget上安装"Microsoft.AspNet.WebApi.Cors"包,并对api controller使用[EnableCors]特性以及Microsoft.AspNetCore.Authentication.JwtBearer包

第二步:创建.netcore API项目 /控制器:AuthenticateController

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using static JSON_WEB_Token.Helper;

namespace JSON_WEB_Token.Controllers
{  //跨域标签
    [EnableCors("anyPolicy")]
    //API接口打上Authorize标签
    [Authorize]
    [ApiController]
    //路由配置
    [Route("api/[controller]/[action]")]
    public class AuthenticateController : ControllerBase
    {
        private JwtSettingsModel _jwtSettings;
        public AuthenticateController(IOptions<JwtSettingsModel> jwtSetting)
        {
            _jwtSettings = jwtSetting.Value;
        }

        [HttpPost]
        public IActionResult Token([FromBody]PasswordModel request)
        {
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.SecetKey));

            string userId = request.UserName == null ? request.UserName : request.UserNo;
            if (request.UserName != "test" && request.PassWord != "123" )
            {
                return BadRequest();
            }
           

            var tokenModel = Helper.GetAccessTokenModel
            (new UserData()
            {
                UserGid = strUserGid,
                UserNo = "test"
            }, 
            24 * 365
            );

            return Ok(tokenModel);
        }


    }

    public class PasswordModel
    {
        public string UserName { get; set; }
        public string PassWord { get; set; }
        public string UserNo { get; set; }
        public string ClientSecret { get; set; }
      
    }
}

 

 

 

第三步: Helper

using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace JSON_WEB_Token
{
    public  class Helper 
    {
        public  static AccessTokenResponse GetAccessTokenModel(UserData userData, int hours = 24, DateTime? expireTimeSpan = null)
        {
            JwtSettingsModel _jwtSettings = GetAppsettings<JwtSettingsModel>("JwtSettings");
            //创建claim
            var claim = new Claim[]{
                    new Claim(ClaimTypes.Sid,userData.UserGid.ToString()),
                    new Claim(ClaimTypes.Name,userData.UserNo),
                    new Claim(ClaimTypes.Role,TokenRoleType.UserApp),
                   
                   };
            //对称秘钥 签名秘钥
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.SecetKey));
            //签名证书(秘钥,加密算法)
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            //生成token
            DateTime expiresDate = expireTimeSpan ?? System.DateTime.Now.AddHours(hours);

            var token = new JwtSecurityToken(_jwtSettings.Issuer, _jwtSettings.Audience, claim, DateTime.Now, expiresDate, creds);

            //保存token
            var accessTokenModel = new AccessTokenResponse();
            accessTokenModel.TokenType = "Bearer";
            accessTokenModel.UserNo = userData.UserNo;
            accessTokenModel.ExpiresDate = DateTimeToTimestamp(expiresDate);
            accessTokenModel.AccessToken = new JwtSecurityTokenHandler().WriteToken(token);
            return accessTokenModel;

        }

        public  static long DateTimeToTimestamp(DateTime dateTime)
        {
            var start = new DateTime(1970, 1, 1, 0, 0, 0, dateTime.Kind);
            return Convert.ToInt64((dateTime - start).TotalSeconds);
        }
        public class UserData
        {
            public Guid UserGid { get; set; }
            public string UserNo { get; set; }
            [Required]
            public string UserName { get; set; }
            public string PassWord { get; set; }







        }

        public class AccessTokenResponse
        {
            public string TokenType { get; set; } = "Bearer";
            public string UserNo { get; set; }
            public string AccessToken { get; set; }
            public long ExpiresDate { get; set; }
            

        }
        /// <summary>
        /// 获取配置文件信息
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="setKey"></param>
        /// <returns></returns>
        public static T GetAppsettings<T>(string setKey)
        {

            var builder = new Microsoft.Extensions.Configuration.ConfigurationBuilder()
                      .SetBasePath(Directory.GetCurrentDirectory())
                      .AddJsonFile("appsettings.json").Build();
            return builder.GetSection(setKey).Get<T>();
        }

        /// <summary>
        /// Token用户类型
        /// </summary>
        public class TokenRoleType
        {
            /// <summary>
            /// 匿名Token
            /// </summary>
            public const string GuoWaiApp = "国外渠道";

            /// <summary>
            /// 用户Token
            /// </summary>
            public const string UserApp = "国内渠道";

           
        }


    }

    
}

第四:JwtSettingsModel

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace JSON_WEB_Token
{
    public class JwtSettingsModel
    {
        //token是谁颁发的
        public string Issuer { get; set; }
        //token可以给哪些客户端使用
        public string Audience { get; set; }
        //加密的key 必须是16个字符以上,要大于128个字节
        public string SecetKey { get; set; }
    }

    public class AccessTokenErrModel
    {
        public string AppId { get; set; }
        
        public string errcode { get; set; }
        public string errmsg { get; set; }

        public Guid UserGid { get; set; }

    }
}

第五:appsettings

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },

  "AllowedHosts": "*",

  "JwtSettings": {
    "Issuer": "http://localhost:44305",
    "Audience": "http://localhost:44305",
    "SecetKey": "HelloWorldHelloWorldHelloWorld"
  }
}

第六:Startup

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;

namespace JSON_WEB_Token
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();

            #region json  web   token  添加认证服务
            //将appsettings.json中的JwtSettings部分文件读取到JwtSettings中
            services.Configure<JwtSettingsModel>(Configuration.GetSection("JwtSettings"));

            //使用Bind的方式读取配置
            //将配置绑定到JwtSettings实例中
            var jwtSettings = new JwtSettingsModel();
            Configuration.Bind("JwtSettings", jwtSettings);

            services.AddAuthentication(options => {
                //认证middleware配置
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(options  => 
            {
                //options.SaveToken = true;
                //options.RequireHttpsMetadata = false;
                //主要是jwt  token参数设置
                options.TokenValidationParameters = new TokenValidationParameters
                {
                   
                    //Token颁发机构
                    ValidIssuer = jwtSettings.Issuer,
                    //颁发给谁
                    ValidAudience = jwtSettings.Audience,
                    //这里的key要进行加密
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.SecetKey))
                    

                };
            });
            #endregion

            #region 注册跨域请求服务 CORS 中间件处理跨域请求
            //注册跨域请求服务 允许所有来源、所有方法、所有请求标头、允许请求凭据
            services.AddCors(options =>
                    {
                        //注册默认策略
                        options.AddDefaultPolicy( builder =>
                        {
                            builder.AllowAnyOrigin()
                            .AllowAnyMethod()
                            .AllowAnyHeader()
                            // .AllowCredentials()
                            ;
                        });
                        //注册一个策略名称
                        options.AddPolicy("anyPolicy", builder =>
                        {
                        builder.WithOrigins("http://127.0.0.1:9102", "https://www.baidu.com")
                        .AllowAnyMethod()
                        .AllowAnyHeader()
                        // .AllowCredentials()
                        ;
                        });
                    });
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
            #endregion
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }
            app.UseHttpsRedirection();
            /////////////////////////////////////////////
            //授权(Authorization)
            app.UseAuthorization();
            ///添加中间件(Middleware) 启用验证
            app.UseAuthentication();
            /////////////////////////////////////////////////
            app.UseCors("anyPolicy"); // 设置全局跨域
            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
                endpoints.MapControllerRoute(
                   name: "default",
                   pattern: "{controller=Authenticate}/{action=Index}/{id?}");
            });
        }
    }
}

 第七:postman请求

 

 

 

posted @ 2019-11-29 15:14  蜜雪粮液  阅读(729)  评论(0编辑  收藏  举报