c# - 使用 AzureAd 为 blazor 服务器端添加自定义角色

标签 c# azure asp.net-core blazor blazor-server-side

我有一个中间件,可以在使用 AzureAd 登录后向用户添加自定义角色,它工作正常,但我有一个问题,例如,在我登录后,有人也在我之后登录,该用户仍然具有我为我添加的相同角色。我的问题:为什么 blazor 通过这种方式即使在注销后也会为不同的用户保存此角色?我想了解背后的机制
这是中间件

public class RoleHandler
{
    private readonly RequestDelegate _next;
    private List<string> Roles { get; set; }

    public RoleHandler(RequestDelegate Next)
    {
        _next = Next;
    }

    public async Task InvokeAsync(HttpContext context, IGenericHttpClient<Role> httpClient)
    {
        if (Roles == null || Roles.Count == 0)
        {
            Roles = await GetRole(context, httpClient);
        }
        else
        {
            foreach (var role in Roles)
            {
                //Add roles to this user, in this case user can be admin or developer ...
                context.User.Identities.FirstOrDefault().AddClaim(new Claim(ClaimTypes.Role, role));
            }
        }
        await _next(context);
    }

    public async Task<List<string>> GetRole(HttpContext context, IGenericHttpClient<Role> httpClient)
    {
        List<string> rolesList = new();
        //Get role from api like [guid, admin]
        var appUserRoles = await httpClient.GetJsonAsync("/api/roles/search?id=XXX");
        //Get role from user as guid
        var RolesString = context.User.Claims
                .Select(c => c.Value).ToList();

        foreach (var appRole in appUserRoles)
        {
            foreach (var role in RolesString)
            {
                if (appRole.RoleString == role)
                {
                    rolesList.Add(appRole.Name);
                }
            }
        }
        return rolesList;
    }
}

在启动中配置服务

        public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<ILoggerManager, LoggerManager>();

        var initialScopes = Configuration.GetValue<string>("DownstreamApi:Scopes")?.Split(' ');

        JwtSecurityTokenHandler.DefaultMapInboundClaims = false;

        services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
            .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))
                .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
                    .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi"))
                    .AddInMemoryTokenCaches();

        services.AddScoped(typeof(IGenericHttpClient<>), typeof(GenericHttpClient<>));

        services.AddControllersWithViews()
            .AddMicrosoftIdentityUI();

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

        services.AddLocalization(options => options.ResourcesPath = "Resources");
        services.AddRazorPages();
        services.AddServerSideBlazor()
            .AddMicrosoftIdentityConsentHandler();
    }

GenericHttpClient

public class GenericHttpClient<T> : IGenericHttpClient<T> where T : class
{
    private readonly IHttpClientFactory _clientFactory;
    private HttpClient _client;
    private readonly IConfiguration _configuration;
    public GenericHttpClient(IHttpClientFactory clientFactory,
        IConfiguration configuration)
    {
        _clientFactory = clientFactory;
        _configuration = configuration;

        _client = _clientFactory.CreateClient();

        _client.BaseAddress = new Uri("https://localhost");
    }
    
    public async ValueTask<List<T>> GetJsonAsync(string url)
    {
        using HttpResponseMessage response = await _client.GetAsync(url);
        ValidateResponse(response);
        var content = await ValidateContent(response).ReadAsStringAsync();
        return JsonSerializer.Deserialize<List<T>>(content, new JsonSerializerOptions() { PropertyNameCaseInsensitive=true});
    }
    // ......
}

}

最佳答案

关于c# - 使用 AzureAd 为 blazor 服务器端添加自定义角色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70336880/

相关文章:

C# 小型数据库项目与 sql server ce

c# - RX : How to concat a Snapshot stream and an Update stream?

php - 如何从codeigniter项目中的url中删除index.php

azure - 如何在 Azure B2C 用户流中编辑回复 URL

javascript - 如何从 Angular ngFor 中的方法中提取值

c# - C# 中的泛型类型转换

c# - "Enum as immutable rich-object": is this an anti-pattern?

Azure 存储 - 在 <img> 标记中使用私有(private)容器中的 Blob

c# - 使用MediatR时,Dapper的DataException消失了

asp.net-core - 在.NET Core 2.1.0-rc1-final中使用System.Net.Http.SocketsHttpHandler