有没有一种方法可以将请求标头指定为ASP.NET Core Controller操作参数/参数? [英] Is there a way to a specify a request header as an ASP.NET Core Controller action argument / parameter?

查看:208
本文介绍了有没有一种方法可以将请求标头指定为ASP.NET Core Controller操作参数/参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有如下控制器操作:

[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}")]
public class StuffController : ControllerBase
{
    [HttpGet("stuff/")]
    [Authorize(Roles = "admin,read-stuff")]
    [Produces("application/json")]
    [ProducesResponseType(typeof(IActionResult), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(StatusCodes.Status403Forbidden)]
    public async Task<IActionResult> Get()
    {
        var authorization = Request.Headers["authorization"];
        var accessToken = authorization[0].Replace("Bearer ", string.Empty);

        // use accessToken for token exchange
        // use the new token another to get and return the actual results
    }
}

我想知道是否有一个技巧可以像操作参数中那样直接使用承载/访问令牌,例如:

I was wondering is there was a trick to have the bearer / access token directly available as in the action parameter, something like:

[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}")]
public class StuffController : ControllerBase
{
    [HttpGet("stuff/")]
    [Authorize(Roles = "admin,read-stuff")]
    [Produces("application/json")]
    [ProducesResponseType(typeof(IActionResult), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(StatusCodes.Status403Forbidden)]
    public async Task<IActionResult> Get([BearerTokenHeader] string bearerTokenHeader)
    {
        // use accessToken for token exchange
        // use the new token another to get and return the actual results
    }
}


推荐答案

添加自定义属性,值提供者:

Add custom attribute, value provider:

[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class BearerTokenFromHeaderAttribute : Attribute, IBindingSourceMetadata, IModelNameProvider
{
    public BindingSource BindingSource => BearerTokenBindingSource.Instance;

    public string Name { get; set; }
}

public static class BearerTokenBindingSource
{
    public static readonly BindingSource Instance = new BindingSource(
        "BearerToken",
        "BearerToken",
        isGreedy: false,
        isFromRequest: true);
}

public class BearerTokenValueProviderFactory : IValueProviderFactory
{
    public Task CreateValueProviderAsync(ValueProviderFactoryContext context)
    {
        var authorizationHeader = context.ActionContext.HttpContext.Request.Headers["Authorization"];
        var accessToken = authorizationHeader[0].Replace("Bearer ", string.Empty);

        context.ValueProviders.Add(new BearerTokenValueProvider(BearerTokenBindingSource.Instance, accessToken));

        return Task.CompletedTask;
    }
}

public class BearerTokenValueProvider : BindingSourceValueProvider
{
    public BearerTokenValueProvider(BindingSource bindingSource, string accessToken) : base(bindingSource)
    {
        AccessToken = accessToken;
    }

    private string AccessToken { get; }

    public override bool ContainsPrefix(string prefix)
    {
        return false;
    }

    public override ValueProviderResult GetValue(string key)
    {
        return new ValueProviderResult(AccessToken);
    }
}

Startup.cs

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddMvc(options =>
    {
        options.ValueProviderFactories.Add(new BearerTokenValueProviderFactory());
    });
}

控制器

[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}")]
public class StuffController : ControllerBase
{
    [HttpGet("stuff/")]
    [Authorize(Roles = "admin,read-stuff")]
    [Produces("application/json")]
    [ProducesResponseType(typeof(IActionResult), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(StatusCodes.Status403Forbidden)]
    public async Task<IActionResult> Get([BearerTokenFromHeader] string accessToken)
    {
        // use accessToken for token exchange
        // use the new token another to get and return the actual results
    }
}

这篇关于有没有一种方法可以将请求标头指定为ASP.NET Core Controller操作参数/参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆