首页 > 编程语言 >asp.net basic auth middleware

asp.net basic auth middleware

时间:2024-04-27 21:25:48浏览次数:28  
标签:WebApi asp middleware api basic dotnet using net public

dotnet-6-basic-authentication-api/Entities/User.cs

namespace WebApi.Entities;

using System.Text.Json.Serialization;

public class User
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Username { get; set; }

    [JsonIgnore]
    public string Password { get; set; }
}

dotnet-6-basic-authentication-api/Services/UserService.cs

namespace WebApi.Services;

using WebApi.Entities;

public interface IUserService
{
    Task<User> Authenticate(string username, string password);
    Task<IEnumerable<User>> GetAll();
}

public class UserService : IUserService
{
    // users hardcoded for simplicity, store in a db with hashed passwords in production applications
    private List<User> _users = new List<User>
    {
        new User { Id = 1, FirstName = "Test", LastName = "User", Username = "test", Password = "test" }
    };

    public async Task<User> Authenticate(string username, string password)
    {
        // wrapped in "await Task.Run" to mimic fetching user from a db
        var user = await Task.Run(() => _users.SingleOrDefault(x => x.Username == username && x.Password == password));

        // on auth fail: null is returned because user is not found
        // on auth success: user object is returned
        return user;
    }

    public async Task<IEnumerable<User>> GetAll()
    {
        // wrapped in "await Task.Run" to mimic fetching users from a db
        return await Task.Run(() => _users);
    }
}

dotnet-6-basic-authentication-api/Controllers/UsersController.cs

namespace WebApi.Controllers;

using Microsoft.AspNetCore.Mvc;
using WebApi.Authorization;
using WebApi.Models;
using WebApi.Services;

[Authorize]
[ApiController]
[Route("[controller]")]
public class UsersController : ControllerBase
{
    private IUserService _userService;

    public UsersController(IUserService userService)
    {
        _userService = userService;
    }

    [AllowAnonymous]
    [HttpPost("authenticate")]
    public async Task<IActionResult> Authenticate([FromBody]AuthenticateModel model)
    {
        var user = await _userService.Authenticate(model.Username, model.Password);

        if (user == null)
            return BadRequest(new { message = "Username or password is incorrect" });

        return Ok(user);
    }

    [HttpGet]
    public async Task<IActionResult> GetAll()
    {
        var users = await _userService.GetAll();
        return Ok(users);
    }
}



dotnet-6-basic-authentication-api/Controllers/CustomersController.cs

namespace WebApi.Controllers;

using Microsoft.AspNetCore.Mvc;
using WebApi.Authorization;
using WebApi.Models;
using WebApi.Services;

[ApiController]
[Route("[controller]")]
public class CustomersController : ControllerBase
{
    private IUserService _userService;

    public CustomersController(IUserService userService)
    {
        _userService = userService;
    }


    [HttpGet]
    public IActionResult Get()
    {
        return Ok("this is customer controller");
    }
}

dotnet-6-basic-authentication-api/Authorization/AllowAnonymousAttribute.cs

namespace WebApi.Authorization;

[AttributeUsage(AttributeTargets.Method)]
public class AllowAnonymousAttribute : Attribute
{ 

}

dotnet-6-basic-authentication-api/Authorization/AuthorizeAttribute.cs

namespace WebApi.Authorization;

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using WebApi.Entities;

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AuthorizeAttribute : Attribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        // skip authorization if action is decorated with [AllowAnonymous] attribute
        var allowAnonymous = context.ActionDescriptor.EndpointMetadata.OfType<AllowAnonymousAttribute>().Any();
        if (allowAnonymous)
            return;

        var user = (User)context.HttpContext.Items["User"];
        if (user == null)
        {
            // not logged in - return 401 unauthorized
            context.Result = new JsonResult(new { message = "Unauthorized" }) { StatusCode = StatusCodes.Status401Unauthorized };

            // set 'WWW-Authenticate' header to trigger login popup in browsers
            context.HttpContext.Response.Headers["WWW-Authenticate"] = "Basic realm=\"\", charset=\"UTF-8\"";
        }
    }
}

dotnet-6-basic-authentication-api/Authorization/BasicAuthMiddleware.cs

namespace WebApi.Authorization;

using System.Net.Http.Headers;
using System.Text;
using WebApi.Services;

public class BasicAuthMiddleware  
{
    private readonly RequestDelegate _next;

    public BasicAuthMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context, IUserService userService)
    {
        try
        {
            var authHeader = AuthenticationHeaderValue.Parse(context.Request.Headers["Authorization"]);
            var credentialBytes = Convert.FromBase64String(authHeader.Parameter);
            var credentials = Encoding.UTF8.GetString(credentialBytes).Split(':', 2);
            var username = credentials[0];
            var password = credentials[1];

            // authenticate credentials with user service and attach user to http context
            context.Items["User"] = await userService.Authenticate(username, password);
        }
        catch
        {
            // do nothing if invalid auth header
            // user is not attached to context so request won't have access to secure routes
        }

        await _next(context);
    }
}

dotnet-6-basic-authentication-api/Models/AuthenticateModel.cs

namespace WebApi.Models;

using System.ComponentModel.DataAnnotations;

public class AuthenticateModel
{
    [Required]
    public string Username { get; set; }

    [Required]
    public string Password { get; set; }
}

dotnet-6-basic-authentication-api/Middlewares/LoggingMiddleware.cs

public class LoggingMiddleware  
{
    private readonly RequestDelegate _next;

    public LoggingMiddleware(RequestDelegate next)
    {
        _next = next;
    }


    public async Task Invoke(HttpContext context)
    {
        Console.WriteLine($"Request path: {context.Request.Path}");
        Console.WriteLine($"Request time: {DateTime.Now}");

        await _next(context);
    }
}

dotnet-6-basic-authentication-api/Program.cs

using WebApi.Authorization;
using WebApi.Services;

var builder = WebApplication.CreateBuilder(args);

// add services to DI container
{
    var services = builder.Services;
    services.AddCors();
    services.AddControllers();
    // configure DI for application services
    services.AddScoped<IUserService, UserService>();
}


var app = builder.Build();


// configure HTTP request pipeline
{
    // global cors policy
    app.UseCors(x => x
        .AllowAnyOrigin()
        .AllowAnyMethod()
        .AllowAnyHeader());
    // custom basic auth middleware
    app
    .UseMiddleware<BasicAuthMiddleware>()
    .UseMiddleware<LoggingMiddleware>();

    app.MapControllers();
}

app.Run("http://localhost:4000");


dotnet-6-basic-authentication-api/global.json

{
  "sdk": {
    "version": "6.0.412"
  }
}

dotnet-6-basic-authentication-api/.gitignore

# Logs
logs
*.log
npm-debug.log*

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules
jspm_packages
typings

# Optional npm cache directory
.npm

# Optional REPL history
.node_repl_history

# .NET compiled files
bin
obj

dotnet-6-basic-authentication-api/dotnet-6-basic-authentication-api.sln


Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.002.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebApi", "WebApi.csproj", "{79F25DFB-5FDB-4E70-9946-E4A1D4CF290A}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
		Release|Any CPU = Release|Any CPU
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{79F25DFB-5FDB-4E70-9946-E4A1D4CF290A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{79F25DFB-5FDB-4E70-9946-E4A1D4CF290A}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{79F25DFB-5FDB-4E70-9946-E4A1D4CF290A}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{79F25DFB-5FDB-4E70-9946-E4A1D4CF290A}.Release|Any CPU.Build.0 = Release|Any CPU
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
	GlobalSection(ExtensibilityGlobals) = postSolution
		SolutionGuid = {517F54C7-E702-4E85-B0E6-FD87AE3FAA41}
	EndGlobalSection
EndGlobal

dotnet-6-basic-authentication-api/appsettings.json

{
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft.AspNetCore": "Warning"
        }
    }
}

dotnet-6-basic-authentication-api/WebApi.csproj

<Project Sdk="Microsoft.NET.Sdk.Web">
    <PropertyGroup>
        <TargetFramework>net6.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
    </PropertyGroup>
</Project>

dotnet-6-basic-authentication-api/omnisharp.json

{
    "msbuild": {
        "useBundledOnly": true
    }
}

标签:WebApi,asp,middleware,api,basic,dotnet,using,net,public
From: https://www.cnblogs.com/zhuoss/p/18162545

相关文章

  • 论文解读(MAML)《Model-Agnostic Meta-Learning for Fast Adaptation of Deep Networks
    Note:[wechat:Y466551|可加勿骚扰,付费咨询]论文信息论文标题:Model-AgnosticMeta-LearningforFastAdaptationofDeepNetworks论文作者:ChelseaFinn、PieterAbbeel、SergeyLevine论文来源:2017 论文地址:download 论文代码:download视屏讲解:click1-摘要我们提出......
  • middleware的注册和使用 asp.net
    middleware的编写和注册编写中间件类(middleware-class)通常,中间件封装在类中,并且通过扩展方法公开。具有类型为RequestDelegate的参数的公共构造函数。publicLoggingMiddleware(RequestDelegatenext){_next=next;}名为Invoke或InvokeAsync的公共方法......
  • centos7出现网络不可达connect network is unreachable?
    centos7出现网络不可达connect:networkisunreachable?问题:在Linux系统中,用户尝试修改IP地址配置后,遇到ping命令提示connect:networkisunreachable,表明网络不可达。原因分析:IP配置错误:修改后的IP地址可能不在正确的子网内,或者与默认网关不在同一网段,导致无法正常通信......
  • RadiationNet——辐射网的典型用户(项目风险分析在上一篇)
    本次的典型用户有四人,分别代表了四种类型的受众——关注人体健康的人群(壮壮妈)、因为各种因素想要了解各地核辐射数据的人群(高启强)、从事环保相关工作的人群(高启盛)、关注核污染问题的人群(牛爷爷)。 表1姓名壮壮妈性别年龄女48职业家庭主妇收......
  • .NET项目中NLog的配置与使用
    因为之前在项目开发中一直都是使用的Log4Net作为项目的日志记录框架,最近忽然感觉对它已经有点腻了,所以尝试着使用了NLog作为新项目的日志记录框架(当然作为一名有志向的攻城狮永远都不能只局限于眼前的技术,要不断的使用和学习新的技术)。当然serilog也是一个不错的日志记录框......
  • gnet--高性能的网络库
    官网地址https://github.com/panjf2000/gnet这里要吐槽一下,官网没有任何使用文档,也没有example,源码test都么有。。。。客户端packagemainimport( "encoding/binary" "io" "log" "net")//封包函数funcpackageData(data[]byte)([]byte,error){ length......
  • Modbus转Profinet网关连接LED大屏与PLC通讯
     Modbus转Profinet网关(XD-MDPN100)的主要功能是实现Modbus协议和Profinet协议之间的转换和通信。Modbus转Profinet网关集成了Modbus和Profinet两种协议,支持ModbusRTU主站/从站,并可以与RS485接口的设备,如变频器、智能高低压电器、电量测量装置等进行连接。通过Modbus转Profinet网......
  • kubernetes安装配置使用vGPU
    前言AI落地时,在某些场景下AI模型在训练或者是推理时,其算力要求不需要占用整卡的GPU,比如只需要0.5卡GPU即可满足需求。在这种情况下,可以使用GPU虚拟化技术来解决这个问题,将整卡的GPU虚拟化为两个0.5卡的GPU,这样就可以在一张卡上同时跑两个AI训练或者AI推理应用服......
  • dotnet 8 版本与银河麒麟V10和UOS系统的 glib 兼容性
    刚刚好dotnet8的glib版本足够旧,可以运行本文记录于2024.04.26如果你阅读本文时间距离本文记录时间过远,可能本文记录的信息已失效dotnet根据dotnet的supported-os文档记录,当前的dotnet8是8.0.4版本,官方说明是支持Debian11及以上版本实际测试可以在debian1......
  • dotnet C# 简单的追加文件夹到 ZipArchive 压缩文件的方法
    本文将告诉大家一个在ZipArchive里追加文件夹,以及添加过滤文件处理的压缩文件辅助方法实现的方法的代码如下///<summary>///追加文件夹到压缩文件里面///</summary>///<paramname="archive"></param>///<paramname="sourceDirectoryName"></p......