我的控制器操作如下:
[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
}
}
我想知道是否有一个技巧可以像操作参数中那样直接使用承载/访问令牌,例如:
[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
}
}
答案 0 :(得分:2)
添加自定义属性,值提供者:
[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
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
}
}
答案 1 :(得分:1)
尝试像这样[FromHeader]绑定源参数:[FromHeader] string authorization