dotnet最小webApi开发实践

软件开发过程中,经常需要写一些功能验证代码。通常是创建一个console程序来验证测试,但黑呼呼的方脑袋界面,实在是不讨人喜欢。

Web开发目前已是网络世界中的主流,微软在asp.net框架大行其道之下,也整了个最小webapi项目开发向导。

今天,我也拥抱一下新的开发模式,来使用webapi方式来做一个小的应用实践。

打开宇宙最强编辑器VS2022,根据向导进行创建新项目,我们选择ASP.NET Core Web API项目。

填写项目配置信息,我们今天来创建一个访客IP白名单授权的功能。功能就是当访客访问web页面时,页面请求api授权,api对网络授权请求来源进行判断,当访客来源地址为白名单中的地址时,返回一个http 200的响应,当访客来源IP不在白名单时,返回一个 http 401未证的响应。

.net框架选项中,最低只有.net8.0可选

点击创建,vs自动为我们生成了项目和代码

namespace flyfire.whitelistAuthorization
{
public class Program
{
public static void Main( string [] args)
{
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(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
} app.UseAuthorization();
app.MapControllers();
app.Run();
}
}
}

框架不仅生成了代码,还默认增加了调试模式下使用丝袜哥(swagger)作为web测试的界面,真是贴心啊。

向导生成了一个天气预报的类和一个web控制器

天气预报的类

namespace flyfire.whitelistAuthorization
{
public class WeatherForecast
{
public DateOnly Date { get ; set ; }
public int TemperatureC { get ; set ; }
public int TemperatureF => 32 + ( int )(TemperatureC / 0.5556);
public string ? Summary { get ; set ; }
}
}

 

天气预报web控制器

using Microsoft.AspNetCore.Mvc;
namespace flyfire.whitelistAuthorization.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
}; private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
} [HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
}

什么代码都不用写,一个最小示例webApi接口方法就OK了。

下面我们来编写一个自己的功能。

在解决方案管理器控制目录上,右键菜单,新建一个API控制器。

选择API分类

我们创建一个名为 “WhitelistAuthorization”的空的API控制器.

我们将在WhitelistAuthorization控制器中,实现一个Authorization接口方法,当请求来源的IP地址为白名单地址时,返回StatusCode  200,并返回一些信息,否则返回StatusCode  401和未授权信息。

我们在appsetting.json中使用的个section存放白名单IP信息。

 "WhiteIpList": {
"IpList": [
"127.0.0.1"
]
}

我们创建一个类WhiteIpList用于映射配置数据。

public class WhiteIpList
{
public List< string > IpList { get ; set ; }
}

在Main函数中,增加如下代码,将配置段实例化绑定并注入到依赖注入(DI)容器

builder.Services.Configure<WhiteIpList>(builder.Configuration.GetSection("WhiteIpList"));

然后,我们在WhitelistAuthorization控制器的构造函数中,注入配置参数。

private readonly WhiteIpList _whiteIpList;

public WhitelistAuthorizationController(IOptions<WhiteIpList> whiteIpList)

{

_whiteIpList = whiteIpList.Value;

}

接着,我们增加一个认证授权方法,用于认证授权,返回状态码200或401。

       [HttpGet("[action]")]
[HttpPost("[action]")]
public IActionResult Authorization()
{
var remote_ip = GetClientIpAddress(HttpContext.Request); if (Untility.IsIpExist(_whiteIpList.IpList, remote_ip))
{
return Ok(new
{
body = new
{
code = 200
}
});
}
else
{
return StatusCode(401, "Unauthorized: IP address not in whitelist.");
}
}

HttpRequest的HttpContext.Connection.RemoteIpAddress中可获得浏览端的IP地址。

不过,如果认证服务接口需经过Nginx转发时,则需要对Nginx进行一些配置以及相应的代码处理方可有效获取到浏览端的IP。

当网络HTTP请求经过Nginx服务器转发时,Web API仍然有可能获取到请求方的IP地址,但这取决于Nginx的配置以及Web API如何解析这些信息。

Nginx配置

Nginx可以通过proxy_set_header指令来添加或修改转发给后端服务器的请求头。为了获取请求方的IP地址,你需要在Nginx配置文件中设置X-Forwarded-For请求头,该请求头会包含客户端的原始IP地址。

例如,你可以在Nginx的配置文件(通常是nginx.conf或某个站点的配置文件)中添加以下行:

proxy_set_header X-Forwarded-For $remote_addr;

这行代码会将客户端的IP地址添加到X-Forwarded-For请求头中,并将其转发给后端服务器。如果客户端和Nginx之间有多层代理,X-Forwarded-For请求头可能会包含多个IP地址,第一个地址通常是客户端的原始IP。

Web API解析

在Web API中,你需要检查X-Forwarded-For请求头来获取客户端的IP地址。这通常涉及到从HTTP请求中提取请求头信息。

以下是一个在ASP.NET Core Web API中获取客户端IP地址的示例代码:

    csharp

    public string GetClientIpAddress(HttpRequest request)

    {

        // 首先尝试从X-Forwarded-For请求头中获取IP地址

        var xForwardedFor = request.Headers["X-Forwarded-For"].ToString();

        if (!string.IsNullOrEmpty(xForwardedFor))

        {

            // 如果X-Forwarded-For包含多个IP地址,取第一个地址作为客户端IP

            var ipAddresses = xForwardedFor.Split(',');

            return ipAddresses.FirstOrDefault()?.Trim();

        }

        // 如果X-Forwarded-For不存在,则尝试从RemoteAddress属性中获取IP地址

        return request.HttpContext.Connection.RemoteIpAddress?.ToString();

    }

在这段代码中,我们首先尝试从X-Forwarded-For请求头中获取IP地址。如果请求头不存在或为空,我们则回退到从RemoteAddress属性中获取IP地址。但请注意,当请求经过Nginx转发时,RemoteAddress属性可能会包含Nginx服务器的IP地址,而不是客户端的IP地址。

注意事项

安全性:X-Forwarded-For请求头可以被客户端伪造,因此它不应该被视为绝对可靠的客户端IP地址来源。在需要高安全性的场景中,你可能需要采取额外的措施来验证客户端的IP地址。

配置一致性:确保你的Nginx服务器和后端Web API都正确配置了相关的请求头处理和解析逻辑。

多层代理:如果请求经过了多层代理服务器,X-Forwarded-For请求头可能会包含多个IP地址。你需要确定如何解析和使用这些地址。如果X-Forwarded-For包含多个IP地址,取第一个地址作为客户端IP

运行项目,在swaggerUI界面框架中进行测试验证

使用localhost地址测试,无法得到有效的IP址,白名单验证失败。

使用127.0.0.1的回环地址测试,可通过白名单验证。

以上,我们使用少量代码,就简单实现了一个支持Get和Post方法的并且可使用配置文件的Authorization授权接口。

dotnet最小webApi开发实践的更多相关文章

  1. Restful WebApi开发实践

    随笔分类 - Restful WebApi开发实践   C#对WebApi数据操作 摘要: ## 目标简化并统一程序获取WebApi对应实体数据的过程,方便对实体进行扩充.原理就是数据服务使用反射发现 ...

  2. WebAPI接口开发实践

    背景 在团队两年多陆续负责了几个项目的开发上线已经代码的review,特别是对老项目的重构过程中,发现之前的API设计是没有任何规范和约定的,不同的开发同学有不同的习惯,因此需要一套规范去约定,现在分 ...

  3. ASP.NET Core WebAPI 开发-新建WebAPI项目 转

    转 http://www.cnblogs.com/linezero/p/5497472.html ASP.NET Core WebAPI 开发-新建WebAPI项目   ASP.NET Core We ...

  4. 如何将dotnet core webapi发布到docker中…

    如何将dotnet core webapi发布到docker中 今天想起来撸一下docker,中途还是遇到些问题,但是这些问题都是由于路径什么的导致不正确,在这儿还是记录下操作过程,今天是基于wind ...

  5. 《JavaScript设计模式与开发实践》整理

    最近在研读一本书<JavaScript设计模式与开发实践>,进阶用的. 一.高阶函数 高阶函数是指至少满足下列条件之一的函数. 1. 函数可以作为参数被传递. 2. 函数可以作为返回值输出 ...

  6. Android游戏开发实践(1)之NDK与JNI开发03

    Android游戏开发实践(1)之NDK与JNI开发03 前面已经分享了两篇有关Android平台NDK与JNI开发相关的内容.以下列举前面两篇的链接地址,感兴趣的可以再回顾下.那么,这篇继续这个小专 ...

  7. TFS 2015 敏捷开发实践 – 在Kanban上运行一个Sprint

    前言:在 上一篇 TFS2015敏捷开发实践 中,我们给大家介绍了TFS2015中看板的基本使用和功能,这一篇中我们来看一个具体的场景,如何使用看板来运行一个sprint.Sprint是Scrum对迭 ...

  8. Android游戏开发实践(1)之NDK与JNI开发01

    Android游戏开发实践(1)之NDK与JNI开发01 NDK是Native Developement Kit的缩写,顾名思义,NDK是Google提供的一套原生Java代码与本地C/C++代码&q ...

  9. Android游戏开发实践(1)之NDK与JNI开发02

    Android游戏开发实践(1)之NDK与JNI开发02 承接上篇Android游戏开发实践(1)之NDK与JNI开发01分享完JNI的基础和简要开发流程之后,再来分享下在Android环境下的JNI ...

  10. vue 2.0 开发实践总结之疑难篇

    续上一篇文章:vue2.0 开发实践总结之入门篇 ,如果没有看过的可以移步看一下. 本篇文章目录如下: 1.  vue 组件的说明和使用 2.  vuex在实际开发中的使用 3.  开发实践总结 1. ...

随机推荐

  1. Linux 基础-查看进程命令 ps 和 top

    目录 1,使用 ps 命令找出 CPU 占用高的进程 2,通过 top 命令定位占用 cpu 高的进程 3,htop 系统监控与进程管理软件 4,参考资料 1,使用 ps 命令找出 CPU 占用高的进 ...

  2. 登陆mysql,Can 't connect to local MySQL server through socket '/tmp/mysql.sock '(2) "

    今天ssh到slave机器上,登陆mysql,遇到下图的报错. 查了一圈,最终解决办法简洁的出乎意料. 首先,要查看mysql服务是否已经启动(真的太容易漏掉) 第2步,你可能会自然而然的以为密码也是 ...

  3. ABC372 (D,E)

    ABC372 (D,E) D 一道比较简单的二分查找题目. 观察到每个数能成为 \(j\) 的条件是独立的,因此想到统计每个数能成为它前面哪些数的 \(j\). 对于每个\(ed​\), 二分 \(1 ...

  4. 去除tinymce中粘贴的样式

    import "tinymce/plugins/paste"; tinymce.init({ ...其他配置, plugins: ["paste"], past ...

  5. 题解:CF634A Island Puzzle

    CF634A Island Puzzle 题解 分析 由于我们仅能移动 \(0\),所以其它数字的相对顺序较原来应该是不变的,所以我们从环中删除 \(0\) 再判断相对位置即可. 还有需要注意的是本题 ...

  6. C#-32位md5加密

    MD5是一种散列函数,它是不可逆的.这意味着你不能通过MD5的输出来恢复输入.MD5不支持解密. C#MD5加密返回32位字串 public static string MD5Encrypt32(st ...

  7. ip addr没有ip显示?

    重新启动网络 service NetworkManager stop systemctl restart network

  8. canvas实例:绚丽小球

    1.思路分析 监听页面尺寸变化(防抖),动态设置canvas大小 监听鼠标移动事件(节流),动态创建小球,小球包含大小,原点坐标,移动方向等信息,其内部方法支持移动和缩小 开启定时器,更新画布内容(清 ...

  9. S2P销讯通-主数据对于客户关系管理系统的重要性

    由于业务发展,各大企业的业务系统经历了从无到有,从简单到复杂,从而形成了一个又一个的业务系统,比如OA.HR.CRM.ERP等等. 主数据在客户关系管理系统(CRM)中扮演着至关重要的角色.主数据是指 ...

  10. openEuler欧拉安装指定版本的nodejs

    1. 安装nodejs dnf -y install nodejs npm config set registry https://registry.npmmirror.com -g npm conf ...