Ocelot+Identity Server

2023-05-16

一、搭建一个ID4.IdServer(.NetCore API)认证服务器项目

1.1、在该项目中添加Nuget包(vs2.1版本安装IdentityServer4 2.5.3版本)

1.2、在ID4.IdServer项目中新建一个Config类

 public class Config
    {
        /// <summary>
        /// 返回应用列表
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<ApiResource> GetApiResources()
        {
            List<ApiResource> resources = new List<ApiResource>();
            //ApiResource第一个参数是应用的名字,第二个参数是描述
            resources.Add(new ApiResource("MsgAPI", "消息服务API"));
            resources.Add(new ApiResource("ProductAPI", "产品API"));
            return resources;
        }


        /// <summary>
        /// 返回账号列表
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<Client> GetClients()
        {
            List<Client> clients = new List<Client>();
            clients.Add(new Client
            {
                ClientId = "clientPC1",//API账号、客户端Id
                AllowedGrantTypes = GrantTypes.ClientCredentials,
                ClientSecrets =
                {
                      new Secret("123321".Sha256())//秘钥
                },
                AllowedScopes = { "MsgAPI", "ProductAPI" }//这个账号支持访问哪些应用
            });
            return clients;
        }
    }

1.3、在ID4.IdServer项目下Startup类中ConfigureServices方法进行注册

 public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            //注册服务
            services.AddIdentityServer()
            .AddDeveloperSigningCredential()
            .AddInMemoryApiResources(Config.GetApiResources())
            .AddInMemoryClients(Config.GetClients());
        }

1.4、在ID4.IdServer项目下Startup类中Configure方法进行注册中间件

​
 public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }
            //注册中间件
            app.UseIdentityServer();
            app.UseHttpsRedirection();
            app.UseMvc();
            
        }

​

1.5、然后在 5000 端口启动 、在 postman 里发出请求,获取 token 
http://localhost:5000/connect/token,发 Post 请求,表单请求内容(注意不是报文头): 
client_id=clientPC1 client_secret=123321 grant_type=client_credentials 

 

二、 搭建 Ocelot 服务器项目

2.1、先在之前博客上OcelotTest API网关项目中添加Nuget包(vs2.1版本安装IdentityServer4 2.5.3版本)

2.2、在OcelotTest API网关项目configuration.json文件中进行修改

{
  "ReRoutes": [
    {
      "DownstreamPathTemplate": "/api/{url}",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/MsgService/{url}",
      "UpstreamHttpMethod": [ "Get", "Post" ],
      "ServiceName": "MsgService",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "UseServiceDiscovery": true,
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "MsgKey",
        "AllowedScopes": []
      }
    },
    {
      "DownstreamPathTemplate": "/api/{url}",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/ProductService/{url}",
      "UpstreamHttpMethod": [ "Get", "Post" ],
      "ServiceName": "ProductService",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "UseServiceDiscovery": true,
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "ProductKey",
        "AllowedScopes": []
      }
    }
  ],
  "GlobalConfiguration": {
    "ServiceDiscoveryProvider": {
      "Host": "localhost",
      "Port": 8500
    }
  }
}

2.3、在OcelotTest项目中修改 Startup类中ConfigureServices方法让 Ocelot 能够访问 Identity Server 进行 Token 的验证

public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
  
            //指定Identity Server的信息
            Action<IdentityServerAuthenticationOptions> isaOptMsg = o => {
                o.Authority = "http://localhost:5003";
                o.ApiName = "MsgAPI";//要连接的应用的名字
                o.RequireHttpsMetadata = false;
                o.SupportedTokens = SupportedTokens.Both;
                o.ApiSecret = "123321";//秘钥
            };
            Action<IdentityServerAuthenticationOptions> isaOptProduct = o => {
                o.Authority = "http://localhost:5003";
                o.ApiName = "ProductAPI";//要连接的应用的名字
                o.RequireHttpsMetadata = false;
                o.SupportedTokens = SupportedTokens.Both;
                o.ApiSecret = "123321";//秘钥
            };
            services.AddAuthentication()
            //对配置文件中使用ChatKey配置了AuthenticationProviderKey=MsgKey
            //的路由规则使用如下的验证方式
            .AddIdentityServerAuthentication("MsgKey", isaOptMsg)
            .AddIdentityServerAuthentication("ProductKey", isaOptProduct);
            //注册ocelot服务
            services.AddOcelot(Configuration).AddConsul();
        }

2.4、在OcelotTest API网关项目Program类中进行修改

 public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)              
            .UseUrls("http://localhost:9500")
            .ConfigureAppConfiguration((hostingContext, builder) =>
            {
                builder.AddJsonFile("configuration.json", false, true);
            }).UseStartup<Startup>();
    }

2.5、启动 Ocelot 服务器,然后向 ocelot 请求/MsgService/SMS/Send_MI(报文体还是要传 json 数据),在请求头(不是报文体)里加上: Authorization="Bearer "+上面 identityserver 返回的 accesstoken

如果返回 401,那就是认证错误。 
Ocelot 会把 Authorization 值传递给后端服务器,这样在后端服务器可以用 IJwtDecoder 
的这个不传递 key 的重载方法 IDictionary<string, object> DecodeToObject(string token),就可 
以在不验证的情况下获取 client_id 等信息。 
也可以把 Identity Server 通过 Consul 进行服务治理。 
Ocelot+Identity Server 实现了接口的权限验证,各个业务系统不需要再去做验证。

 

三、用户名密码登录

3.1、在ID4.IdServer项目中新建一个ProfileService类

namespace ID4.IdServer
{
    public class ProfileService : IProfileService
    {
        public async Task GetProfileDataAsync(ProfileDataRequestContext context)
        {
            var claims = context.Subject.Claims.ToList();
            context.IssuedClaims = claims.ToList();
        }
        public async Task IsActiveAsync(IsActiveContext context)
        {
            context.IsActive = true;
        }
    }
}

3.2、在ID4.IdServer项目中再新建一个ResourceOwnerPasswordValidator验证类

public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
    {
        public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
        {
            //根据context.UserName和context.Password与数据库的数据做校验,判断是否合法
            if (context.UserName == "yzk" && context.Password == "123")
            {
                context.Result = new GrantValidationResult(
                subject: context.UserName,
                authenticationMethod: "custom",
                claims: new Claim[] { new Claim("Name",context.UserName), new Claim("UserId","111"), new Claim("RealName", "杨中科"), new Claim("Email", "yzk365@qq.com") });
            }
            else
            {
                //验证失败
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "invalid custom credential");
            }
        }
    }

(注:当然这里的用户名密码是写死的,可以在项目中连接自己的用户数据库进行验证。claims 中可以 放入多组用户的信息,这些信息都可以在业务系统中获取到)

3.3、进行修改ID4.IdServer项目中Config类

    public class Config
    {
        /// <summary>
        /// 返回应用列表
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<ApiResource> GetApiResources()
        {
            List<ApiResource> resources = new List<ApiResource>();
            //ApiResource第一个参数是应用的名字,第二个参数是描述
            resources.Add(new ApiResource("MsgAPI", "消息服务API"));
            resources.Add(new ApiResource("ProductAPI", "产品API"));
            return resources;
        }
        /// <summary>
        /// 返回客户端账号列表
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<Client> GetClients()
        {
            List<Client> clients = new List<Client>();
            clients.Add(new Client
            {
                ClientId = "clientPC1",//API账号、客户端Id
                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
                ClientSecrets =
                {
                   new Secret("123321".Sha256())//秘钥
                },
                AllowedScopes = { "MsgAPI","ProductAPI",IdentityServerConstants.StandardScopes.OpenId, //必须要添加,否则报forbidden错误
                IdentityServerConstants.StandardScopes.Profile }//这个账号支持访问哪些应用
            });
            return clients;
        }
    }

3.4、进行修改ID4.IdServer项目中Startup类中ConfigureServices方法

public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            //注册服务
            var idResources = new List<IdentityResource>
            {
              new IdentityResources.OpenId(), //必须要添加,否则报无效的 scope 错误
              new IdentityResources.Profile()
            };
            services.AddIdentityServer()
            .AddDeveloperSigningCredential()
            .AddInMemoryIdentityResources(idResources)
            .AddInMemoryApiResources(Config.GetApiResources())
            .AddInMemoryClients(Config.GetClients())//
            .AddResourceOwnerValidator<ResourceOwnerPasswordValidator>()
            .AddProfileService<ProfileService>();
        }

(注:主 要 是 增 加 了 AddInMemoryIdentityResources 、 AddResourceOwnerValidator 、AddProfileService)

3.5、进行修改ID4.IdServer项目中Program类

  public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>().UseUrls($"http://localhost:5003");
    }

3.6 修改业务系统

3.6.1、在之前博客上MsgService信息服务项目中添加Nuget包(IdentityServer4.AccessTokenValidation)

3.6.2、在MsgService项目下Startup类中ConfigureServices方法进行修改

 public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            //注册服务
            services.AddAuthentication("Bearer")
            .AddIdentityServerAuthentication(options =>
            {
                options.Authority = "http://localhost:5003";//identity server 地址
                options.RequireHttpsMetadata = false;
            });          
        }

3.6.3、在MsgService项目下Startup类中Configure方法添加注册中间件

//注册中间件
app.UseAuthentication();

3.6.4、在MsgService项目下Program类中进行修改

 public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args)
        {
            var config = new ConfigurationBuilder().AddCommandLine(args).Build();
            String ip = config["ip"];
            String port = config["port"];
            return  WebHost.CreateDefaultBuilder(args)
                   .UseStartup<Startup>()
                   .UseUrls($"http://{ip}:{port}");
        }
    }

3.7、请求 token 、把报文头中的 grant_type 值改为 password,报文头增加 username、password 为用户名、密码

 

四、创建一个LoginService(.NetCore Api) 独立登录服务器项目

4.1、在LoginService项目中新建一个RequestTokenParam类

 public class RequestTokenParam
    {
        public string username { get; set; }
        public string password { get; set; }
    }

4.2、在LoginService项目中新建一个LoginController(Api)控制器

namespace LoginService.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class LoginController : ControllerBase
    {
        [HttpPost]
        public async Task<ActionResult> RequestToken(RequestTokenParam model)
        {
            Dictionary<string, string> dict = new Dictionary<string, string>();
            dict["client_id"] = "clientPC1";
            dict["client_secret"] = "123321";
            dict["grant_type"] = "password";
            dict["username"] = model.username;
            dict["password"] = model.password;
            //由登录服务器向IdentityServer发请求获取Token
            using (HttpClient http = new HttpClient())
            using (var content = new FormUrlEncodedContent(dict))
            {
                var msg = await http.PostAsync("http://localhost:5003/connect/token", content);
                string result = await msg.Content.ReadAsStringAsync();
                return Content(result, "application/json");
            }
        }
    }
}

(这 样 客 户 端 只 要 向 LoginService 的 /api/Login/ 发 请 求 带 上 json 报文体 {username:"yzk",password:"123"}即可。客户端就不知道 client_secret 这些机密信息了)

4.3、在LoginService项目中对Program类进行修改

public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>().UseUrls($"http://localhost:6008");
    }

 

五、创建一个LoginServer(WinForm窗体)项目

5.1、在LoginServer项目中添加Nuget包(Newtonsoft.Json)

5.2、在LoginServer项目Form1窗体中添加QQ登录按钮

5.3、Form1窗体按钮点击事件代码

 public partial class Form1 : Form
    {
        public static string token;
        public Form1()
        {
            InitializeComponent();
        }


        public class SendSMSRequest
        {
            public string PhoneNum { get; set; }
            public string Msg { get; set; }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            FrmLogin login = new FrmLogin();
            login.ShowDialog();
        }

        private async void BtnQQLogin_Click(object sender, EventArgs e)
        {
            SendSMSRequest req = new SendSMSRequest();
            req.PhoneNum = "189189189";
            req.Msg = "hello world!";
            string jsonReq = JsonConvert.SerializeObject(req);

            using (var http = new HttpClient())
            using (var content = new StringContent(jsonReq, Encoding.UTF8, "application/json"))
            {
                http.DefaultRequestHeaders.Authorization = AuthenticationHeaderValue.Parse(token);
                var resp = await http.PostAsync("http://localhost:9500/MsgService/SMS/Send_LX", content);
                if (resp.StatusCode != System.Net.HttpStatusCode.OK)
                {
                    MessageBox.Show("发送错误,状态码" + resp.StatusCode);
                }
                else
                {
                    MessageBox.Show("发送成功");
                }
            }
        }
    }

5.4、在LoginServer项目新建一个FrmLogin窗体

5.5、FrmLogin窗体中代码

public partial class FrmLogin : Form
    {
        public FrmLogin()
        {
            InitializeComponent();
        }

        
        class LoginReq
        {
            public string username { get; set; }
            public string password { get; set; }
        }

        private void FrmLogin_Load(object sender, EventArgs e)
        {

        }

        private async void BtnLogin_Click(object sender, EventArgs e)
        {
            LoginReq req = new LoginReq();
            req.username = txtUserName.Text;
            req.password = txtPassword.Text;
            //转换成json
            string jsonReq = JsonConvert.SerializeObject(req);
            //发送请求
            using (HttpClient http = new HttpClient())
            using (var content = new StringContent(jsonReq, Encoding.UTF8, "application/json"))
            {
                var resp = await http.PostAsync("http://localhost:9500/LoginService/Login", content);
                if (resp.IsSuccessStatusCode == false)
                {
                    MessageBox.Show("error" + resp.StatusCode);
                    return;
                }
                string jsonResp = await resp.Content.ReadAsStringAsync();
                dynamic respObj = JsonConvert.DeserializeObject<dynamic>(jsonResp);
                //获取token
                string access_token = respObj.access_token;
                string token_type = respObj.token_type;
                // MessageBox.Show(token_type+" "+access_token);
                Form1.token = token_type + " " + access_token;
                this.Close();
            }
        }
    }

 

六、操作OcelotTest(API 网关)项目

6.1、在OcelotTest项目下configuration.json文件再进一步修改

{
  "ReRoutes": [
    {
      "DownstreamPathTemplate": "/api/{url}",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/MsgService/{url}",
      "UpstreamHttpMethod": [ "Get", "Post" ],
      "ServiceName": "MsgService",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "UseServiceDiscovery": true,
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "MsgKey",
        "AllowedScopes": []
      }
    },
    {
      "DownstreamPathTemplate": "/api/{url}",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/ProductService/{url}",
      "UpstreamHttpMethod": [ "Get", "Post" ],
      "ServiceName": "ProductService",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "UseServiceDiscovery": true,
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "ProductKey",
        "AllowedScopes": []
      }
    },
    {
      "DownstreamPathTemplate": "/api/{url}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 6008
        }
      ],
      "UpstreamPathTemplate": "/LoginService/{url}",
      "UpstreamHttpMethod": [ "Get", "Post" ]
    }
  ],
  "GlobalConfiguration": {
    "ServiceDiscoveryProvider": {
      "Host": "localhost",
      "Port": 8500
    }
  }
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Ocelot+Identity Server 的相关文章

  • 服务器显示文本而不是 HTML

    我正在尝试创建一个 C 服务器 它将接受输入并能够通过 html 格式将它们返回给用户 其中服务器充当用户界面 我当前的问题似乎无法弄清楚为什么 C 服务器在 localhost 3838 处将 HTML 代码以文本形式吐出 而不是将其显示
  • WSO2 身份服务器 - Oauth 2.0 - Java 签核示例

    我为 Oauth2 身份验证流程编写了一个基于 Java 的签核例程 令牌撤销 请参阅下面的代码实现 遵循手册中描述的 cURL 协议说明 here https docs wso2 com display IS500 OAuth Token
  • Tomcat 和 TomEE、TomEE 和 TomEE Plus 之间有什么区别

    我想在服务器中部署 EJB Ear 但我对选择服务器感到非常困惑tomcat TomEE and TomEE Plus 两者有什么区别Tomcat and TomEE 其中有哪些新功能TomEE and TomEE Plus 在什么情况下才
  • Ruby 中按身份分组

    鲁比的怎么样group by http ruby doc org core 2 2 3 Enumerable html method i group by方法按标识对数组进行分组 或者更确切地说self 其元素 a abccac chars
  • 在插入行上返回最后一个 ID (IDENTITY) VB.NET MySQL

    Dim insert coupon query As String INSERT INTO qa discountcoupons id status code VALUES AUTO INCREMENT ID 5 Dim cmd query
  • 如何在Windows平台上编写Git Server Hooks?

    我找不到任何适用于 Windows 的 Git 挂钩的明确示例 我在 Windows Server 上使用 Bonobo Git Server 我需要预提交和提交后挂钩作为 cmd 或 bat 预提交应检查空注释 提交后应发送有关提交的电子
  • 错误:在 Google 应用引擎上部署节点 js 时找不到模块“/workspace/server.js”

    经过一周的搜索 我无法找到适用于我的 Node js 应用程序的应用程序引擎部署问题的解决方案 我已经用这个替换了原来的代码Express 的 hello world 示例 https expressjs com en starter he
  • 当 URL 可在浏览器中访问时,SSH Curl 不起作用

    This post is linked with another post of mine still unsolved Laravel 作曲家更新 连接被拒绝 https stackoverflow com questions 52404
  • 对 Python 的 id() 感到困惑[重复]

    这个问题在这里已经有答案了 我可以理解以下定义 每个对象都有一个身份 类型和值 对象的身份 一旦创建就永远不会改变 你可能会认为它是 对象在内存中的地址 这is操作员比较身份 两个物体 这id 函数返回一个代表其值的整数 身份 我假设上面的
  • PHP 扩展 mysqli 和 nd_mysqli 之间的区别[重复]

    这个问题在这里已经有答案了 Mysqli 准备好的语句 如下所示 在以下情况下会抛出以下错误 get result 叫做 stmt connection gt prepare select column from table where i
  • 结果身份改变

    我正在使用 TOR 我想知道如何在需要国家 地区的结果节点之间切换 我可以简单地通过 telnet 9051 端口来更改它 例如 telnet localhost 9051 AUTHENTICATE r signal NEWNYM r qu
  • 为什么turn服务器不支持tcp连接?

    我是 WebRTC 新手 我需要为我的 webrtc 应用程序配置我自己的 Turn 服务器 我使用以下命令安装了我的转弯服务器 apt get install coturn 我只需要通过 tcp 运行转变服务器 它不必使用 UDP 进行任
  • 如何关闭 Grizzly 日志记录?

    如何关闭 Grizzly 的日志记录 我想关闭以下日志记录 Okt 18 2018 8 42 24 AM org glassfish grizzly http server NetworkListener start INFORMATION
  • Rails 的 Puma Systemd 配置不起作用

    我已经完成了一个使用 Ruby on Rails 构建的应用程序 现在我想将其托管在 AWS 上的 EC2 实例上 我已经为其配置了服务器 并且正在使用pumaHTTP服务器作为应用服务器 在生产中启动应用程序总是需要我运行RAILS EN
  • 插入记录后如何从SQL Server获取Identity值

    我在数据库中添加一条记录identity价值 我想在插入后获取身份值 我不想通过存储过程来做到这一点 这是我的代码 SQLString INSERT INTO myTable SQLString Cal1 Cal2 Cal3 Cal4 SQ
  • Grpc - 将消息从一个客户端发送到连接到同一服务器的另一个客户端

    是否可以将消息从一个客户端发送到连接到同一服务器的另一个客户端 我想将数据从一个客户端发送到服务器然后发送到特定客户端 我想我需要获取客户端 ID 但我不知道如何获取此 ID 以及如何从服务器将此消息发送到该客户端 我这里有一个样本 这是一
  • Jetty Plugin 9启动不喜欢icu4j-2.6.1.jar

    我对 mortbay 的 Maven jetty 插件 6 有相同的配置
  • 查找“未找到身份”的角色分配的可靠方法是什么?在 Azure 上使用 Powershell?

    如果您在 Azure 中分配角色 然后在删除角色分配之前删除该身份 则会出现 找不到身份 的情况 健康 状况 它是无害的 但它会占用角色分配空位并使角色分配列表变得混乱 我想找到并删除这些 我想这个 Get AzRoleAssignment
  • 在 CMS(Wordpress 和 phpBB)之间共享登录信息

    假设我想开发一个嵌入一些 CMS 的网站 例如 WordPress http wordpress org 博客和phpbb http www phpbb com forum 统一网站登录和注册流程的最便捷方法是什么 让用户对网站的每个部分采
  • 詹金斯上的登录类型选择有什么区别?

    我之前已经在一些机器上通过 war 文件和作为 Windows 服务安装的网页安装了 jenkins 现在我尝试通过 msi 文件将其安装在另一台计算机上 但我遇到了一个问题 在安装步骤中 有一个步骤询问我 登录类型 这给了我 2 个选择

随机推荐

  • 快速安装Pytorch和Torchvision

    文章目录 1 Linux下激活自己的虚拟环境并查看Python版本2 查看需要安装的Pytorch和Torchvision版本3 直接命令行安装3 1 如果不报错的话3 2 ERROR Could not install packages
  • 【Darknet-53】YOLOv3 backbone Darknet-53 详解

    文章目录 1 模型计算量与参数量2 Darknet 53网络3 感谢链接 1 模型计算量与参数量 模型计算量与参数量的计算方式主要有两种 xff0c 一种是使用thop库 xff0c 一种是使用torchsummaryX 使用pip ins
  • 【DeeplabV3+】DeeplabV3+网络结构详解

    文章目录 1 常规卷积与空洞卷积的对比1 1 空洞卷积简介1 2 空洞卷积的优点 2 DeeplabV3 43 模型简介3 DeeplabV3 43 网络代码4 mobilenetv2网络代码5 感谢链接 聊DeeplabV3 43 网络前
  • 【YOLOv3 decode】YOLOv3中解码理解decode_box

    文章目录 1 解码是什么意思2 代码解读3 生成网格中心 代码详解4 按照网格格式生成先验框的宽高 代码详解5 感谢链接 1 解码是什么意思 在利用YOLOv3网络结构提取到out0 out1 out2之后 xff0c 不同尺度下每个网格点
  • 【DeeplabV3+ MIoU】DeeplabV3+计算评价指标

    文章目录 1 分割常用评价指标1 1 什么是MIoU1 2 什么是PA1 2 什么是MPA 2 根据混淆矩阵计算评价指标2 1 计算MIoU2 2 计算PA2 3 计算MPA 3 计算 MIoU 总体代码4 compute mIoU 函数
  • 【MobileNetV3】MobileNetV3网络结构详解

    文章目录 1 MobileNetV3创新点2 block变成了什么样2 1 总体介绍2 2 SE模块理解2 3 ReLu6和hardswish激活函数理解 3 网络总体结构4 代码解读5 感谢链接 在看本文前 xff0c 强烈建议先看一下之
  • 【Smooth L1 Loss】Smooth L1损失函数理解

    文章目录 1 引言2 L1 Loss3 L2 Loss4 Smooth L1 Loss5 曲线对比分析6 参考链接 1 引言 目标检测任务的损失函数由Classificition Loss和Bounding Box Regeression
  • Command errored out with exit status 1类似问题解决方案

    在使用pip install onnx时遇到如下错误 xff1a Building wheels for collected packages onnx Building wheel for onnx setup py error ERRO
  • 【tensorflow onnx】TensorFlow2导出ONNX及模型可视化教程

    文章目录 1 背景介绍2 实验环境3 tf2onnx工具介绍4 代码实操4 1 TensorFlow2与ONNX模型导出4 2 ONNX正确性验证4 3 TensorFlow2与ONNX的一致性检查4 4 多输入的情况4 5 设定输入 输出
  • 如何在Microsoft Edge中更改主页

    By default Microsoft Edge opens with a custom New Tab page full of content Luckily it s easy to open the browser with a
  • 【PaddlePaddle onnx】PaddlePaddle导出ONNX及模型可视化教程

    文章目录 1 背景介绍2 实验环境3 paddle onnx export函数简介4 代码实操4 1 PaddlePaddle与ONNX模型导出4 2 ONNX正确性验证4 3 PaddlePaddle与ONNX的一致性检查4 4 多输入的
  • 【linux命令】如何查看文件/文件夹所占空间大小

    文章目录 1 查看文件大小1 1 方法1 xff1a ls lh1 2 方法2 xff1a du sh1 3 方法3 xff1a stat 2 查看文件夹所占大小2 1 方法1 xff1a du2 2 方法2 xff1a ncdu 1 查看
  • Github+Hexo搭建个人博客(图文详解)

    文章目录 使用Github 43 hexo搭建个人博客 不会让小伙伴们走弯路 1 准备工作 xff1a 安装两个我们本次所需要使用的软件 xff1a 2 注册Github账号以及建立仓库 xff1a https github com htt
  • 2019-12-14-FTP服务器搭建

    title FTP服务器搭建 date 2019 12 14 15 34 19 updated 2019 12 14 15 34 19 categories 服务器 搭建 网络 tags FTP服务器 目录 什么是FTP服务器本地FTP服务
  • 小程序开发需要多少钱?

    小程序开发的费用 xff1a 一般几千到几万不等 看具体要求 其实开发小程序的价格主要取决于你要做多少页面和要做的页面和功能的复杂程度 如果是行业内比较成熟的标准化系统就会相对便宜点 至于开发多少钱 xff0c 这样看你采用以下哪种模式 x
  • Docker 1 - 基本使用

    Docker 文章目录 Docker一 关于 Docker安装 Docker1 查看版本2 安装3 卸载 Docker 常见命令查看Docker 磁盘使用情况清理磁盘停止Docker 服务 二 镜像查看已安装镜像拉取镜像删除镜像查找镜像方式
  • Spring MVC的异常处理和友好页面

    加油 xff0c 新时代打工人 xff01 Spring MVC详细环境配置和入门 Spring MVC 响应数据和结果视图 SpringMVC实现三种文件上传的方式 实现之前把Spring MVC环境配置完成 xff0c 参考以上文章 S
  • oh-my-posh 配置

    官网 oh my poshpowershell windows 安装 oh my posh winget span class token function install span JanDeDobbeleer OhMyPosh 初始化设
  • matplotlib 点线动画

    matplotlib 点线动画 作者的Github 主写 Web Development HTML PHP CSS JS node js Ruby Sketchup API Python Tkinter Django Matplotlib
  • Ocelot+Identity Server

    一 搭建一个ID4 IdServer NetCore API 认证服务器项目 1 1 在该项目中添加Nuget包 vs2 1版本安装IdentityServer4 2 5 3版本 1 2 在ID4 IdServer项目中新建一个Config