【问题标题】:Blazor Server MSAL View & Controller Role Based AuthorizationBlazor 服务器 MSAL 视图和控制器基于角色的授权
【发布时间】:2022-08-18 23:46:37
【问题描述】:

我有一个 Blazor 服务器 Web 应用程序,它通过 OIDC 使用 Azure AD 来授权 Razor 组件内的访问。这工作正常,登录后我可以在整个 Razor 组件中访问 User ClaimsPrincipal。问题是,应用程序的所有业务逻辑都位于通过 HTTP 从 Razor 组件调用的控制器中(在同一个项目中)。我无法弄清楚如何获取用户声称的 JWT 标记化版本以传入 Authorization 标头以调用我的控制器。

这是我的一些代码。

DevicesController.cs:

    [Route(\"api/[controller]\")]
    [ApiController]
    [Authorize(Roles = \"Administrator\", \"User\")]
    public class DevicesController : ControllerBase
    {
        private readonly ILogger<DevicesController> _logger;
        private readonly AppSettings _config;
        private readonly IDeviceEnvironmentService _deviceEnvironmentService;

        public DevicesController(ILogger<DevicesController> logger, IOptions<AppSettings> config, IDeviceEnvironmentService deviceEnvironmentService,)
        {
            _logger = logger;
            _config = config.Value;
            _deviceEnvironmentService = deviceEnvironmentService;
        }

        [HttpGet]
        public async Task<ActionResult<object>> Index()
        {
            try
            {
                return await _deviceEnvironmentService.GetEnvironmentDevices(_config.Environment);
            }
            catch(Exception ex)
            {
                _logger.LogError(ex, $\"Failed to fetch devices. Exception details: {ex}\");
                return StatusCode(500, \"Failed to fetch devices.\");
            }
        }
}

DeviceIndex.razor:


@code {
    [CascadingParameter] Task<AuthenticationState> AuthenticationStateTask { get; set; }

    private ClaimsPrincipal User { get; set; }
    private List<DeviceEnvironment> devices { get; set; }
    private HubConnection hubConnection;  

    protected override async Task OnInitializedAsync()
    {
        var authState = await AuthenticationStateTask;
        User = authState.User;

        hubConnection = new HubConnectionBuilder()
        .WithUrl(NavigationManager.ToAbsoluteUri(\"/DeviceHub\"))
        .Build();

        hubConnection.On(\"ReceiveMessage\", () =>
        {
            LoadData();
            StateHasChanged();
        });

        await hubConnection.StartAsync();
        LoadData();
    }

    public bool IsConnected => hubConnection.State == HubConnectionState.Connected;

    protected async void LoadData()
    {
        devices = await Http.GetFromJsonAsync<List<DeviceEnvironment>>($\"{NavigationManager.BaseUri}api/devices\");
        StateHasChanged();
    }
}

Program.cs:

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(builder.Configuration);
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration);

builder.Services.AddControllersWithViews(options =>
    {
        var policy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .Build();
        options.Filters.Add(new AuthorizeFilter(policy));
    })
    .AddMicrosoftIdentityUI();

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

builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor()
    .AddMicrosoftIdentityConsentHandler();

var app = builder.Build();

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


app.Run();

有没有办法在我的 Razor 组件中获取 JWT 令牌,我可以通过 Authorization 标头将其传递给我的控制器?或者有没有一种方法可以通过 HttpContext 访问用户声明而不将令牌传递给控制器​​?

    标签: c# asp.net-mvc azure-active-directory openid-connect blazor-server-side


    【解决方案1】:

    因为您已经有了获取用户声明的方法

    private ClaimsPrincipal User { get; set; }
    

    请检查以下是否是您可能希望从获得的声明主体获取访问令牌的方式

    var token = (User as ClaimsPrincipal).FindFirst("access_token").Value
    

    您可以从 Header 中获取授权令牌,如下所示,仅当客户端在请求中发送 header 时才有效。

    HttpContext.Request.Headers["Authorization"]
    

    参考:

    1. 也请查看Implement app roles authorization with Azure AD and ASP.NET Core | Software Engineering (damienbod.com)
    2. c# - How to get JWTToken from ASPNET Core Controller? - Stack Overflow

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-24
      • 2020-06-22
      • 1970-01-01
      • 1970-01-01
      • 2017-11-24
      • 1970-01-01
      相关资源
      最近更新 更多