Ocelot 认证与授权

Ocelot 认证与授权

 

目前项目接口都是公开的,没有经过任何的认证,只要知道接口的调用方法,任何人都可以随意调用,因此,很容易就造成信息泄露或者服务被攻击。

需要在Ocelot中接入IdentityServer4的认证与授权。

 

IdentityServer4使用

 

NETCORE - IdentityServer4 身份认证 ,可参考:https://www.cnblogs.com/1285026182YUAN/p/15250347.html

 

IdentityServer4有多种认证模式,包括用户密码、客户端等等,我这里只需要实现IdentityServer4的验证过程即可,因此,我选择了使用最简单的客户端模式。

首先我们来看,当没有Ocelot网关时系统是如何使用IdentityServer4进行认证的。

客户端需要先想IdentityServer请求认证,获得一个Token,然后再带着这个Token向下游服务发出请求。

 

 

 一. IdentityServer服务端

 创建IdentityServer服务端

1. 创建项目 :IdentityServer

  框架:netcore web api 

 

 

2. 增加 nuget 包:IdentityServer4

 

 

3. 配置文件:appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
 },
"SSOConfig": { "ApiResources": [ { "Name": "identityAPIService", "DisplayName": "identityAPIServiceName" } ], "Clients": [ { "ClientId": "mark", "ClientSecrets": [ "markjiang7m2" ], "AllowedGrantTypes": "ClientCredentials", "AllowedScopes": [ "identityAPIService" ] } ] }, "AllowedHosts": "*" }

 

ApiResources为数组类型,表示IdentityServer管理的所有的下游服务列表

  • Name: 下游服务名称

  • DisplayName: 下游服务别名

Clients为数组类型,表示IdentityServer管理的所有的上游客户端列表

  • ClientId: 客户端ID

  • ClientSecrets: 客户端对应的密钥

  • AllowedGrantTypes: 该客户端支持的认证模式,目前支持如下:

    • Implicit

    • ImplicitAndClientCredentials

    • Code

    • CodeAndClientCredentials

    • Hybrid

    • HybridAndClientCredentials

    • ClientCredentials

    • ResourceOwnerPassword

    • ResourceOwnerPasswordAndClientCredentials

    • DeviceFlow

  • AllowedScopes: 该客户端支持访问的下游服务列表,必须是在ApiResources列表中登记的

 

4. 创建配置文件类:SSOConfig,用于读取配置文件。

using IdentityServer4.Models;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace IdentityServer
{
    public class SSOConfig
    {
        private IConfigurationSection section;

        public SSOConfig(IConfiguration Configuration)
        {
            section = Configuration.GetSection("SSOConfig");
        }


        public IEnumerable<IdentityResource> GetIdentityResources()
        {
            return new List<IdentityResource> { new IdentityResources.OpenId(), new IdentityResources.Profile() };
        }



        public IEnumerable<ApiResource> GetApiResources()
        {
            List<ApiResource> resource = new List<ApiResource>();

            if (section != null)
            {
                List<ApiConfig> configs = new List<ApiConfig>();
                section.Bind("ApiResources", configs);
                foreach (var config in configs)
                {
                    resource.Add(new ApiResource(config.Name, config.DisplayName) { Scopes = { config.Name } });
                }
            }

            return resource.ToArray();
        }

        /// <summary>
        /// 定义受信任的客户端 Client
        /// </summary>
        /// <returns></returns>
        public IEnumerable<Client> GetClients()
        {
            List<Client> clients = new List<Client>();

            if (section != null)
            {
                List<ClientConfig> configs = new List<ClientConfig>();
                section.Bind("Clients", configs);
                foreach (var config in configs)
                {
                    Client client = new Client();
                    client.ClientId = config.ClientId;
                    List<Secret> clientSecrets = new List<Secret>();
                    foreach (var secret in config.ClientSecrets)
                    {
                        clientSecrets.Add(new Secret(secret.Sha256()));
                    }
                    client.ClientSecrets = clientSecrets.ToArray();

                    GrantTypes grantTypes = new GrantTypes();
                    var allowedGrantTypes = grantTypes.GetType().GetProperty(config.AllowedGrantTypes);
                    client.AllowedGrantTypes = allowedGrantTypes == null ?
                        GrantTypes.ClientCredentials : (ICollection<string>)allowedGrantTypes.GetValue(grantTypes, null);

                    client.AllowedScopes = config.AllowedScopes.ToArray();
                    clients.Add(client);
                }
            }
            return clients.ToArray();
        }

        public IEnumerable<ApiScope> GetApiScopes()
        {
            var apiScopes = new List<ApiScope>();

            List<ApiConfig> configs = new List<ApiConfig>();
            section.Bind("ApiResources", configs);

            var scopes = configs.Select(t => { return t.Name; }).ToList();

            scopes.ForEach(t => { apiScopes.Add(new ApiScope(t)); });

            return apiScopes;
        }
    }

    public class ApiConfig
    {
        public string Name { get; set; }
        public string DisplayName { get; set; }
    }

    public class ClientConfig
    {
        public string ClientId { get; set; }
        public List<string> ClientSecrets { get; set; }
        public string AllowedGrantTypes { get; set; }
        public List<string> AllowedScopes { get; set; }
    }
}

 

 

 

 5. 服务注册:startup.cs

        public void ConfigureServices(IServiceCollection services)
        {
            var ssoConfig = new SSOConfig(Configuration);
            services.AddIdentityServer()//Ids4服务
                .AddDeveloperSigningCredential()//添加开发人员签名凭据
                .AddInMemoryIdentityResources(ssoConfig.GetIdentityResources())//添加内存apiresource
                .AddInMemoryApiResources(ssoConfig.GetApiResources())
                .AddInMemoryApiScopes(ssoConfig.GetApiScopes())
                .AddInMemoryClients(ssoConfig.GetClients());//把配置文件的client配置资源放到内存

            services.AddControllers();
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "IdentityServer", Version = "v1" });
            });
        }

 

 

 

 中间件使用

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "IdentityServer v1"));
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseIdentityServer();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }

 

修改端口号为:8005 

 

配置完成,启动项目后,调用接口获取 token 。

 

 

 

 

 

二. 下游服务认证配置

项目:OService1

增加 nuget 包, IdentityServer4.AccessTokenValidation

 

 

 

appsettings.json中加入IdentityServer服务信息

 

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "IdentityServerConfig": {
    "ServerIP": "localhost",
    "ServerPort": 8005,
    "IdentityScheme": "Bearer",
    "ResourceName": "identityAPIService"
  },
  "AllowedHosts": "*"
}

 

这里的identityAPIService就是在IdentityServer服务端配置ApiResources列表中登记的其中一个下游服务。

 

Startup.cs中读取IdentityServer服务信息,加入IdentityServer验证

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

引用:http://letyouknow.net/ocelot/ocelot-tutorial-4.html
项目:https://gitee.com/wuxincaicai/ocelothost.git

 

posted @ 2021-10-13 16:34  无心々菜  阅读(315)  评论(0编辑  收藏  举报