How to get user claims inside ASP Core 2 method without Authorize attribute?

限于喜欢 提交于 2021-01-27 12:09:34

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!