亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

.Net?Core中如何寫自定義認證實現

發布時間:2022-01-24 11:14:05 來源:億速云 閱讀:224 作者:柒染 欄目:開發技術

今天就跟大家聊聊有關.Net Core中如何寫自定義認證實現,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

一、起因

 最近項目中需要對項目同時支持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
}

  調用

.Net?Core中如何寫自定義認證實現

三、多認證支持

 在實際項目中可能存在,對一個控制器支持多種認證方式如:常用的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 應用自定義實現的認證處理器。

看完上述內容,你們對.Net Core中如何寫自定義認證實現有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

阿荣旗| 富源县| 正安县| 定结县| 玛多县| 堆龙德庆县| 清镇市| 宝丰县| 体育| 双柏县| 偃师市| 望江县| 抚顺县| 静海县| 普定县| 普兰店市| 临海市| 资阳市| 沾化县| 台北市| 迁安市| 张家港市| 封丘县| 璧山县| 连南| 宁国市| 罗定市| 专栏| 称多县| 珠海市| 汤阴县| 新邵县| 静海县| 哈巴河县| 陆良县| 岳阳县| 沧州市| 嘉峪关市| 峡江县| 弥渡县| 呼伦贝尔市|