问题
I have a method on an API that can be accessed anonymously. I want to use resource authorization to determine if the user has access. If the object is "public" than it can be accessed by anyone (including anonymous users). If the object is "private" than it can only be viewed by logged in users. This logic works fine if I have an authorize attribute on the method, but if not the User has no claims even when they are logged in.
Is there a way to get the user's claims in a method without an Authorize attribute?
Method looks like this:
[HttpGet]
[Route("name/{name}")]
public async Task<IActionResult> Get(string name)
{
var activity = Repo.GetCommandLineActivity(name);
if (activity == null)
{
return NotFound();
}
var isAuthed = await _authService.AuthorizeAsync(User, activity, new ViewIPublicPrivateRequirement());
if (isAuthed.Succeeded)
{
return Ok(activity);
}
return Unauthorized();
}
回答1:
The solution was actually very simple, adding [AllowAnonymous]
and [Authorize]
did the trick.
回答2:
It is possible to retrieve the ClaimsPrincipal
even without the [Authorize]
attribute, but it truly feels like a hack, and I wouldn't recommend it. If I were you, I'd create two different endpoints, one for public access, and the other for authenticated users.
That being said, the way to retrieve the ClaimsPrincipal
is to call the AuthenticateAsync
method. Note that this code is for ASP.NET Core 2.0, it would be slightly different for 1.1.
Here's the modified method:
[HttpGet("name/{name}")]
[AllowAnonymous]
public async Task<IActionResult> Get(string name)
{
var activity = Repo.GetCommandLineActivity(name);
if (activity == null)
{
return NotFound();
}
// based on the way your authentication is configured in services.AddAuthentication(),
// this can be omitted (in which case, the default authenticate scheme will be used)
var authenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme;
var auth = await HttpContext.AuthenticateAsync(authenticationScheme);
if (auth.Succeeded)
{
// CAUTION: HttpContext.User will STILL be null
var user = auth.Principal;
return Ok(activity);
}
return Unauthorized();
}
Caution: HttpContext.User
will NOT be set if the [Authorize]
attribute is omitted (or if [AllowAnonymous]
is specified.
回答3:
Short answer - you cannot.
If you check closely you will see that, when you have the Authorize
attribute, the User object is of type ClaimsPrincipal
and when you don't have it - it is of type WindowsPrincipal
.
But you can always add custom Authorize
attribute, or Custom policy-based authorization, and check the user claims there and do your stuff.
来源:https://stackoverflow.com/questions/48453591/how-to-get-user-claims-inside-asp-core-2-method-without-authorize-attribute