How to get claim inside Asp.Net Core Razor View
Asked Answered
U

4

25

I did it in my rc1 project like:

User.Claims.ElementAt(#).Value

But after I switched to rtm it wouldn’t work anymore. When I debug the Razor view the object looks the same but User.Claims is just empty. Any idea what the reason could be.

Unawares answered 24/8, 2016 at 13:56 Comment(3)
I found the problem. I had a typo in the line where it sets the cookie: HttpContext.Authentication.SignInAsync("typo here", new ClaimsPrincipal(auth));. Sorry for the unnecessary work people.Unawares
Just a suggestion, it might be a bad idea to access claims by index.. Might want to use claim types as in JDupont's answer.Lunetta
You are right it already caused an out of bounds once we removed a claim from the system. It is already a task on the board but got not jet around to it.Unawares
T
31

Assuming you have claims attached to the current principal. In your Razor view:

@((ClaimsIdentity) User.Identity)

This will give you access to the ClaimsIdentity of the current user. In an effort to keep your claims fetching clean you may want to create an extension method for searching claims.

public static string GetSpecificClaim(this ClaimsIdentity claimsIdentity, string claimType)
{
    var claim = claimsIdentity.Claims.FirstOrDefault(x => x.Type == claimType);

    return (claim != null) ? claim.Value : string.Empty;
}

Then you can just access whatever claim you want with:

@((ClaimsIdentity) User.Identity).GetSpecificClaim("someclaimtype")

Hope this helps.

Quick search for claims identity in razor view came up with a similar question and answer: MVC 5 Access Claims Identity User Data

Theophylline answered 24/8, 2016 at 14:23 Comment(2)
I first stumbled on the one you linked at the end, but I find that your answer is the better solution. Since creating an extention allows your to use it better throughout the most of the application.Panga
How to check IsInRole?Fifteenth
N
14

Tested in .net core 2.2 in the razor page :

@User.FindFirst("nameOfClaim").Value

Ney answered 1/5, 2020 at 22:36 Comment(1)
@User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier);Psalmody
C
3

In Core 3.0, use view authorization.

In Startup.cs:

    services.AddAuthorization(options =>
    {
        options.AddPolicy("Policy_Name", x => x.RequireClaim("Policy_Name"));
    });

At the top of your UI file where you are inserting the conditional element, insert:

@using Microsoft.AspNetCore.Authorization
@inject IAuthorizationService AuthorizationService

Then inside the body use:

    @if ((await AuthorizationService.AuthorizeAsync(User, "Policy_Name")).Succeeded){
        //show ui element
    }

View-based authorization in ASP.NET Core MVC

Carman answered 29/10, 2019 at 2:37 Comment(2)
See this related post with concerns about this policy based approach: https://mcmap.net/q/63791/-how-do-you-create-a-custom-authorizeattribute-in-asp-net-coreChart
@Carman your Polocy_Name will not necessarily be your claim name. Here is an example We use in production: options.AddPolicy("AnsiblePageAccess", policy => policy.RequireClaim(Claims.CustomClaimTypes.PageAccess, "Ansible")); The claim name in the Claims table is "Ansible" but the access can be granted using the Policy: [Authorize(Policy = "AnsiblePageAccess")] Make sense? Cheers.Passifloraceous
I
0

You can achieve this with the following code in your view :

if(User.FindFirst("MyClaim")?.Value == "some_value")
{
  ... Show concerned UI block
}

Altough, if you use policies (as it's the recommended way), I suggest to define policies in your Startup.cs/Program.cs and use injected IAuthorizationService to call AuthorizeAsync :

if((await AuthorizationService.AuthorizeAsync(User, "MyClaim")).Succeeded)
{
   ... Show concerned UI block
}

This way is better as it use defined policies, which can validates many different values.

Imperative answered 9/1, 2022 at 9:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.