I have the following code which using a policy requirement to see if a user has access to a specific matchKey. Here is my controller action
[HttpGet]
[Authorize(Policy = Policy.Match)]
public async Task<IActionResult> Index(Guid matchKey)
{
var model = await _mediator.Send(new MatchIndexQuery
{
MatchKey = matchKey
});
return View("Index", model);
}
I get the matchKey from the request.query and everything works as intended.
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MatchRequirement requirement)
{
if (context.Resource is HttpContext httpContext)
{
var query = httpContext.Request.Query;
if (query.TryGetValue("matchKey", out StringValues matchKeyString))
{
if (Guid.TryParse(matchKeyString.ToString(), out Guid matchKey))
{
// Do some checks here and return
context.Succeed(requirement);
}
}
}
}
This all works, now I'd like to make my URL a bit nicer so I can just have /Match/{matchKey} instead of /Match?matchKey={matchKey} so I have the following route.
[HttpGet]
[Authorize(Policy = Policy.Match)]
[Route("[controller]/{matchKey?}")]
[Route("[controller]/[action]/{matchKey?}")]
public async Task<IActionResult> Index(Guid matchKey)
{
var model = await _mediator.Send(new MatchIndexQuery
{
MatchKey = matchKey
});
return View("Index", model);
}
However now my policy doesn't work because the {matchKey} isn't seen in the Request.Query anymore but as part of the Request.Path.
Is there any unified way to get the {matchKey} in my policy or do I need to some some string splitting based on the Request.Path if I can't find it in the query?
CodePudding user response:
or do I need to some some string splitting based on the Request.Path if I can't find it in the query?
Yes,you can split httpContext.Request.Path
and get the value of matchKey
.
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MatchRequirement requirement)
{
if (context.Resource is HttpContext httpContext)
{
var path = httpContext.Request.Path.ToString().Split("/");
//if Path contains matchKey,httpContext.Request.Path.ToString() will be /controllername/actionname/matchkeyvalue,and the length of path will be 4
if (path.Length==4)
{
var matchKeyString=path[path.Length - 1];
if (Guid.TryParse(matchKeyString.ToString(), out Guid matchKey))
{
// Do some checks here and return
context.Succeed(requirement);
}
}
}
}