簡體   English   中英

使用 windows 身份驗證保留自定義聲明 ASP.NET Core 6

[英]Persist custom claims with windows authentication ASP.NET Core 6

我使用 Visual Studio Code 使用do.net new mvc --auth windows創建了一個具有 windows 身份驗證的新 mvc 應用程序。

如果我使用 VS Code 和 Kestrel 啟動應用程序,一切都會按預期工作(我在頁面頂部看到我的域名)。 現在我想使用 IClaimsTransformation 添加自定義聲明。

我們有一個 REST API,它獲取用戶的域名和應用程序名稱,並返回當前用戶對該應用程序的角色。 收到回復后,我正在為當前身份添加新聲明。

但是,我不知道如何堅持這些自定義聲明。

這是我的代碼:

帶有啟動代碼的 Program.cs:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Negotiate;
using WindowsAuth.Utils;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
   .AddNegotiate();

builder.Services.AddAuthorization(options =>
{
    // By default, all incoming requests will be authorized according to the default policy.
    options.FallbackPolicy = options.DefaultPolicy;
});

builder.Services.AddTransient<IClaimsTransformation, CustomClaimsTransformer>();
builder.Services.AddRazorPages();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

CustomClaimsTransformer.cs:

using System.Security.Claims;
using Microsoft.AspNetCore.Authentication;

namespace WindowsAuth.Utils;

public class CustomClaimsTransformer : IClaimsTransformation
{
    public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
    {
        if (principal.Identity == null || string.IsNullOrEmpty(principal.Identity.Name))
            return principal;

        var userData = await GetUserDataFromRestAPI(principal.Identity.Name); //This is currently a dummy method, but will be called on every request
        if (userData == null || string.IsNullOrEmpty(userData.Role))
            return principal;

        var clone = principal.Clone();

        Claim[] claims = new Claim[]{
            new Claim(ClaimTypes.Name, principal.Identity.Name),
            new Claim("CustomProviderAccountId", userData.AccountId.ToString()),
            new Claim(ClaimTypes.Role, userData.Role)
        };
        ClaimsIdentity identity = new ClaimsIdentity(claims);
        clone.AddIdentity(identity); //Alternativly I cloud add the claims to the existing identity, but those won't persist either
        return clone;
    }

    private Task<AuthProviderResponse> GetUserDataFromRestAPI(string username)
    {
        return Task.FromResult(new AuthProviderResponse
        {
            AccountId = 42,
            Role = "Admin"
        });
    }
}

如前所述:這工作正常,因為我可以添加自定義聲明,並且它們正在傳遞給應用程序的 rest,但我不知道如何暫時保留這些聲明。 也許在 cookie 或緩存或 session 或其他什么。 這種情況的最佳做法是什么?

此應用程序中的所有其他內容都是 mvc 模板的默認設置。

最后我找到了一個解決方案,但我不確定這是否接近最佳實踐:

在 CustomClaimsTransformer 中,我在 cookie 中編寫聲明,並使用 IDataProtector 加密該 cookie。 因此,對於每個請求,我首先嘗試讀取 cookie 值,如果它不存在,我將調用 API。 完成調用后,我將加密的聲明保存在 cookie 中。

暫無
暫無

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

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