簡體   English   中英

在 ASP.NET Core 3.1 中使用多個身份驗證方案?

[英]Using multiple authentication schemes in ASP.NET Core 3.1?

我一直在使用 ASP.NET Core 3.1 使用干凈的架構制作 web 應用程序。

我有一些 class 庫,例如 Infrastructure、Persistence、Domain、Application 和一個名為“Web”的 MVC 應用程序項目作為我的應用程序的啟動點。

在 Web 層中,我有一個“區域”,其中我有一個管理區域,其中包含一些控制器和操作方法,它們返回 JSON 作為我的 API 端點

我在 Controllers 文件夾中的 Web MVC 項目中也有一些控制器,它們的操作方法返回 html 視圖

我還將 Identity 和 JWT 用於我的 API 端點,但是:

- 如果我想在我的 MVC 控制器中使用基於聲明的身份,其操作結果返回 html 視圖,該怎么辦?

- 在此類應用程序中使用 ASP.NET Core 3.1 中基於聲明的身份的最佳實踐是什么?

任何幫助,將不勝感激。

經過一番研究,我在 ASP.NET 內核授權文檔中找到了解決方案,標題為“ 在 ASP.NET 內核中使用特定方案進行授權”。

根據 Microsoft ASP .NET 核心文檔中提到的文章,在某些情況下,例如單頁應用程序 (SPA),通常使用多種身份驗證方法。 例如,應用程序可以使用基於 cookie 的身份驗證登錄,並使用 JWT 不記名身份驗證 JavaScript 請求。

認證方案是在認證過程中配置認證服務時命名的。 例如:

public void ConfigureServices(IServiceCollection services)
{
    // Code omitted for brevity

    services.AddAuthentication()
        .AddCookie(options => {
            options.LoginPath = "/Account/Unauthorized/";
            options.AccessDeniedPath = "/Account/Forbidden/";
        })
        .AddJwtBearer(options => {
            options.Audience = "http://localhost:5001/";
            options.Authority = "http://localhost:5000/";
        });

在上述代碼中,添加了兩個身份驗證處理程序:一個用於 cookies,一個用於承載。

選擇具有 Authorize 屬性的方案

[Authorize(AuthenticationSchemes = 
    JwtBearerDefaults.AuthenticationScheme)]
public class MixedController : Controller

在前面的代碼中,只有帶有“Bearer”方案的處理程序運行。 任何基於 cookie 的身份都會被忽略。

這是解決我的問題的解決方案,我認為與需要它的人分享它會很好。

.Net Core 3.1 或 .Net 5.0 中的多種身份驗證方案

啟動.cs

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                    .AddCookie(x =>
                    {
                        x.LoginPath = "/";
                        x.ExpireTimeSpan = TimeSpan.FromMinutes(Configuration.GetValue<int>("CookieExpiry"));
                    })
                    .AddJwtBearer(x =>
                    {
                        x.RequireHttpsMetadata = false;
                        x.SaveToken = true;
                        x.TokenValidationParameters = new TokenValidationParameters
                        {
                            ValidateIssuerSigningKey = true,
                            IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration.GetValue<string>("JWTSecret"))),
                            ValidateIssuer = false,
                            ValidateAudience = false
                        };
                    });

            services.AddAuthorization(options =>
            {
                var defaultAuthorizationPolicyBuilder = new AuthorizationPolicyBuilder(CookieAuthenticationDefaults.AuthenticationScheme, JwtBearerDefaults.AuthenticationScheme);
                defaultAuthorizationPolicyBuilder = defaultAuthorizationPolicyBuilder.RequireAuthenticatedUser();
                options.DefaultPolicy = defaultAuthorizationPolicyBuilder.Build();
            });

/api/auth/登錄

public async Task<AuthenticationResult> Login([FromForm] string userName, [FromForm] string password, [FromHeader] string authmode = "")
{
    if (userName != "demo" || password != "demo")
        return new AuthenticationResult { HasError = true, Message = "Either the user name or password is incorrect." };

    var claims = new Claim[]
    {
        new Claim(ClaimTypes.Name, userName)
    };
    

    if(authmode?.ToLower() == "token")
    {
        var tokenHandler = new JwtSecurityTokenHandler();
        var key = Encoding.ASCII.GetBytes(_config.GetValue<string>("JWTSecret"));
        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(claims, "JWT"),
            Expires = DateTime.UtcNow.AddMinutes(_config.GetValue<int>("JWTExpiry")),
            SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
        };
        var token = tokenHandler.CreateToken(tokenDescriptor);
        var jwt = tokenHandler.WriteToken(token);
        return new AuthenticationResult { Token = jwt };
    }
    else
    {
        ClaimsPrincipal princ = new ClaimsPrincipal(new ClaimsIdentity(claims, "COOKIE"));
        await HttpContext.SignInAsync(princ);
        return new AuthenticationResult();
    }
}

Output:

在此處輸入圖像描述 在此處輸入圖像描述

在此處輸入圖像描述 在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM