ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

ASP.NET Core Ocelot+Consul+Nginx+JWT 构建微服务鉴权中心

2022-04-17 00:02:37  阅读:149  来源: 互联网

标签:Core ASP string builder Consul HttpJsonResponse new app public


目录

ASP.NET Core Ocelot+Consul+Nginx+JWT 构建微服务鉴权中心

  1. 构建鉴权中心 通过webapi的形式给微服务颁发可以登录的有效JWT Token
  2. 构建用户微服务 管理用户信息
  3. 构建测试用微服务
  4. 构建网关层,对微服务进行转发和鉴权
  5. 使用Consul 进行服务的注册 发现

访问流程:

Nginx=>3个鉴权中心集群=》访问问User 微服务验证用户正确性=》验证成功鉴权中心颁发有效Token

Nginx=>(网管层)Ocelot 鉴权=》Consul(服务注册发现)=》测试微服务

鉴权中心 Common.AuthenticationCenter

Controllers文件

AuthenticationController.cs

通过访问用户微服务的登录接口,如果登录成功就颁发JWT Token

[Route("api/[controller]")]
[ApiController]
public class AuthenticationController : ControllerBase
    {
        #region MyRegion

        private ILogger<AuthenticationController> _logger = null;
        private IJWTService _iJWTService = null;
        private readonly IConfiguration _iConfiguration;
        private HttpHelperService _HttpHelperService = null;

        public AuthenticationController(ILoggerFactory factory,
            ILogger<AuthenticationController> logger,
            IConfiguration configuration
            , IJWTService service
            , HttpHelperService httpHelperService)
        {
            this._logger = logger;
            this._iConfiguration = configuration;
            this._iJWTService = service;
            _HttpHelperService = httpHelperService;
        }

        #endregion MyRegion

        [Route("Get")]
        [HttpGet]
        public IEnumerable<int> Get()
        {
            return new List<int>() { 1, 2, 3, 4, 6, 7 };
        }

        [Route("GetKey")]
        [HttpGet]
        public string GetKey()
        {
            string keyDir = Directory.GetCurrentDirectory();
            if (RSAHelper.TryGetKeyParameters(keyDir, false, out RSAParameters keyParams) == false)
            {
                keyParams = RSAHelper.GenerateAndSaveKey(keyDir, false);
            }

            return JsonConvert.SerializeObject(keyParams);
            //return "";
        }

        [Route("Login")]
        [HttpPost]
        public HttpJsonResponse Login([FromForm] string username, [FromForm] string password)
        {
            User user = _HttpHelperService.VerifyUser(username, password);
            if (user is not null)//应该数据库
            {
                string token = this._iJWTService.GetToken(username, password, user);
                return HttpJsonResponse.SuccessResult(token);
            }
            else
            {
                return HttpJsonResponse.FailedResult("校验失败");
            }
        }
    }

Utility 文件夹

Model 文件夹

User.cs

用户微服务的 Model 抽象

public class User
    {
        /// <summary>
        /// 主键ID
        /// </summary>
        public long Id { get; set; }

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreateTime { get; set; } = DateTime.Now;

        /// <summary>
        /// 修改时间
        /// </summary>
        public DateTime UpdateTime { get; set; } = DateTime.Now;

        /// <summary>
        /// 用户名
        /// </summary>
        public string UserName { get; set; } = string.Empty;

        /// <summary>
        /// 密码
        /// </summary>
        public string Password { get; set; } = string.Empty;

        /// <summary>
        /// 用户昵称
        /// </summary>
        public string NickName { get; set; } = string.Empty;

        /// <summary>
        /// 用户部门ID
        /// </summary>
        public long DepartmentId { get; set; } = -1;

        /// <summary>
        /// 用户头像
        /// </summary>
        public string Avatar { get; set; } = string.Empty;

        /// <summary>
        /// 是否是老师
        /// </summary>
        public bool IsTeacher { get; set; } = false;

        /// <summary>
        /// 用户规则ID 测试期间 方便测试暂不关联规则表 -1表示普通用户具有查询权限 0代表管理员具有增加 删除 修改权限
        /// </summary>
        public long RoleId { get; set; } = -1;
    }

RSA 文件夹

RSAHelper.cs

public class RSAHelper
    {
        /// <summary>
        /// 从本地文件中读取用来签发 Token 的 RSA Key
        /// </summary>
        /// <param name="filePath">存放密钥的文件夹路径</param>
        /// <param name="withPrivate"></param>
        /// <param name="keyParameters"></param>
        /// <returns></returns>
        public static bool TryGetKeyParameters(string filePath, bool withPrivate, out RSAParameters keyParameters)
        {
            string filename = withPrivate ? "key.json" : "key.public.json";
            string fileTotalPath = Path.Combine(filePath, filename);
            keyParameters = default(RSAParameters);
            if (!File.Exists(fileTotalPath))
            {
                return false;
            }
            else
            {
                keyParameters = JsonConvert.DeserializeObject<RSAParameters>(File.ReadAllText(fileTotalPath));
                return true;
            }
        }

        /// <summary>
        /// 生成并保存 RSA 公钥与私钥
        /// </summary>
        /// <param name="filePath">存放密钥的文件夹路径</param>
        /// <returns></returns>
        public static RSAParameters GenerateAndSaveKey(string filePath, bool withPrivate = true)
        {
            RSAParameters publicKeys, privateKeys;
            using (var rsa = new RSACryptoServiceProvider(2048))//即时生成
            {
                try
                {
                    privateKeys = rsa.ExportParameters(true);
                    publicKeys = rsa.ExportParameters(false);
                }
                finally
                {
                    rsa.PersistKeyInCsp = false;
                }
            }
            File.WriteAllText(Path.Combine(filePath, "key.json"), JsonConvert.SerializeObject(privateKeys));
            File.WriteAllText(Path.Combine(filePath, "key.public.json"), JsonConvert.SerializeObject(publicKeys));
            return withPrivate ? privateKeys : publicKeys;
        }

        //public static string GenerateAndSaveKey(string filePath, bool withPrivate = true)
        //{
        //    //RSAParameters publicKeys, privateKeys;
        //    using (var rsa = new RSACryptoServiceProvider(2048))//即时生成
        //    {
        //        try
        //        {
        //            //privateKeys = rsa.ExportParameters(true);
        //            //publicKeys = rsa.ExportParameters(false);

        //            //rsa.ExportRSAPublicKey();
        //            //rsa.ExportRSAPrivateKey();

        //            string publicKey = rsa.ToXmlString(false);//publickey
        //            string privateKey = rsa.ToXmlString(true);//privateKey
        //            File.WriteAllText(Path.Combine(filePath, "key.json"), privateKey);
        //            File.WriteAllText(Path.Combine(filePath, "key.public.json"), publicKey);
        //            return withPrivate ? privateKey : publicKey;
        //        }
        //        finally
        //        {
        //            rsa.PersistKeyInCsp = false;
        //        }
        //    }

        //}
    }

ConfigInformation.cs

public class ConfigInformation
    {
        public string RootUrl { get; set; }

        public string UserUrl { get; set; }

        public JWTTokenOptions JWTTokenOptions { get; set; }
    }

HttpHelperService.cs

/// <summary>
/// 就是去调用服务的---暂时没有Consul---ToDo
/// </summary>
public class HttpHelperService
    {
        #region Option注入

        private readonly ConfigInformation _ConfigInformation;

        public HttpHelperService(IOptionsMonitor<ConfigInformation> configInformation)
        {
            this._ConfigInformation = configInformation.CurrentValue;
        }

        #endregion Option注入

        public User VerifyUser(string name, string password)
        {
            string requestUrl = $"{_ConfigInformation.RootUrl}{_ConfigInformation.UserUrl}?username={name}&password={password}";
            Console.WriteLine(requestUrl);

            HttpResponseMessage sResult = this.HttpRequest(requestUrl, HttpMethod.Get, null);
            if (sResult.IsSuccessStatusCode)
            {
                string content = sResult.Content.ReadAsStringAsync().Result;
                HttpJsonResponse response = JsonConvert.DeserializeObject<HttpJsonResponse>(content);
                User user = JsonConvert.DeserializeObject<User>(JsonConvert.SerializeObject(response.Data));
                return user;
            }
            else
            {
                return null;
            }
        }

        public HttpResponseMessage HttpRequest(string url, HttpMethod httpMethod, Dictionary<string, string> parameter)
        {
            using (HttpClient httpClient = new HttpClient())
            {
                HttpRequestMessage message = new HttpRequestMessage()
                {
                    Method = httpMethod,
                    RequestUri = new Uri(url)
                };
                if (parameter != null)
                {
                    var encodedContent = new FormUrlEncodedContent(parameter);
                    message.Content = encodedContent;
                }
                return httpClient.SendAsync(message).Result;
            }
        }
    }

IJWTService.cs

/// <summary>
/// 封装注入
/// </summary>
public interface IJWTService
    {
        /// <summary>
        /// 获取Token
        /// </summary>
        /// <param name="UserName">账号</param>
        /// <param name="password">密码</param>
        /// <param name="user">用户信息</param>
        /// <returns></returns>
        string GetToken(string UserName, string password, User user);
    }

JWTHSService.cs

public class JWTHSService : IJWTService
    {
        #region Option注入

        private readonly JWTTokenOptions _JWTTokenOptions;

        public JWTHSService(IOptionsMonitor<ConfigInformation> configInformation)
        {
            this._JWTTokenOptions = configInformation.CurrentValue.JWTTokenOptions;
        }

        #endregion Option注入

        public string GetToken(string UserName, string password, User user)
        {
            var claims = new[]
            {
                 new Claim("username", user.UserName),
                 new Claim("id", user.Id.ToString()),
                 new Claim(ClaimTypes.Role,user.RoleId.ToString())
            };

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(this._JWTTokenOptions.SecurityKey));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var token = new JwtSecurityToken(
                issuer: this._JWTTokenOptions.Issuer,
                audience: this._JWTTokenOptions.Audience,
                claims: claims,
                expires: DateTime.Now.AddMinutes(60),//5分钟有效期
                notBefore: DateTime.Now.AddMilliseconds(5),//1分钟后有效
                signingCredentials: creds);
            string returnToken = new JwtSecurityTokenHandler().WriteToken(token);
            return returnToken;
        }
    }

JWTRSService.cs

public class JWTRSService : IJWTService
    {
        #region Option注入

        private readonly JWTTokenOptions _JWTTokenOptions;

        public JWTRSService(IOptionsMonitor<ConfigInformation> configInformation)
        {
            this._JWTTokenOptions = configInformation.CurrentValue.JWTTokenOptions;
        }

        #endregion Option注入

        public string GetToken(string userName, string password, User user)
        {
            string jtiCustom = Guid.NewGuid().ToString();//用来标识 Token
            var claims = new[]
            {
                   new Claim(ClaimTypes.Name, user.UserName),
                   new Claim("id", user.Id.ToString()),
                   new Claim(ClaimTypes.Role,user.RoleId.ToString())
            };
            string keyDir = Directory.GetCurrentDirectory();
            if (RSAHelper.TryGetKeyParameters(keyDir, true, out RSAParameters keyParams) == false)
            {
                keyParams = RSAHelper.GenerateAndSaveKey(keyDir);
            }
            var credentials = new SigningCredentials(new RsaSecurityKey(keyParams), SecurityAlgorithms.RsaSha256Signature);

            #region XML

            //string privateKey = RSAHelper.GenerateAndSaveKey(keyDir);
            //var  RSA = new RSACryptoServiceProvider();
            //RSA.FromXmlString(privateKey);
            //var credentials = new SigningCredentials(new RsaSecurityKey(RSA), SecurityAlgorithms.RsaSha256Signature);

            #endregion XML

            var token = new JwtSecurityToken(
               issuer: this._JWTTokenOptions.Issuer,
               audience: this._JWTTokenOptions.Audience,
               claims: claims,
               expires: DateTime.Now.AddMinutes(60),//5分钟有效期
               signingCredentials: credentials);
            var handler = new JwtSecurityTokenHandler();
            string tokenString = handler.WriteToken(token);
            return tokenString;
        }
    }

JWTTokenOptions.cs

public class JWTTokenOptions
    {
        public string Audience
        {
            get;
            set;
        }

        public string SecurityKey
        {
            get;
            set;
        }

        //public SigningCredentials Credentials
        //{
        //    get;
        //    set;
        //}

        public string Issuer
        {
            get;
            set;
        }
    }

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConfigInformation": {
    "RootUrl": "http://localhost:10091", //服务调用
    "UserUrl": "/api/userapi/User/validate",
    "JWTTokenOptions": {
      "Audience": "http://localhost:8761",
      "Issuer": "http://localhost:8761",
      "SecurityKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI2a2EJ7m872v0afyoSDJT2o1+SitIeJSWtLJU8/Wz2m7gStexajkeD+Lka6DSTy8gt9UwfgVQo6uKjVLG5Ex7PiGOODVqAEghBuS7JzIYU5RvI543nNDAPfnJsas96mSA7L/mD7RTE2drj6hf3oZjJpMPZUQI/B1Qjb5H3K3PNwIDAQAB"
    }
  }
}

key.json

{"D":"ayJEcDAFTdAjKtn/wUvAe0z0RtXcOFENJm55PaTbDV8QAKfKKENY5K+nvU36uSi3qh2xP6NVoo3H3rDlk6X8AEuAOQs+arGfHQ/aL4Ob3skuEioHWszXScJ2KTzrrsolOik9SybNLRSMIgQKyZY5URk3BhLqSvMDwBQ2Nht/mlx+eQi1GpPgiJFH77BlRt3O/LKafAtgS292RxeKUJn3Q4dsn1PtJX+PMPT+bn+9PZXpQtSI8r8yUtrFja61WcGN8aJrG47EfT5wa3J/mcfhEK+4hU2uI3ycW+TaNjuxDZ+nAD4k3pcNT6a1ldSi3CnZKR2p/MUh07oazmx2QEg54Q==","DP":"t58aASvJT2+mQCi9EN5RksOXrgzGNB2U6PeS8NJ9ht6HiA78+fZKrfbxXxz8i/069Tyg7dkzYeKFd93q9FhFKqsOGE67gqjelKIXFTN2s2DFiJ7neFHkIhPisdS/a+SzHziFsxYHJbWobuHlrDw2QcoYGDsgS1Crbatn7t90Hfs=","DQ":"dzpHSw7DD1vwy+mOX5nRJLVniSmcIX8MMWtCXlmzj6CdUddyiGSGFhTB+hjVHLPxsJAzoV4zBFRt1s+CHGlgjhfD6ct58i7bDVG/6OVUI4v95iYiA7kPB44DlOzVjuhlGmTm5Tw5eTwjA3s/5FUuif0DShzt4jam7f+jlTvkXaM=","Exponent":"AQAB","InverseQ":"MTykln8IgIQ2DwhC4d0d/RXNk5/PvKXSY8goldKfxCiAwTmArivvuxfHC01oKFlZkZbPRVvh0rM9QkM4pX9ITfKd4+VoxmDtMMx5oEkbxKMbJQkUvJeADmtcy/zfXq8ZNSNcIkAI4setydA6tOvRZKuudJ5tEpXOxwTel8U5ltM=","Modulus":"o0jSDb5OYfSTPFPjZS67yovVQLEA5OIrey/1mBCH8Xxvo1zLwKPYzWwkRjzSLURZ19V9AeKAiP+JxDtGRzmUflqXY3e7vKeEosk5MoUj4MlBvxVxDL3bdghJaqhARaqsuXQ1dvOGABsDIogBmvCJyJOBHXISLl+hDGIOQSpHqtMFz4UHAF5v62x82oMYT8O4lTfoTSF1+jMH31rCCERXFEz2DUngdsT8gwQncTMrVTS2dIdacvkWmN0yvzLmMqZetv12p10O7jjuN61hlhhccAibGeU3X1veOHS4L9TzQ0rLPK/yTm3QlShWZD8oiLBnNXGhS0m/RTk3Uc7IrvvaqQ==","P":"0daJpBirbZIUYZyqeXW6csoy2eKDO81G4DAe0gzyZUk7ZQ97H3sIRdKU05lmeR0KuEtp71LOaljx2MJ1vawF4zoJ3MQEjzQYQS0Gq5zLPrX/Q+Sy/7Brb9oYlfwDzlyszlZqjSyJjupNOAlpkTkytt6a5g6LtD44mo2A9XCteTM=","Q":"xzSFkOTiJGyTNatXO8pAxZyGg4qjAweJOL5wv5dGqFF7fWx92uJrMcGy6kda5A3aCE0KG0441fWjGPjzb6GvoTzwADRx4mNhOcVV0gx/lbKydc15KaBNEX29TkmYbG4dRQ5wOs+FBm0PAHcQgK64AFYhobG4w8VZBLxCXdwndLM="}

Program.cs

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.Configure<ConfigInformation>(builder.Configuration.GetSection("ConfigInformation"));
builder.Services.AddTransient<HttpHelperService>();
builder.Services.AddControllers();

#region HS256

builder.Services.AddScoped<IJWTService, JWTHSService>();
//builder.Services.Configure<JWTTokenOptions>(builder.Configuration.GetSection("JWTTokenOptions"));

#endregion HS256

#region RS256

//builder.Services.AddScoped<IJWTService, JWTRSService>();
//builder.Services.Configure<JWTTokenOptions>(builder.Configuration.GetSection("JWTTokenOptions"));

#endregion RS256

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddCors(options =>
{
    options.AddPolicy("default", policy =>
    {
        policy.AllowAnyOrigin()
            .AllowAnyHeader()
            .AllowAnyMethod();
    });
});
var app = builder.Build();

// Configure the HTTP request pipeline.

app.UseSwagger();
app.UseSwaggerUI();

app.UseAuthorization();
app.UseCors("default");
app.MapControllers();

app.Run();

网关 Common.OcelotGateway

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "JWTTokenOptions": {
    "Audience": "http://localhost:8761",
    "Issuer": "http://localhost:8761",
    "SecurityKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI2a2EJ7m872v0afyoSDJT2o1+SitIeJSWtLJU8/Wz2m7gStexajkeD+Lka6DSTy8gt9UwfgVQo6uKjVLG5Ex7PiGOODVqAEghBuS7JzIYU5RvI543nNDAPfnJsas96mSA7L/mD7RTE2drj6hf3oZjJpMPZUQI/B1Qjb5H3K3PNwIDAQAB"
  }
}

OcelotConfiguration.json

{
  "Routes": [    
    {
      "UpstreamPathTemplate": "/api/lessonapi/{url}",
      "UpstreamHttpMethod": [
        "Get",
        "Post",
        "Put",
        "Patch",
        "Delete",
        "Options"
      ],
      "UserServiceDIscovery": true,
      "ServiceName": "LessonCenter",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "DownstreamPathTemplate": "/api/lessonapi/{url}",
      "DownstreamScheme": "http",
      "DownstreamHeaderTransform": {
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Methods": "*",
        "Access-Control-Allow-Headers": "*"
      },
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "UserGatewayKey",
        "AllowedScopes": []
      }
    },
    {
      "UpstreamPathTemplate": "/lesson/swagger/v1/swagger.json",
      "UpstreamHttpMethod": [
        "Get"
      ],
      "UseServiceDiscovery": true,
      "ServiceName": "LessonCenter",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "DownstreamPathTemplate": "/swagger/v1/swagger.json",
      "DownstreamScheme": "http",
      "RateLimitOptions": {
        "ClientWhiteList": [
          "ajun816",
          "superhero"
        ],
        "EnableRateLimiting": true,
        "Period": "5m",
        "PeriodTimespan": 30,
        "Limit": 5
      }
    },
    {
      "UpstreamPathTemplate": "/api/userapi/{url}",
      "UpstreamHttpMethod": [
        "Get",
        "Post",
        "Put",
        "Patch",
        "Delete",
        "Options"
      ],
      "UserServiceDIscovery": true,
      "ServiceName": "UserCenter",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "DownstreamPathTemplate": "/api/userapi/{url}",
      "DownstreamScheme": "http",
      "DownstreamHeaderTransform": {
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Methods": "*",
        "Access-Control-Allow-Headers": "*"
      }
    },
    {
      "UpstreamPathTemplate": "/user/swagger/v1/swagger.json",
      "UpstreamHttpMethod": [
        "Get"
      ],
      "UseServiceDiscovery": true,
      "ServiceName": "UserCenter",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "DownstreamPathTemplate": "/swagger/v1/swagger.json",
      "DownstreamScheme": "http",
      "RateLimitOptions": {
        "ClientWhiteList": [
          "ajun816",
          "superhero"
        ],
        "EnableRateLimiting": true,
        "Period": "5m",
        "PeriodTimespan": 30,
        "Limit": 5
      }
    },

  "GlobalConfiguration": {
    "BaseUrl": "http://127.0.0.1:8070", //网关对外地址
    "ServiceDiscoveryProvider": {
      "Host": "127.0.0.1",
      "Port": 8500,
      "Type": "Consul" //由Consul提供服务发现
    },
    "RateLimitOptions": {
      "QuotaExceededMessage": "Too many requests, maybe later? 11", // 当请求过载被截断时返回的消息
      "HttpStatusCode": 666, // 当请求过载被截断时返回的http status
      "ClientIdHeader": "client_id" // 用来识别客户端的请求头,默认是 ClientId
    }
  }
}

Program.cs

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "Common.OcelotGateway", Version = "v1" });
});

builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.AddJsonFile("OcelotConfiguration.json", optional: true, reloadOnChange: true);
});

#region JWT检验 HS

JWTTokenOptions tokenOptions = new JWTTokenOptions();
builder.Configuration.Bind("JWTTokenOptions", tokenOptions);
string authenticationProviderKey = "UserGatewayKey";

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)//Bearer Scheme
       .AddJwtBearer(authenticationProviderKey, options =>
       {
           options.TokenValidationParameters = new TokenValidationParameters
           {
               //JWT有一些默认的属性,就是给鉴权时就可以筛选了
               ValidateIssuer = true,//是否验证Issuer
               ValidateAudience = true,//是否验证Audience
               ValidateLifetime = true,//是否验证失效时间---默认还添加了300s后才过期
               ClockSkew = TimeSpan.FromSeconds(0),//token过期后立马过期
               ValidateIssuerSigningKey = true,//是否验证SecurityKey
               ValidAudience = tokenOptions.Audience,//Audience,需要跟前面签发jwt的设置一致
               ValidIssuer = tokenOptions.Issuer,//Issuer,这两项和前面签发jwt的设置一致
               IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenOptions.SecurityKey)),//拿到SecurityKey
           };
       });

#endregion JWT检验 HS

builder.Services.AddOcelot()
                .AddConsul()
                .AddPolly();

var app = builder.Build();

// Configure the HTTP request pipeline.

app.UseSwagger();
app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/lesson/swagger/v1/swagger.json", "课程 API V1");
    c.SwaggerEndpoint("/user/swagger/v1/swagger.json", "用户 API V1");
});

app.UseOcelot().Wait();

app.Run();

用户微服务 UserMicroservice

Controllers文件夹

UserController.cs

[Route("api/userapi/[controller]")]
[ApiController]
public class UserController : ControllerBase
    {
        private readonly IUserService? _userService;

        public UserController(IUserService? userService)
        {
            _userService = userService;
        }

        [HttpGet("all")]
        public HttpJsonResponse GetAll()
        {
            try
            {
                var data = _userService?.GetAll<SysUser>();
                return HttpJsonResponse.SuccessResult(data);
            }
            catch
            {
                return HttpJsonResponse.FailedResult();
            }
        }

        [Route("validate")]
        [HttpGet]
        public HttpJsonResponse ValidateUser(string username, string password)
        {
            try
            {
                var accountInfo = _userService?.ValidateUser(username, password);
                return HttpJsonResponse.SuccessResult(accountInfo);
            }
            catch (Exception ex)
            {
                return HttpJsonResponse.FailedResult(ex.Message);
            }
        }

        [HttpPost("regist")]
        public HttpJsonResponse CreateUser(RegisterModel registerModel)
        {
            try
            {
                var accountInfo = _userService?.CreateUser(registerModel);
                return HttpJsonResponse.SuccessResult(accountInfo);
            }
            catch (Exception ex)
            {
                return HttpJsonResponse.FailedResult(ex.Message);
            }
        }

        [HttpPut("update")]
        public HttpJsonResponse UpdateUser(RegisterModel registerModel)
        {
            try
            {
                var accountInfo = _userService?.UpdateUser(registerModel);
                return HttpJsonResponse.SuccessResult(accountInfo);
            }
            catch (Exception ex)
            {
                return HttpJsonResponse.FailedResult(ex.Message);
            }
        }

        [HttpDelete("delete/{id}")]
        public HttpJsonResponse DeleteUser([FromRoute] long id)
        {
            bool success = _userService?.Delete<SysUser>(id) ?? false;
            return success ? HttpJsonResponse.SuccessResult("删除成功") :
                HttpJsonResponse.FailedResult("删除失败");
        }
    }

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "MySqlConn": "Server=111.44.222.111;Database=db_user;Uid=root;Pwd=111111;SslMode=none;"
  },
  "CodeFirstSettings": {
    "Migrate": "true", //是否开启同步(是否进行codefirst创建表)
    "Backup": "true", //是否进行备份
    "ModelPath": "UserModel" //要进行同步的Model程序集路径
  },
  "SqlSugarSnowFlakeSettings": {
    "WorkerId": "1"
  },
  "ConsulClientOption": {
    "IP": "111.44.222.111",
    "Port": "18500",
    "Datacenter": "dc1"
  },
  "ConsulRegisterOption": {
    "IP": "111.44.222.111",
    "Port": "8761",
    "GroupName": "UserCenter",
    "HealthCheckUrl": "http://111.44.222.111:8761/Health",
    "Interval": 10,
    "Timeout": 5,
    "DergisterCriticalServiceAfter": 20,
    "Tag": "13"
  }
}

Program.cs

var builder = WebApplication.CreateBuilder(args);

// 配置牛顿库,让json解析的时候使用我们自定义的解析器 这个解析器不会造成long类型数据的精度损失
builder.Services.AddControllers().AddNewtonsoftJson(options =>
{
    options.SerializerSettings.DateFormatString = "yyyy'-'MM'-'dd' 'HH':'mm':'ss";
    options.SerializerSettings.ContractResolver = new CustomerJsonResolver();
});

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

// SqlSugar配置
builder.Services.AddSqlSugarSetup(builder.Configuration);
// SqlSugar的雪花ID配置
builder.Services.AddSqlSugarSonwFlakeSetup(builder.Configuration);
// SqlSugarCodeFirst设置
builder.Services.AddCodeFirstSetup(builder.Configuration, typeof(BaseModel));

builder.Services.AddTransient<IUserService, UserService>();

var app = builder.Build();

// Configure the HTTP request pipeline.
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "UserMicroservice V1"));

app.UseAuthorization();

app.UsePerOptionsRequest();

app.UseHealthCheckMiddleware();

app.MapControllers();

app.UseConsulConfiguration(builder.Configuration).Wait();

app.Run();

课程微服务 LessonMicroservice

Controllers文件夹

LessonController.cs

[Route("api/lessonapi/[controller]")]
[ApiController]
public class LessonController : ControllerBase
    {
        #region 服务注入

        private readonly ILessonService? _lessonService;

        public LessonController(ILessonService? lessonService)
        {
            _lessonService = lessonService;
        }

        #endregion 服务注入

        /// <summary>
        /// 分页获取数据
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet("page")]
        public HttpJsonResponse GetPaged(int pageIndex = 1, int pageSize = 10)
        {
            var data = _lessonService?.GetLessons(pageIndex, pageSize, l => l.CreateTime);
            return HttpJsonResponse.SuccessResult(data);
        }

        /// <summary>
        /// 创建课程
        /// </summary>
        /// <param name="lesson"></param>
        /// <returns></returns>
        [HttpPost("create")]
        [Authorize(Roles = "0")]
        public HttpJsonResponse Create(Lesson lesson)
        {
            var data = _lessonService?.CreateLesson(lesson);
            return HttpJsonResponse.SuccessResult(data);
        }

        /// <summary>
        /// 按条件筛选数据
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        [HttpPost("filter")]
        public HttpJsonResponse GetPagedByFilter([FromBody] LessonFilter filter)
        {
            var data = _lessonService?.PagedLessonsByFilter(filter.GetFilterExpression(),
                filter.CategoryId, filter.PageIndex, filter.PageSize);
            return HttpJsonResponse.SuccessResult(data);
        }

        /// <summary>
        /// 按照Id删除数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete("delete/{id}")]
        [Authorize(Roles = "0")]
        public HttpJsonResponse DeleteById([FromRoute] long id)
        {
            bool success = _lessonService?.DeleteLessonById(id) ?? false;
            return success ?
                HttpJsonResponse.SuccessResult(success) :
                HttpJsonResponse.FailedResult("删除课程失败!");
        }

        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="lesson"></param>
        /// <returns></returns>
        [HttpPut("update")]
        [Authorize(Roles = "0")]
        public HttpJsonResponse Update(Lesson lesson)
        {
            var data = _lessonService?.Update<Lesson>(lesson);
            return HttpJsonResponse.SuccessResult(data);
        }
    }

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "MySqlConn": "Server=111.44.222.111;Database=db_Lesson;Uid=root;Pwd=111111;SslMode=none;"
  },
  "CodeFirstSettings": {
    "Migrate": "true", //是否开启同步(是否进行codefirst创建表)
    "Backup": "true", //是否进行备份
    "ModelPath": "LessonModel" //要进行同步的Model程序集路径
  },
  "SqlSugarSnowFlakeSettings": {
    "WorkerId": "1"
  },
  "JWTTokenOptions": {
    "Audience": "http://localhost:8761",
    "Issuer": "http://localhost:8761",
    "SecurityKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI2a2EJ7m872v0afyoSDJT2o1+SitIeJSWtLJU8/Wz2m7gStexajkeD+Lka6DSTy8gt9UwfgVQo6uKjVLG5Ex7PiGOODVqAEghBuS7JzIYU5RvI543nNDAPfnJsas96mSA7L/mD7RTE2drj6hf3oZjJpMPZUQI/B1Qjb5H3K3PNwIDAQAB"
  },
  //"ConsulClientOption": {
  //  "IP": "111.44.222.111",
  //  "Port": "18500",
  //  "Datacenter": "dc1"
  //},
  //"ConsulRegisterOption": {
  //  "IP": "111.44.222.111",
  //  "Port": "8761",
  //  "GroupName": "LessonCenter",
  //  "HealthCheckUrl": "http://111.44.222.111:8761/Health",
  //  "Interval": 10,
  //  "Timeout": 5,
  //  "DergisterCriticalServiceAfter": 20,
  //  "Tag": "13"
  //},

  //本地测试ConsulClientOption

  "ConsulClientOption": {
    "IP": "localhost",
    "Port": "8500",
    "Datacenter": "dc1"
  },
  "ConsulRegisterOption": {
    "IP": "localhost",
    "Port": "8761",
    "GroupName": "LessonCenter",
    "HealthCheckUrl": "http://localhost:8761/Health",
    "Interval": 10,
    "Timeout": 5,
    "DergisterCriticalServiceAfter": 20,
    "Tag": "13"
  }
}

Program.cs

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
// 配置牛顿库,让json解析的时候使用我们自定义的解析器 这个解析器不会造成long类型数据的精度损失
builder.Services.AddControllers().AddNewtonsoftJson(options =>
{
    options.SerializerSettings.DateFormatString = "yyyy'-'MM'-'dd' 'HH':'mm':'ss";
    options.SerializerSettings.ContractResolver = new CustomerJsonResolver();
});

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

// SqlSugar设置
builder.Services.AddSqlSugarSetup(builder.Configuration);
// SqlSugar CodeFirst设置
builder.Services.AddCodeFirstSetup(builder.Configuration, typeof(BaseModel));
// SqlSugar 雪花ID设置
builder.Services.AddSqlSugarSonwFlakeSetup(builder.Configuration);

// 服务注入
builder.Services.AddTransient<ILessonService, LessonService>();

#region jwt校验  HS

JWTTokenOptions tokenOptions = new JWTTokenOptions();
builder.Configuration.Bind("JWTTokenOptions", tokenOptions);

builder.Services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)//Bearer Scheme
.AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        //JWT有一些默认的属性,就是给鉴权时就可以筛选了
        ValidateIssuer = true,//是否验证Issuer
        ValidateAudience = true,//是否验证Audience
        ValidateLifetime = true,//是否验证失效时间---默认还添加了300s后才过期
        ClockSkew = TimeSpan.FromSeconds(0),//token过期后立马过期
        ValidateIssuerSigningKey = true,//是否验证SecurityKey

        ValidAudience = tokenOptions.Audience,//Audience,需要跟前面签发jwt的设置一致
        ValidIssuer = tokenOptions.Issuer,//Issuer,这两项和前面签发jwt的设置一致
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenOptions.SecurityKey)),//拿到SecurityKey
    };
});

#endregion jwt校验  HS

var app = builder.Build();

// Configure the HTTP request pipeline.

app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "CommentMicroService V1"));

app.UsePerOptionsRequest();

app.UseHealthCheckMiddleware();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.UseConsulConfiguration(builder.Configuration).Wait();

app.Run();

标签:Core,ASP,string,builder,Consul,HttpJsonResponse,new,app,public
来源: https://www.cnblogs.com/AJun816/p/16154715.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有