.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; }
            public Guid ShopGid { get; set; }
            public string ShopName { get; set; }
            public Guid UserGid { 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请求

 

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

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

 

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

上一篇:实验4:开源控制器实践——OpenDaylight


下一篇:C#编程之AES加密(一)