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 |
| { |
| |
| 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) |
| { |
| |
| var user = await Task.Run(() => _users.SingleOrDefault(x => x.Username == username && x.Password == password)); |
| |
| |
| |
| return user; |
| } |
| |
| public async Task<IEnumerable<User>> GetAll() |
| { |
| |
| 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) |
| { |
| |
| var allowAnonymous = context.ActionDescriptor.EndpointMetadata.OfType<AllowAnonymousAttribute>().Any(); |
| if (allowAnonymous) |
| return; |
| |
| var user = (User)context.HttpContext.Items["User"]; |
| if (user == null) |
| { |
| |
| context.Result = new JsonResult(new { message = "Unauthorized" }) { StatusCode = StatusCodes.Status401Unauthorized }; |
| |
| |
| 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]; |
| |
| |
| context.Items["User"] = await userService.Authenticate(username, password); |
| } |
| catch |
| { |
| |
| |
| } |
| |
| 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); |
| |
| |
| { |
| var services = builder.Services; |
| services.AddCors(); |
| services.AddControllers(); |
| |
| services.AddScoped<IUserService, UserService>(); |
| } |
| |
| |
| var app = builder.Build(); |
| |
| |
| |
| { |
| |
| app.UseCors(x => x |
| .AllowAnyOrigin() |
| .AllowAnyMethod() |
| .AllowAnyHeader()); |
| |
| 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 |
| } |
| } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战