返回顶部
首页 > 资讯 > 后端开发 > ASP.NET >.NetCore中自定义认证实现
  • 151
分享到

.NetCore中自定义认证实现

2024-04-02 19:04:59 151人浏览 泡泡鱼
摘要

目录一、起因二、自定义认证实现 三、多认证支持四、总结一、起因  最近项目中需要对项目同时支持Jwt认证,以及自定义的认证校验方式认证。通过对官方文档了解,得到认证实现主要

一、起因

 最近项目中需要对项目同时支持Jwt认证,以及自定义的认证校验方式认证。通过对官方文档了解,得到认证实现主要通过继承 IAuthenticationHandler 或 AuthenticationHandler<TOptions>来实现自定义认证的处理。 

 那么接下来实现一个自定义的认证访问。

二、自定义认证实现 

 1、根据前面内容得知,处理认证通过IAuthenticationHandler 实例处理;那么首先添加一个自定义IAuthenticationHandler 类型:

/// <summary>
/// 方式一:自定义认证处理器
/// </summary>
public class CustomerAuthenticationHandler : IAuthenticationHandler
{
    private IUserService _userService;
    public CustomerAuthenticationHandler(IUserService userService)
    {
        _userService = userService;
    }

    /// <summary>
    /// 自定义认证Scheme名称
    /// </summary>
    public const string CustomerSchemeName = "cusAuth";

    private AuthenticationScheme _scheme;
    private HttpContext _context;

    /// <summary>
    /// 认证逻辑:认证校验主要逻辑
    /// </summary>
    /// <returns></returns>
    public Task<AuthenticateResult> AuthenticateAsync()
    {
        AuthenticateResult result;
        _context.Request.Headers.TryGetValue("Authorization", out StringValues values);
        string valStr = values.ToString();
        if (!string.IsNullOrWhiteSpace(valStr))
        {
            //认证模拟basic认证:cusAuth YWRtaW46YWRtaW4=
            string[] authVal = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(valStr.Substring(CustomerSchemeName.Length + 1))).Split(':');
            var loginInfo = new Dto.LoginDto() { Username = authVal[0], PassWord = authVal[1] };
            var validVale = _userService.IsValid(loginInfo);
            if (!validVale)
                result = AuthenticateResult.Fail("未登陆");
            else
            {
                var ticket = GetAuthTicket(loginInfo.Username, "admin");
                result = AuthenticateResult.Success(ticket);
            }
        }
        else
        {
            result = AuthenticateResult.Fail("未登陆");
        }
        return Task.FromResult(result);
    }

    /// <summary>
    /// 未登录时的处理
    /// </summary>
    /// <param name="properties"></param>
    /// <returns></returns>
    public Task ChallengeAsync(AuthenticationProperties properties)
    {
        _context.Response.StatusCode = (int)httpstatusCode.Unauthorized;
        return Task.CompletedTask;
    }

    /// <summary>
    /// 权限不足时处理
    /// </summary>
    /// <param name="properties"></param>
    /// <returns></returns>
    public Task ForbidAsync(AuthenticationProperties properties)
    {
        _context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
        return Task.CompletedTask;
    }

    /// <summary>
    /// 初始化认证
    /// </summary>
    /// <param name="scheme"></param>
    /// <param name="context"></param>
    /// <returns></returns>
    public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
    {
        _scheme = scheme;
        _context = context;
        return Task.CompletedTask;
    }

    #region 认证校验逻辑

    /// <summary>
    /// 生成认证票据
    /// </summary>
    /// <param name="name"></param>
    /// <param name="role"></param>
    /// <returns></returns>
    private AuthenticationTicket GetAuthTicket(string name, string role)
    {
        var claimsIdentity = new ClaimsIdentity(new Claim[]
        {
    new Claim(ClaimTypes.Name, name),
    new Claim(ClaimTypes.Role, role),
        }, CustomerSchemeName);
        var principal = new ClaimsPrincipal(claimsIdentity);
        return new AuthenticationTicket(principal, _scheme.Name);
    }

    #endregion
}

/// <summary>
/// 方式二:继承已实现的基类
/// </summary>
public class SubAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
    public SubAuthenticationHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
        : base(options, logger, encoder, clock)
    {
    }

    protected override Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        throw new NotImplementedException();
    }
}

 2、在Startup.cs中启用自定义认证:

public void ConfigureServices(IServiceCollection services)
{
    //other code
    services.AddAuthentication(o =>
    {
        x.DefaultAuthenticateScheme = CustomerAuthenticationHandler.CustomerSchemeName;
        x.DefaultChallengeScheme = CustomerAuthenticationHandler.CustomerSchemeName;
        o.AddScheme<CustomerAuthenticationHandler>(CustomerAuthenticationHandler.CustomerSchemeName, CustomerAuthenticationHandler.CustomerSchemeName);
    });
    //other code
}

public void Configure(IApplicationBuilder app)
{
    //other code
    app.UseRouting();

    //在UseRouting后;UseEndpoints前添加以下代码
    app.UseAuthentication();
    app.UseAuthorization();

    //other code
    app.UseEndpoints()
}

 3、在控制器上添加认证标记,测试验证

//指定认证时,采用CustomerAuthenticationHandler.CustomerSchemeName
[Authorize(AuthenticationSchemes = CustomerAuthenticationHandler.CustomerSchemeName)]
[Route("api/[controller]")]
[ApiController]
public class AuditLoGController : ControllerBase
{
 //code
}

  调用

三、多认证支持

 在实际项目中可能存在,对一个控制器支持多种认证方式如:常用的Jwt认证、自定义认证等,那么如何实现呢?

 1、在Startup的ConfigureServices 方法中添加以下逻辑:

public void ConfigureServices(IServiceCollection services)
{
    //other code
    services.Configure<JwtSetting>(Configuration.GetSection("JWTSetting"));
    var token = Configuration.GetSection("JWTSetting").Get<JwtSetting>();
    //JWT认证
    services.AddAuthentication(x =>
    {
        x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
     //添加自定义认证处理器
        x.AddScheme<CustomerAuthenticationHandler>(CustomerAuthenticationHandler.CustomerSchemeName, CustomerAuthenticationHandler.CustomerSchemeName);
    }).AddJwtBearer(x =>
    {
        x.RequireHttpsMetadata = false;
        x.SaveToken = true;
        x.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(token.SecreTKEy)),
            ValidIssuer = token.Issuer,
            ValidAudience = token.Audience,
            ValidateIssuer = false,
            ValidateAudience = false
        };
    });
    //other code
}

 2、在需要支持多种认证方式的控制器上添加标记:

//指定认证时,采用CustomerAuthenticationHandler.CustomerSchemeName
[Authorize(AuthenticationSchemes = CustomerAuthenticationHandler.CustomerSchemeName)]
[Route("api/[controller]")]
[ApiController]
public class AuditLogController : ControllerBase
{
 //code
}

//指定认证采用JWT 
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] 
public class WeatherForecastController : ControllerBase 
{
  //code 
}

   这样就支持了两种认证方式

 3、一个控制器支持多种认证类型:继承Jwt认证处理,并根据Scheme那么调用自定义的认证处理器:

/// <summary>
/// 方式二:同时支持多种认证方式
/// </summary>
public class MultAuthenticationHandler : JwtBearerHandler
{
    public const string MultAuthName = "MultAuth";
    IUserService _userService;
    public MultAuthenticationHandler(IOptionsMonitor<JwtBearerOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IUserService userService)
        : base(options, logger, encoder, clock)
    {
        _userService = userService;
    }

    protected override Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        Context.Request.Headers.TryGetValue("Authorization", out StringValues values);
        string valStr = values.ToString();
        if (valStr.StartsWith(CustomerAuthenticationHandler.CustomerSchemeName))
        {
            var result = Valid();
            if (result != null)
                return Task.FromResult(AuthenticateResult.Success(result));
            else
                return Task.FromResult(AuthenticateResult.Fail("未认证"));
        }
        else
            return base.AuthenticateAsync();
    }

    private AuthenticationTicket Valid()
    {
        Context.Request.Headers.TryGetValue("Authorization", out StringValues values);
        string valStr = values.ToString();
        if (!string.IsNullOrWhiteSpace(valStr))
        {
            //认证模拟basic认证:cusAuth YWRtaW46YWRtaW4=
            string[] authVal = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(valStr.Substring(CustomerAuthenticationHandler.CustomerSchemeName.Length + 1))).Split(':');
            var loginInfo = new Dto.LoginDto() { Username = authVal[0], Password = authVal[1] };
            if (_userService.IsValid(loginInfo))
                return GetAuthTicket(loginInfo.Username, "admin");
        }
        return null;
    }

    /// <summary>
    /// 生成认证票据
    /// </summary>
    /// <param name="name"></param>
    /// <param name="role"></param>
    /// <returns></returns>
    private AuthenticationTicket GetAuthTicket(string name, string role)
    {
        var claimsIdentity = new ClaimsIdentity(new Claim[]
        {
            new Claim(ClaimTypes.Name, name),
            new Claim(ClaimTypes.Role, role),
        }, CustomerAuthenticationHandler.CustomerSchemeName);
        var principal = new ClaimsPrincipal(claimsIdentity);
        return new AuthenticationTicket(principal, CustomerAuthenticationHandler.CustomerSchemeName);
    }
}

四、总结

  .net core中的自定义认证主要通过实现IAuthenticationHandler 接口实现,如果要实现多认证方式通过AddScheme 应用自定义实现的认证处理器。

 源码GitHub

到此这篇关于.Net Core中自定义认证实现的文章就介绍到这了,更多相关.net Core 自定义认证内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: .NetCore中自定义认证实现

本文链接: https://lsjlt.com/news/163504.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • .NetCore中自定义认证实现
    目录一、起因二、自定义认证实现 三、多认证支持四、总结一、起因  最近项目中需要对项目同时支持JWT认证,以及自定义的认证校验方式认证。通过对官方文档了解,得到认证实现主要...
    99+
    2024-04-02
  • .NetCore实现JWT授权认证
    关于JWT的基本概念,如果有不清晰的同学,请点击这里,就不在这里赘述了。接下来聊聊JWT是怎么发挥作用的。 第一,安装nuget包 Microsoft.AspNetCore.Auth...
    99+
    2024-04-02
  • .Net Core中如何写自定义认证实现
    今天就跟大家聊聊有关.Net Core中如何写自定义认证实现,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、起因 最近项目中需要对项目同时支持JWT认证,以及自定义的认证...
    99+
    2023-06-28
  • SpringSecurity自定义认证器的实现代码
    目录AuthenticationAuthenticationProviderSecurityConfigurerAdapterUserDetailsServiceTokenFilte...
    99+
    2024-04-02
  • spring security 自定义Provider 如何实现多种认证
    目录security内部认证流程是这样的1、 Controller2、spring security3、调用匹配的provider内部认证逻辑4、UserDetailsService...
    99+
    2024-04-02
  • Asp.net Core中实现自定义身份认证的示例代码
    Asp.Net Core中虽然集成了许多常用的身份认证,但很多时候,我们还是需要实现自己的身份认证接口,本文这里就简单的介绍下如何实现自定义身份认证接口。 首先写一个简单的接口...
    99+
    2022-06-07
    自定义 ASP.NET net 示例 core ASP
  • .NETCore自定义配置文件
    前文讲获取配置文件内容的时候,是获取默认的appsettings.json配置文件的配置,下面说明下如何进行自定义配置文件获取 1. Json Provider 1.1 构建独立的I...
    99+
    2024-04-02
  • Spring Security自定义认证逻辑实例详解
    目录前言分析问题自定义 Authentication自定义 Filter自定义 Provider自定义认证成功/失败后的 Handler配置自定义认证的逻辑测试总结前言 这篇文章的内...
    99+
    2024-04-02
  • Django通过自定义认证后端实现多种登录方式验证
    目录前言实现自定义认证后端前言 我们见到几乎所有的 Web 网站或者手机 App 也好,它们的最终目的都是要留住用户,提升自己网站的用户注册量,所以说用户的概念也必须深入到每一个程序...
    99+
    2024-04-02
  • Android自定义View实现验证码
    本文章是基于鸿洋的Android 自定义View (一) 的一些扩展,以及对Android自定义View构造函数详解里面内容的一些转载。 首先我们定义一个declare-sty...
    99+
    2022-06-06
    view 验证码 Android
  • DreamWeaver CS3中如何实现SPRY的自定义验证
    这篇文章将为大家详细讲解有关DreamWeaver CS3中如何实现SPRY的自定义验证,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。代码如下:<span id="sprytextfiel...
    99+
    2023-06-08
  • Android自定义View实现随机验证码
    对于android开发来说自定义View还是一个比较重要的技能,所以在这里写一篇自定义View入门的文章,也是实现一个相对简单的随机产生验证码的功能: 自定义View主要也就...
    99+
    2022-06-06
    view 验证码 Android
  • vueelementUI实现自定义正则规则验证
    目录项目场景:验证是否是合法手机号(举例)实现步骤:总结:项目场景: 常见的表单填写中都会遇到,比如新增信息,修改信息等,如下图 相信大家对上面的验证都非常熟悉了,不多哔哔 本篇文...
    99+
    2024-04-02
  • jquery.validationEngine自定义验证使用怎么实现
    要实现自定义验证规则,可以按照以下步骤操作: 在 jQuery Validation Engine 的配置中,添加自定义验证规则...
    99+
    2023-10-25
    jquery
  • Spring Security基于自定义的认证提供器实现图形验证码流程解析
    目录前言一. 认证提供器简介1. 认证提供器AuthenticationProver2. WebAuthenticationDetails类介绍二. 实现图形验证码1. 添加依赖包2...
    99+
    2024-04-02
  • Spring Security OAuth2.0(五)-----OAuth2实现自定义统一认证登录页/自定义授权页/基于mysql存储数据
    本次实例涉及三个项目 核心项目工程unify_authorization_server(认证授权登录) 资源服务器项目unify_resource_server 测试项目是前面几篇写的项目 这里没有改...
    99+
    2023-09-11
    spring mysql java
  • Asp.Net Core如何添加请求头自定义认证
    小编给大家分享一下Asp.Net Core如何添加请求头自定义认证,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!要点实现 IAuthenticationHandler 接口:4 个方法首先会调用 InitializeAsy...
    99+
    2023-06-14
  • Android自定义View实现随机数验证码
    目录前言效果自定义 View 分类步骤1.自定义属性2.添加构造方法3.在构造里获取自定义样式4.重写 onDraw 计算坐标绘制5.重写 onMeasure 测量宽高6.设置点击事...
    99+
    2024-04-02
  • .NetCore日志记录之自定义日志组件
    一、前言 回顾:日志记录之日志核心要素揭秘 在上一篇中,我们通过学习了解在.net core 中内置的日志记录中的几大核心要素,在日志工厂记录器(ILoggerFactory)中实现...
    99+
    2024-04-02
  • Asp.Net Core添加请求头自定义认证的示例
    目录前言要点GuidToken 类就是我们自定义的 token 管理器最后就是使用方式前言 小项目中需要添加 Api 请求权限认证, 并且只是专用网络内使用,于是只想简单得认证下是...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作