{"id":53775,"date":"2020-08-11T08:00:17","date_gmt":"2020-08-11T06:00:17","guid":{"rendered":"https:\/\/code-maze.com\/?p=53775"},"modified":"2022-05-22T15:22:57","modified_gmt":"2022-05-22T13:22:57","slug":"blazor-webassembly-role-based-authorization","status":"publish","type":"post","link":"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/","title":{"rendered":"Role-Based Authorization with Blazor WebAssembly"},"content":{"rendered":"<p>Up until now, we have learned how to use <a href=\"https:\/\/code-maze.com\/authenticationstateprovider-blazor-webassembly\/\" target=\"_blank\" rel=\"noopener noreferrer\">AuthenticationStateProvider<\/a> in Blazor WebAssembly. Additionally, we have learned how to <a href=\"https:\/\/code-maze.com\/blazor-webassembly-registration-aspnetcore-identity\/\" target=\"_blank\" rel=\"noopener noreferrer\">create registration functionality<\/a> as well as <a href=\"https:\/\/code-maze.com\/blazor-webassembly-authentication-aspnetcore-identity\" target=\"_blank\" rel=\"noopener noreferrer\">Login and Logout functionalities<\/a> in our application. But what about the roles? Well, in this article, we are going to learn how to create a role-based authorization in our Blazor WebAssembly application and how to modify AuthenticationStateProvider to support this feature.<\/p>\n<div style=\"padding: 20px; border-left: 5px #dc2323 solid; display: block; margin-bottom: 20px; box-shadow: 1px 1px 5px 0px lightgrey;\">To download the source code for this article, you can visit the <a href=\"https:\/\/github.com\/CodeMazeBlog\/blazor-series\/tree\/blazor-webassembly-role-based-authorization\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Role-Based Authorization with Blazor WASM repository<\/a>.<\/div>\n<p>For the complete navigation for this series, you can visit the <a href=\"https:\/\/code-maze.com\/blazor-webassembly-series\/\" target=\"_blank\" rel=\"noopener noreferrer\">Blazor Series page<\/a>.<\/p>\n<p>So, let&#8217;s start.<\/p>\n<h2 id=\"adding-roles\">Adding Roles to the Database<\/h2>\n<p>If we inspect the <code>Startup.cs<\/code> class in the Web API project, or the <code>Program<\/code> class in .NET 6 and above, we are going to see that we already support roles:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">services.AddIdentity&lt;IdentityUser, IdentityRole&gt;()\r\n    .AddEntityFrameworkStores&lt;ProductContext&gt;();\r\n<\/pre>\n<p>So, all we have to do is to add different roles to the database. To do that, let\u2019s create a new <code>RoleConfiguration<\/code> class inside the <code>Configuration<\/code> folder and modify it:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class RoleConfiguration : IEntityTypeConfiguration&lt;IdentityRole&gt;\r\n{\r\n    public void Configure(EntityTypeBuilder&lt;IdentityRole&gt; builder)\r\n    {\r\n        builder.HasData(\r\n            new IdentityRole\r\n            {\r\n                Name = \"Viewer\",\r\n                NormalizedName = \"VIEWER\"\r\n            },\r\n            new IdentityRole\r\n            {\r\n                Name = \"Administrator\",\r\n                NormalizedName = \"ADMINISTRATOR\"\r\n            }\r\n        );\r\n    }\r\n}\r\n<\/pre>\n<p>Here we just create two roles that we are going to seed to the database.<\/p>\n<p>After that, we are going to modify the <code>OnModelCreating<\/code> method in the <code>ProductContext<\/code> class:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-highlight=\"6\">protected override void OnModelCreating(ModelBuilder modelBuilder)\r\n{\r\n    base.OnModelCreating(modelBuilder);\r\n\r\n    modelBuilder.ApplyConfiguration(new ProductConfiguration());\r\n    modelBuilder.ApplyConfiguration(new RoleConfiguration());\r\n}\r\n<\/pre>\n<p>With this in place, we are ready to create our migration files:<\/p>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"powershell\">PM&gt; Add-Migration InitialRoleSeed<\/code><\/p>\n<p>And update the database:<\/p>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"powershell\">PM&gt; Update-Database<\/code><\/p>\n<p>With that, we have our roles added to the database.<\/p>\n<p>Just one more thing. Since we already have a single user in our database, we can assign an administrator role to that user. All we have to do is to write a simple INSERT query in the SQL Management Studio:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">INSERT INTO AspNetUserRoles \r\nVALUES ('22da8bd7-7ba3-40ad-9ebd-f0c149e759d6','c2671493-8bcf-4a82-969b-6c5fbc2cd5e0')\r\n<\/pre>\n<p>Of course, you have to replace these id values with your user and role id values.<\/p>\n<h2 id=\"supporting-role-based\">Supporting Role-Based Authorization with Register Action and Claims<\/h2>\n<p>What we want to do here is to assign a Viewer role to every user registered through the Registration form. To do that, we have to slightly modify the <code>RegisterUser<\/code> action in the <code>Accounts<\/code> controller:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-highlight=\"17\">[HttpPost(\"Registration\")]\r\npublic async Task&lt;IActionResult&gt; RegisterUser([FromBody] UserForRegistrationDto userForRegistration) \r\n{\r\n    if (userForRegistration == null || !ModelState.IsValid)\r\n        return BadRequest();\r\n\r\n    var user = new IdentityUser { UserName = userForRegistration.Email, Email = userForRegistration.Email };\r\n            \r\n    var result = await _userManager.CreateAsync(user, userForRegistration.Password); \r\n    if (!result.Succeeded) \r\n    {\r\n        var errors = result.Errors.Select(e =&gt; e.Description);\r\n\r\n        return BadRequest(new RegistrationResponseDto { Errors = errors }); \r\n    }\r\n\r\n    await _userManager.AddToRoleAsync(user, \"Viewer\");\r\n            \r\n    return StatusCode(201); \r\n}\r\n<\/pre>\n<p>That\u2019s all it takes, but we require one more thing. We want to add this role or multiple roles related to a single user, inside the JWT claims. To do that, we have to modify the private <code>GetClaims<\/code> method in the same controller:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-highlight=\"1,8-11\">private async Task&lt;List&lt;Claim&gt;&gt; GetClaims(IdentityUser user) \r\n{ \r\n    var claims = new List&lt;Claim&gt; \r\n    { \r\n        new Claim(ClaimTypes.Name, user.Email) \r\n    };\r\n\r\n    var roles = await _userManager.GetRolesAsync(user); \r\n    foreach (var role in roles) \r\n    { \r\n        claims.Add(new Claim(ClaimTypes.Role, role)); \r\n    }\r\n\r\n    return claims; \r\n}\r\n<\/pre>\n<p>Additionally, since this method is now the async one, we have to add the <code>await<\/code> keyword while calling it inside the <code>Login<\/code> action:<\/p>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">var claims = await GetClaims(user);<\/code><\/p>\n<p>Excellent.<\/p>\n<p>Once we send the Postman request to the <code>Login<\/code> action, we are going to get the valid token as we did in a previous article. But this time, if we inspect the token, we are going to find an additional role claim inside it:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/79-Additional-Role-Claim-in-the-JWT.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-53776\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/79-Additional-Role-Claim-in-the-JWT.png\" alt=\"Additional Role Claim in the JWT for the Role-Based Authorization\" width=\"982\" height=\"539\" srcset=\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/79-Additional-Role-Claim-in-the-JWT.png 982w, https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/79-Additional-Role-Claim-in-the-JWT-300x165.png 300w, https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/79-Additional-Role-Claim-in-the-JWT-768x422.png 768w\" sizes=\"auto, (max-width: 982px) 100vw, 982px\" \/><\/a><\/p>\n<p>Nicely done.<\/p>\n<p>We can move on to the Blazor WebAssembly part.<\/p>\n<h2 id=\"role-based-authorization\">Role-Based Authorization with the Blazor Client Application<\/h2>\n<p>In a previous part, we have implemented our <code>AuthenticationStateProvider<\/code> with the <code>JwtParser<\/code> class that extracts claims from our token. But in that class, we didn\u2019t cover the role claims. So, it is time to change that.<\/p>\n<p>Let\u2019s first modify the <code>ParseClaimsFromJwt<\/code> method:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-highlight=\"10\">public static IEnumerable&lt;Claim&gt; ParseClaimsFromJwt(string jwt)\r\n{\r\n    var claims = new List&lt;Claim&gt;();\r\n    var payload = jwt.Split('.')[1];\r\n\r\n    var jsonBytes = ParseBase64WithoutPadding(payload);\r\n\r\n    var keyValuePairs = JsonSerializer.Deserialize&lt;Dictionary&lt;string, object&gt;&gt;(jsonBytes);\r\n\r\n    ExtractRolesFromJWT(claims, keyValuePairs);\r\n\r\n    claims.AddRange(keyValuePairs.Select(kvp =&gt; new Claim(kvp.Key, kvp.Value.ToString())));\r\n\r\n    return claims;\r\n}\r\n<\/pre>\n<p>As you can see, we are calling an additional method to extract roles from JWT. That said, let\u2019s create this missing method:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">private static void ExtractRolesFromJWT(List&lt;Claim&gt; claims, Dictionary&lt;string, object&gt; keyValuePairs)\r\n{\r\n    keyValuePairs.TryGetValue(ClaimTypes.Role, out object roles);\r\n\r\n    if (roles != null)\r\n    {\r\n        var parsedRoles = roles.ToString().Trim().TrimStart('[').TrimEnd(']').Split(',');\r\n\r\n        if (parsedRoles.Length &gt; 1)\r\n        {\r\n            foreach (var parsedRole in parsedRoles)\r\n            {\r\n                claims.Add(new Claim(ClaimTypes.Role, parsedRole.Trim('\"')));\r\n            }\r\n        }\r\n        else\r\n        {\r\n            claims.Add(new Claim(ClaimTypes.Role, parsedRoles[0]));\r\n        }\r\n\r\n        keyValuePairs.Remove(ClaimTypes.Role);\r\n    }\r\n}\r\n<\/pre>\n<p>Here, we try to extract roles from the <code>keyValuePairs<\/code> dictionary. If the roles exist, we split the roles into a string array. If we have more than one role, we iterate through each of them and add them to the claims list. Otherwise, we just add that single role to the claims list. Also, we are using the <code>Trim<\/code>, <code>TrimStart<\/code>, and <code>TrimEnd<\/code> methods to remove the square brackets and quotation marks from our roles. If a user has multiple roles, the roles object looks like this: <code>[\"FirstRole\",\"SecondRole\"]<\/code>. So, by using all the <code>Trim<\/code> methods, we are removing these brackets and quotation marks.<\/p>\n<p>Now, we want to modify the <code>NotifyUserAuthentication<\/code> method from the <code>AuthStateProvider<\/code> class:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-highlight=\"1,3\">public void NotifyUserAuthentication(string token)\r\n{\r\n    var authenticatedUser = new ClaimsPrincipal(new ClaimsIdentity(JwtParser.ParseClaimsFromJwt(token), \"jwtAuthType\"));\r\n    var authState = Task.FromResult(new AuthenticationState(authenticatedUser));\r\n    NotifyAuthenticationStateChanged(authState);\r\n}\r\n<\/pre>\n<p>As you can see, we don\u2019t accept just an email as a parameter but the entire token. Additionally, for the <code>ClaimsIdentity<\/code>, we use all the claims parsed from the <code>JwtParser<\/code> class.<\/p>\n<p>Due to this change, we have to modify the call to this method from the <code>Login<\/code> method inside the <code>AuthenticationService<\/code> class:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-highlight=\"7\">public async Task&lt;AuthResponseDto&gt; Login(UserForAuthenticationDto userForAuthentication)\r\n{\r\n    \/\/previous code\r\n\r\n    await _localStorage.SetItemAsync(\"authToken\", result.Token);\r\n              \r\n    ((AuthStateProvider)_authStateProvider).NotifyUserAuthentication(result.Token);\r\n    _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(\"bearer\", result.Token);\r\n\r\n    return new AuthResponseDto { IsAuthSuccessful = true };\r\n}\r\n<\/pre>\n<p>We are using the entire token as a parameter instead of just an email.<\/p>\n<h2 id=\"testing\">Testing Role-Based Authorization<\/h2>\n<p>Before we start with testing, we are going to register another user in our application. After registration, this user will have the Viewer role.<\/p>\n<p>Right now, only authorized users can access the <code>Products<\/code> page. But, let\u2019s change that a bit. Let\u2019s assume that only administrators can access this page. To do that, we have to modify the <code>[Authorize]<\/code> attribute in the <code>Products.razor<\/code> file:<\/p>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">@attribute [Authorize(Roles = \"Administrator\")]<\/code><\/p>\n<p>We add the <code>Roles<\/code> property with the <code>Administrator<\/code> value.<\/p>\n<p>Now, if we start both applications and login as a viewer, we won\u2019t be able to access this page:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/80-Access-protected-page-with-role-without-enough-rights.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-53777\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/80-Access-protected-page-with-role-without-enough-rights.png\" alt=\"Access protected page with role without enough rights - Role-Based Authorization\" width=\"885\" height=\"232\" srcset=\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/80-Access-protected-page-with-role-without-enough-rights.png 885w, https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/80-Access-protected-page-with-role-without-enough-rights-300x79.png 300w, https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/80-Access-protected-page-with-role-without-enough-rights-768x201.png 768w\" sizes=\"auto, (max-width: 885px) 100vw, 885px\" \/><\/a><\/p>\n<p>But if we try to login with the administrator account:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/81-Access-protected-page-with-admin-account.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-53778\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/81-Access-protected-page-with-admin-account.png\" alt=\"Role-Based authorization with admin account\" width=\"1090\" height=\"291\" srcset=\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/81-Access-protected-page-with-admin-account.png 1090w, https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/81-Access-protected-page-with-admin-account-300x80.png 300w, https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/81-Access-protected-page-with-admin-account-1024x273.png 1024w, https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/81-Access-protected-page-with-admin-account-768x205.png 768w, https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/81-Access-protected-page-with-admin-account-1080x288.png 1080w\" sizes=\"auto, (max-width: 1090px) 100vw, 1090px\" \/><\/a><\/p>\n<p>We can see that we can access the page.<\/p>\n<p>Additionally, if we don\u2019t want to allow users with the Viewer role to even see the <code>Products<\/code> menu item, we can do that by modifying the <code>NavMenu.razor<\/code> file:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"html\" data-enlighter-highlight=\"1\">&lt;AuthorizeView Roles=\"Administrator\"&gt;\r\n    &lt;Authorized&gt;\r\n        &lt;li class=\"nav-item px-3\"&gt;\r\n            &lt;NavLink class=\"nav-link\" href=\"products\"&gt;\r\n                &lt;span class=\"oi oi-list-rich\" aria-hidden=\"true\"&gt;&lt;\/span&gt; Products\r\n            &lt;\/NavLink&gt;\r\n        &lt;\/li&gt;\r\n    &lt;\/Authorized&gt;\r\n&lt;\/AuthorizeView&gt;\r\n<\/pre>\n<p>With the previous logic, the Products menu was visible only to authorized users. Now, we allow this link to be visible only to authorized users in the Administrator role.<\/p>\n<p>Again, you can log in with both users and confirm that the Viewers can\u2019t see the Products menu item.<\/p>\n<p>Finally, since the client code can be bypassed, we should ensure that our API\u2019s endpoint is protected properly as well:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-highlight=\"3\">[Route(\"api\/products\")]\r\n[ApiController]\r\n[Authorize(Roles = \"Administrator\")]\r\npublic class ProductsController : ControllerBase\r\n<\/pre>\n<p>And that\u2019s all it takes.<\/p>\n<p>We have implemented Role-Based authorization in our Blazor WebAssembly application.<\/p>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>In this article, we have learned how to implement Role-Based authorization with Blazor WebAssembly and our API application. We have seen how to add roles to the database, how to include them in the JWT as claims, and how to parse them on the client level.<\/p>\n<p>Additionally, we have learned how to protect endpoints, limit access to some pages, and how to hide pages using roles in our Blazor WASM application.<\/p>\n<p>In the next article, we are going to show you how to <a href=\"https:\/\/code-maze.com\/refresh-token-with-blazor-webassembly-and-asp-net-core-web-api\/\" target=\"_blank\" rel=\"noopener noreferrer\">refresh your access token with Blazor WebAssembly and ASP.NET Core Web API<\/a>.<\/p>\n<p>Best regards.<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Up until now, we have learned how to use AuthenticationStateProvider in Blazor WebAssembly. Additionally, we have learned how to create registration functionality as well as Login and Logout functionalities in our application. But what about the roles? Well, in this article, we are going to learn how to create a role-based authorization in our Blazor [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":55060,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"categories":[683,684,12],"tags":[685,686,742,741],"class_list":["post-53775","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blazor","category-blazor-webassembly","category-csharp","tag-blazor","tag-blazor-webassembly","tag-role-claims","tag-role-based-authorization","et-has-post-format-content","et_post_format-et-post-format-standard"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.7 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Role-Based Authorization with Blazor WebAssembly - Code Maze<\/title>\n<meta name=\"description\" content=\"In this article, we are going to learn about Role-Based Authorization with Blazor WebAssembly and ASP.NET Core Web API applications.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Role-Based Authorization with Blazor WebAssembly - Code Maze\" \/>\n<meta property=\"og:description\" content=\"In this article, we are going to learn about Role-Based Authorization with Blazor WebAssembly and ASP.NET Core Web API applications.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/\" \/>\n<meta property=\"og:site_name\" content=\"Code Maze\" \/>\n<meta property=\"article:published_time\" content=\"2020-08-11T06:00:17+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-05-22T13:22:57+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/15-Role-Based-Authorization.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1100\" \/>\n\t<meta property=\"og:image:height\" content=\"620\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Marinko Spasojevi\u0107\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/CodeMazeBlog\" \/>\n<meta name=\"twitter:site\" content=\"@CodeMazeBlog\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Marinko Spasojevi\u0107\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":[\"Article\",\"BlogPosting\"],\"@id\":\"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/\"},\"author\":{\"name\":\"Marinko Spasojevi\u0107\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/d6fa06e66820968d19b39fb63cff2533\"},\"headline\":\"Role-Based Authorization with Blazor WebAssembly\",\"datePublished\":\"2020-08-11T06:00:17+00:00\",\"dateModified\":\"2022-05-22T13:22:57+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/\"},\"wordCount\":1004,\"commentCount\":25,\"publisher\":{\"@id\":\"https:\/\/code-maze.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/15-Role-Based-Authorization.png\",\"keywords\":[\"Blazor\",\"Blazor WebAssembly\",\"Role Claims\",\"Role-Based Authorization\"],\"articleSection\":[\"Blazor\",\"Blazor WebAssembly\",\"C#\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/\",\"url\":\"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/\",\"name\":\"Role-Based Authorization with Blazor WebAssembly - Code Maze\",\"isPartOf\":{\"@id\":\"https:\/\/code-maze.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/15-Role-Based-Authorization.png\",\"datePublished\":\"2020-08-11T06:00:17+00:00\",\"dateModified\":\"2022-05-22T13:22:57+00:00\",\"description\":\"In this article, we are going to learn about Role-Based Authorization with Blazor WebAssembly and ASP.NET Core Web API applications.\",\"breadcrumb\":{\"@id\":\"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/#primaryimage\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/15-Role-Based-Authorization.png\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/15-Role-Based-Authorization.png\",\"width\":1100,\"height\":620,\"caption\":\"15 Role-Based Authorization\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/code-maze.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Role-Based Authorization with Blazor WebAssembly\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/code-maze.com\/#website\",\"url\":\"https:\/\/code-maze.com\/\",\"name\":\"Code Maze\",\"description\":\"Learn. Code. Succeed.\",\"publisher\":{\"@id\":\"https:\/\/code-maze.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/code-maze.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/code-maze.com\/#organization\",\"name\":\"Code Maze\",\"url\":\"https:\/\/code-maze.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png\",\"width\":3511,\"height\":3510,\"caption\":\"Code Maze\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/CodeMazeBlog\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/d6fa06e66820968d19b39fb63cff2533\",\"name\":\"Marinko Spasojevi\u0107\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/marinko-1x1-3-150x150.jpg\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/marinko-1x1-3-150x150.jpg\",\"caption\":\"Marinko Spasojevi\u0107\"},\"description\":\"Hi, my name is Marinko Spasojevic. Currently, I work as a full-time .NET developer and my passion is web application development. Just getting something to work is not enough for me. To make it just how I like it, it must be readable, reusable, and easy to maintain. Prior to being an author on the CodeMaze blog, I had been working as a professor of Computer Science for several years. So, sharing knowledge while working as a full-time developer comes naturally to me.\",\"sameAs\":[\"https:\/\/www.linkedin.com\/in\/marinko-spasojevic\/\",\"https:\/\/x.com\/https:\/\/twitter.com\/CodeMazeBlog\"],\"url\":\"https:\/\/code-maze.com\/author\/marinko\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Role-Based Authorization with Blazor WebAssembly - Code Maze","description":"In this article, we are going to learn about Role-Based Authorization with Blazor WebAssembly and ASP.NET Core Web API applications.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/","og_locale":"en_US","og_type":"article","og_title":"Role-Based Authorization with Blazor WebAssembly - Code Maze","og_description":"In this article, we are going to learn about Role-Based Authorization with Blazor WebAssembly and ASP.NET Core Web API applications.","og_url":"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/","og_site_name":"Code Maze","article_published_time":"2020-08-11T06:00:17+00:00","article_modified_time":"2022-05-22T13:22:57+00:00","og_image":[{"width":1100,"height":620,"url":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/15-Role-Based-Authorization.png","type":"image\/png"}],"author":"Marinko Spasojevi\u0107","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/CodeMazeBlog","twitter_site":"@CodeMazeBlog","twitter_misc":{"Written by":"Marinko Spasojevi\u0107","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":["Article","BlogPosting"],"@id":"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/#article","isPartOf":{"@id":"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/"},"author":{"name":"Marinko Spasojevi\u0107","@id":"https:\/\/code-maze.com\/#\/schema\/person\/d6fa06e66820968d19b39fb63cff2533"},"headline":"Role-Based Authorization with Blazor WebAssembly","datePublished":"2020-08-11T06:00:17+00:00","dateModified":"2022-05-22T13:22:57+00:00","mainEntityOfPage":{"@id":"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/"},"wordCount":1004,"commentCount":25,"publisher":{"@id":"https:\/\/code-maze.com\/#organization"},"image":{"@id":"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/#primaryimage"},"thumbnailUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/15-Role-Based-Authorization.png","keywords":["Blazor","Blazor WebAssembly","Role Claims","Role-Based Authorization"],"articleSection":["Blazor","Blazor WebAssembly","C#"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/","url":"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/","name":"Role-Based Authorization with Blazor WebAssembly - Code Maze","isPartOf":{"@id":"https:\/\/code-maze.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/#primaryimage"},"image":{"@id":"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/#primaryimage"},"thumbnailUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/15-Role-Based-Authorization.png","datePublished":"2020-08-11T06:00:17+00:00","dateModified":"2022-05-22T13:22:57+00:00","description":"In this article, we are going to learn about Role-Based Authorization with Blazor WebAssembly and ASP.NET Core Web API applications.","breadcrumb":{"@id":"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/#primaryimage","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/15-Role-Based-Authorization.png","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/08\/15-Role-Based-Authorization.png","width":1100,"height":620,"caption":"15 Role-Based Authorization"},{"@type":"BreadcrumbList","@id":"https:\/\/code-maze.com\/blazor-webassembly-role-based-authorization\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/code-maze.com\/"},{"@type":"ListItem","position":2,"name":"Role-Based Authorization with Blazor WebAssembly"}]},{"@type":"WebSite","@id":"https:\/\/code-maze.com\/#website","url":"https:\/\/code-maze.com\/","name":"Code Maze","description":"Learn. Code. Succeed.","publisher":{"@id":"https:\/\/code-maze.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/code-maze.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/code-maze.com\/#organization","name":"Code Maze","url":"https:\/\/code-maze.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/#\/schema\/logo\/image\/","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png","width":3511,"height":3510,"caption":"Code Maze"},"image":{"@id":"https:\/\/code-maze.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/CodeMazeBlog"]},{"@type":"Person","@id":"https:\/\/code-maze.com\/#\/schema\/person\/d6fa06e66820968d19b39fb63cff2533","name":"Marinko Spasojevi\u0107","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/#\/schema\/person\/image\/","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/marinko-1x1-3-150x150.jpg","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/marinko-1x1-3-150x150.jpg","caption":"Marinko Spasojevi\u0107"},"description":"Hi, my name is Marinko Spasojevic. Currently, I work as a full-time .NET developer and my passion is web application development. Just getting something to work is not enough for me. To make it just how I like it, it must be readable, reusable, and easy to maintain. Prior to being an author on the CodeMaze blog, I had been working as a professor of Computer Science for several years. So, sharing knowledge while working as a full-time developer comes naturally to me.","sameAs":["https:\/\/www.linkedin.com\/in\/marinko-spasojevic\/","https:\/\/x.com\/https:\/\/twitter.com\/CodeMazeBlog"],"url":"https:\/\/code-maze.com\/author\/marinko\/"}]}},"_links":{"self":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/53775","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/comments?post=53775"}],"version-history":[{"count":4,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/53775\/revisions"}],"predecessor-version":[{"id":70483,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/53775\/revisions\/70483"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/media\/55060"}],"wp:attachment":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/media?parent=53775"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/categories?post=53775"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/tags?post=53775"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}