<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Decoupling Authentication and Authorization: A Clean Design for Dynamic Role Switching in Software - General</title>
    <link>https://community.hpe.com/t5/software-general/decoupling-authentication-and-authorization-a-clean-design-for/m-p/7273559#M1617</link>
    <description>&lt;P&gt;Modern enterprise applications commonly use Azure Active Directory (Azure AD) for authentication while maintaining &lt;STRONG&gt;application-specific roles&lt;/STRONG&gt; in their own database.&lt;/P&gt;&lt;P&gt;A typical requirement looks like this:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;A single Azure AD user can belong to multiple organizations&lt;/LI&gt;&lt;LI&gt;Each organization maps to different roles in the application&lt;/LI&gt;&lt;LI&gt;After login, the user selects which organization (or role context) they want to operate in&lt;/LI&gt;&lt;LI&gt;The UI and authorization rules must respond to that selection&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;At first glance, this seems straightforward. However, in Blazor Server, things become tricky because of how &lt;STRONG&gt;authentication, authorization, and circuit state&lt;/STRONG&gt; interact.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT size="4"&gt;&lt;STRONG&gt;Business Scenario&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;Consider a procurement system:&lt;/P&gt;&lt;P&gt;A user logs in via Azure AD and may have multiple roles:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Global Administrator&lt;/LI&gt;&lt;LI&gt;Local Administrator&lt;/LI&gt;&lt;LI&gt;Service Desk User&lt;/LI&gt;&lt;LI&gt;Supplier&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;Instead of maintaining separate Azure AD identities, the application allows the user to &lt;STRONG&gt;switch context dynamically&lt;/STRONG&gt;.&lt;/P&gt;&lt;P&gt;&lt;FONT size="4"&gt;&lt;STRONG&gt;Conceptual Flow&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;DIV&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic1.png" style="width: 708px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159387iE5F32B6C96CA96DE/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic1.png" alt="Decoupling Authentication and Authorization_Pic1.png" /&gt;&lt;/span&gt;&lt;/DIV&gt;&lt;P&gt;The challenge is ensuring that &lt;STRONG&gt;navigation and authorization stay consistent with the selected context&lt;/STRONG&gt;.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT size="4"&gt;&lt;STRONG&gt;Role Model&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;To support multiple roles efficiently, roles are stored as &lt;STRONG&gt;bitwise values&lt;/STRONG&gt; instead of strings.&lt;/P&gt;&lt;P&gt;This allows multiple roles to be combined and evaluated using bitwise operations.&lt;/P&gt;&lt;P&gt;For example:&lt;/P&gt;&lt;DIV&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic2.png" style="width: 448px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159388i5FC02167259C15C8/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic2.png" alt="Decoupling Authentication and Authorization_Pic2.png" /&gt;&lt;/span&gt;&lt;/DIV&gt;&lt;P&gt;This model enables flexibility such as:&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;A user being both SuperAdmin and SupportUser&lt;/LI&gt;&lt;LI&gt;Policies that combine multiple roles without additional logic&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT size="4"&gt;&lt;STRONG&gt;Authorization with Policies&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;ASP.NET Core policies make role checks declarative and reusable.&lt;/P&gt;&lt;P&gt;Instead of writing custom checks in every page, you define policies like:&lt;/P&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic3.png" style="width: 752px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159377iAC61546EBEC0A2C7/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic3.png" alt="Decoupling Authentication and Authorization_Pic3.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;Under the hood, these policies evaluate a custom authorization requirement that performs &lt;STRONG&gt;bitwise comparisons&lt;/STRONG&gt;.&lt;/P&gt;&lt;P&gt;&lt;FONT size="4"&gt;&lt;STRONG&gt;Policy Evaluation:&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;DIV&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic4.png" style="width: 435px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159389i3AE55FE6AAC45CCB/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic4.png" alt="Decoupling Authentication and Authorization_Pic4.png" /&gt;&lt;/span&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT size="4"&gt;&lt;STRONG&gt;Simplified handler logic&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;DIV&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic5.png" style="width: 710px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159390i76CC831C433155EE/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic5.png" alt="Decoupling Authentication and Authorization_Pic5.png" /&gt;&lt;/span&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;This keeps authorization logic centralized and consistent across the application.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT size="4"&gt;&lt;STRONG&gt;The First Challenge: AppState vs Authorization&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;A natural approach in Blazor is to store the selected role in a service like:&lt;/P&gt;&lt;P&gt;AppState.SelectedRole&lt;/P&gt;&lt;P&gt;This works for the UI:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Menus update correctly&lt;/LI&gt;&lt;LI&gt;Components react to changes&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;However, authorization attributes like:&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic6.png" style="width: 485px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159391iC1157AB6FE9FC846/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic6.png" alt="Decoupling Authentication and Authorization_Pic6.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;do not work with this approach.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Why?&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;Because:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Authorization runs in ASP.NET Core middleware&lt;/LI&gt;&lt;LI&gt;AppState exists inside the Blazor circuit&lt;/LI&gt;&lt;LI&gt;These are completely different runtime contexts&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic7.png" style="width: 752px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159392i61307B43676DE3BE/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic7.png" alt="Decoupling Authentication and Authorization_Pic7.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Attempt 1: Updating Claims Dynamically&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;A common idea is to update claims when the user changes roles.&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic8.png" style="width: 752px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159393iF2FE638832A8DB91/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic8.png" alt="Decoupling Authentication and Authorization_Pic8.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;But this creates problems:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Claims are tied to the authentication cookie&lt;/LI&gt;&lt;LI&gt;Changing them inside a running circuit is unreliable&lt;/LI&gt;&lt;LI&gt;The current request context does not automatically refresh&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;In practice, this leads to inconsistent behavior.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Attempt 2: Reading AppState in Authorization&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;Another idea is to access AppState inside the authorization handler.&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic9.png" style="width: 752px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159394iD2A3116DF1792960/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic9.png" alt="Decoupling Authentication and Authorization_Pic9.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;This fails because:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Authorization handlers run in middleware&lt;/LI&gt;&lt;LI&gt;They do not have access to Blazor services&lt;/LI&gt;&lt;LI&gt;There is no shared state between these layers&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT size="4"&gt;&lt;STRONG&gt;The Core Architectural Insight&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;The key realization is:&lt;/P&gt;&lt;P&gt;Authentication identity and application context are not the same thing.&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;&lt;STRONG&gt;Authentication&lt;/STRONG&gt; → Who the user is (Azure AD)&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Authorization&lt;/STRONG&gt; → What the user can do (application roles)&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Application context&lt;/STRONG&gt; → Which organization the user is acting under&lt;/LI&gt;&lt;/UL&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic10.png" style="width: 752px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159384iE77AD0C073566A07/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic10.png" alt="Decoupling Authentication and Authorization_Pic10.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;A Practical and Reliable Solution&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;Instead of forcing these concerns together, separate them:&lt;/P&gt;&lt;P&gt;Azure AD → Authentication only&lt;/P&gt;&lt;P&gt;Application → Role + context management&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Recommended Flow&lt;/STRONG&gt;&lt;/P&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic11.png" style="width: 587px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159395i06847731A0A7A5AB/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic11.png" alt="Decoupling Authentication and Authorization_Pic11.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Using a Server-Side Endpoint&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;When a user switches organization, send the selection to a controller:&lt;/P&gt;&lt;P&gt;POST /account/switch&lt;/P&gt;&lt;P&gt;The controller:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Validates the user&lt;/LI&gt;&lt;LI&gt;Retrieves the correct role from the database&lt;/LI&gt;&lt;LI&gt;Stores the selected context&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Authorization Based on Context&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;Instead of relying on UI state, the authorization handler evaluates:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Current user identity&lt;/LI&gt;&lt;LI&gt;Selected organization / role context&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;This ensures consistent behaviour across requests.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Security Consideration&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;Never trust client input directly.&lt;/P&gt;&lt;P&gt;Even if the role is stored in a cookie or selected via UI:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Always validate against the database&lt;/LI&gt;&lt;LI&gt;Ensure that the selected role belongs to the authenticated user&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;UI → Cookie → DB Validation → Authorization Decision&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT size="4"&gt;&lt;STRONG&gt;Why Page Refresh Is Necessary&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;One of the most confusing aspects is that role changes do not take effect immediately.&lt;/P&gt;&lt;P&gt;This is expected.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Execution model:&lt;/STRONG&gt;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Blazor events → SignalR (no new HTTP request)&lt;/LI&gt;&lt;LI&gt;Authorization → Requires HTTP request&lt;/LI&gt;&lt;/UL&gt;&lt;DIV&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic12.png" style="width: 444px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159396i804660470EDBD6A1/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic12.png" alt="Decoupling Authentication and Authorization_Pic12.png" /&gt;&lt;/span&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;That’s why:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Page reload&lt;/LI&gt;&lt;LI&gt;Or forceLoad: true&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;is required for changes to take effect.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Lessons Learned&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;During implementation, several approaches were evaluated:&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic13.png" style="width: 580px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159397i790134313C7F9810/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic13.png" alt="Decoupling Authentication and Authorization_Pic13.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Best Practices&lt;/STRONG&gt;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Keep Azure AD for authentication only&lt;/LI&gt;&lt;LI&gt;Store application roles in your own database&lt;/LI&gt;&lt;LI&gt;Use policy-based authorization for clarity&lt;/LI&gt;&lt;LI&gt;Never depend on Blazor UI state for authorization&lt;/LI&gt;&lt;LI&gt;Always validate role selection on the server&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT size="4"&gt;&lt;STRONG&gt;Conclusion&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;Dynamic role switching in Blazor Server is not just a UI challenge — it is an &lt;STRONG&gt;architecture challenge&lt;/STRONG&gt; involving authentication, authorization, and state management.&lt;/P&gt;&lt;P&gt;The key takeaway is:&lt;/P&gt;&lt;P&gt;Authentication defines &lt;EM&gt;who the user is&lt;/EM&gt;, while application logic defines &lt;EM&gt;what they are allowed to do in a specific context&lt;/EM&gt;.&lt;/P&gt;&lt;P&gt;By separating these concerns and using server-side validation with policy-based authorization, you can build a solution that is:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Secure&lt;/LI&gt;&lt;LI&gt;Maintainable&lt;/LI&gt;&lt;LI&gt;Scalable&lt;/LI&gt;&lt;/UL&gt;</description>
    <pubDate>Mon, 05 Oct 2026 08:55:39 GMT</pubDate>
    <dc:creator>SasmitaB</dc:creator>
    <dc:date>2026-10-05T08:55:39Z</dc:date>
    <item>
      <title>Decoupling Authentication and Authorization: A Clean Design for Dynamic Role Switching</title>
      <link>https://community.hpe.com/t5/software-general/decoupling-authentication-and-authorization-a-clean-design-for/m-p/7273559#M1617</link>
      <description>&lt;P&gt;Modern enterprise applications commonly use Azure Active Directory (Azure AD) for authentication while maintaining &lt;STRONG&gt;application-specific roles&lt;/STRONG&gt; in their own database.&lt;/P&gt;&lt;P&gt;A typical requirement looks like this:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;A single Azure AD user can belong to multiple organizations&lt;/LI&gt;&lt;LI&gt;Each organization maps to different roles in the application&lt;/LI&gt;&lt;LI&gt;After login, the user selects which organization (or role context) they want to operate in&lt;/LI&gt;&lt;LI&gt;The UI and authorization rules must respond to that selection&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;At first glance, this seems straightforward. However, in Blazor Server, things become tricky because of how &lt;STRONG&gt;authentication, authorization, and circuit state&lt;/STRONG&gt; interact.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT size="4"&gt;&lt;STRONG&gt;Business Scenario&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;Consider a procurement system:&lt;/P&gt;&lt;P&gt;A user logs in via Azure AD and may have multiple roles:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Global Administrator&lt;/LI&gt;&lt;LI&gt;Local Administrator&lt;/LI&gt;&lt;LI&gt;Service Desk User&lt;/LI&gt;&lt;LI&gt;Supplier&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;Instead of maintaining separate Azure AD identities, the application allows the user to &lt;STRONG&gt;switch context dynamically&lt;/STRONG&gt;.&lt;/P&gt;&lt;P&gt;&lt;FONT size="4"&gt;&lt;STRONG&gt;Conceptual Flow&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;DIV&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic1.png" style="width: 708px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159387iE5F32B6C96CA96DE/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic1.png" alt="Decoupling Authentication and Authorization_Pic1.png" /&gt;&lt;/span&gt;&lt;/DIV&gt;&lt;P&gt;The challenge is ensuring that &lt;STRONG&gt;navigation and authorization stay consistent with the selected context&lt;/STRONG&gt;.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT size="4"&gt;&lt;STRONG&gt;Role Model&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;To support multiple roles efficiently, roles are stored as &lt;STRONG&gt;bitwise values&lt;/STRONG&gt; instead of strings.&lt;/P&gt;&lt;P&gt;This allows multiple roles to be combined and evaluated using bitwise operations.&lt;/P&gt;&lt;P&gt;For example:&lt;/P&gt;&lt;DIV&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic2.png" style="width: 448px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159388i5FC02167259C15C8/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic2.png" alt="Decoupling Authentication and Authorization_Pic2.png" /&gt;&lt;/span&gt;&lt;/DIV&gt;&lt;P&gt;This model enables flexibility such as:&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;A user being both SuperAdmin and SupportUser&lt;/LI&gt;&lt;LI&gt;Policies that combine multiple roles without additional logic&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT size="4"&gt;&lt;STRONG&gt;Authorization with Policies&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;ASP.NET Core policies make role checks declarative and reusable.&lt;/P&gt;&lt;P&gt;Instead of writing custom checks in every page, you define policies like:&lt;/P&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic3.png" style="width: 752px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159377iAC61546EBEC0A2C7/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic3.png" alt="Decoupling Authentication and Authorization_Pic3.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;Under the hood, these policies evaluate a custom authorization requirement that performs &lt;STRONG&gt;bitwise comparisons&lt;/STRONG&gt;.&lt;/P&gt;&lt;P&gt;&lt;FONT size="4"&gt;&lt;STRONG&gt;Policy Evaluation:&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;DIV&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic4.png" style="width: 435px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159389i3AE55FE6AAC45CCB/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic4.png" alt="Decoupling Authentication and Authorization_Pic4.png" /&gt;&lt;/span&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT size="4"&gt;&lt;STRONG&gt;Simplified handler logic&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;DIV&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic5.png" style="width: 710px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159390i76CC831C433155EE/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic5.png" alt="Decoupling Authentication and Authorization_Pic5.png" /&gt;&lt;/span&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;This keeps authorization logic centralized and consistent across the application.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT size="4"&gt;&lt;STRONG&gt;The First Challenge: AppState vs Authorization&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;A natural approach in Blazor is to store the selected role in a service like:&lt;/P&gt;&lt;P&gt;AppState.SelectedRole&lt;/P&gt;&lt;P&gt;This works for the UI:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Menus update correctly&lt;/LI&gt;&lt;LI&gt;Components react to changes&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;However, authorization attributes like:&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic6.png" style="width: 485px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159391iC1157AB6FE9FC846/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic6.png" alt="Decoupling Authentication and Authorization_Pic6.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;do not work with this approach.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Why?&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;Because:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Authorization runs in ASP.NET Core middleware&lt;/LI&gt;&lt;LI&gt;AppState exists inside the Blazor circuit&lt;/LI&gt;&lt;LI&gt;These are completely different runtime contexts&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic7.png" style="width: 752px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159392i61307B43676DE3BE/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic7.png" alt="Decoupling Authentication and Authorization_Pic7.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Attempt 1: Updating Claims Dynamically&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;A common idea is to update claims when the user changes roles.&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic8.png" style="width: 752px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159393iF2FE638832A8DB91/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic8.png" alt="Decoupling Authentication and Authorization_Pic8.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;But this creates problems:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Claims are tied to the authentication cookie&lt;/LI&gt;&lt;LI&gt;Changing them inside a running circuit is unreliable&lt;/LI&gt;&lt;LI&gt;The current request context does not automatically refresh&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;In practice, this leads to inconsistent behavior.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Attempt 2: Reading AppState in Authorization&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;Another idea is to access AppState inside the authorization handler.&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic9.png" style="width: 752px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159394iD2A3116DF1792960/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic9.png" alt="Decoupling Authentication and Authorization_Pic9.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;This fails because:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Authorization handlers run in middleware&lt;/LI&gt;&lt;LI&gt;They do not have access to Blazor services&lt;/LI&gt;&lt;LI&gt;There is no shared state between these layers&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT size="4"&gt;&lt;STRONG&gt;The Core Architectural Insight&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;The key realization is:&lt;/P&gt;&lt;P&gt;Authentication identity and application context are not the same thing.&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;&lt;STRONG&gt;Authentication&lt;/STRONG&gt; → Who the user is (Azure AD)&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Authorization&lt;/STRONG&gt; → What the user can do (application roles)&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Application context&lt;/STRONG&gt; → Which organization the user is acting under&lt;/LI&gt;&lt;/UL&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic10.png" style="width: 752px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159384iE77AD0C073566A07/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic10.png" alt="Decoupling Authentication and Authorization_Pic10.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;A Practical and Reliable Solution&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;Instead of forcing these concerns together, separate them:&lt;/P&gt;&lt;P&gt;Azure AD → Authentication only&lt;/P&gt;&lt;P&gt;Application → Role + context management&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Recommended Flow&lt;/STRONG&gt;&lt;/P&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic11.png" style="width: 587px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159395i06847731A0A7A5AB/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic11.png" alt="Decoupling Authentication and Authorization_Pic11.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Using a Server-Side Endpoint&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;When a user switches organization, send the selection to a controller:&lt;/P&gt;&lt;P&gt;POST /account/switch&lt;/P&gt;&lt;P&gt;The controller:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Validates the user&lt;/LI&gt;&lt;LI&gt;Retrieves the correct role from the database&lt;/LI&gt;&lt;LI&gt;Stores the selected context&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Authorization Based on Context&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;Instead of relying on UI state, the authorization handler evaluates:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Current user identity&lt;/LI&gt;&lt;LI&gt;Selected organization / role context&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;This ensures consistent behaviour across requests.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Security Consideration&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;Never trust client input directly.&lt;/P&gt;&lt;P&gt;Even if the role is stored in a cookie or selected via UI:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Always validate against the database&lt;/LI&gt;&lt;LI&gt;Ensure that the selected role belongs to the authenticated user&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;UI → Cookie → DB Validation → Authorization Decision&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT size="4"&gt;&lt;STRONG&gt;Why Page Refresh Is Necessary&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;One of the most confusing aspects is that role changes do not take effect immediately.&lt;/P&gt;&lt;P&gt;This is expected.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Execution model:&lt;/STRONG&gt;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Blazor events → SignalR (no new HTTP request)&lt;/LI&gt;&lt;LI&gt;Authorization → Requires HTTP request&lt;/LI&gt;&lt;/UL&gt;&lt;DIV&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic12.png" style="width: 444px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159396i804660470EDBD6A1/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic12.png" alt="Decoupling Authentication and Authorization_Pic12.png" /&gt;&lt;/span&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;That’s why:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Page reload&lt;/LI&gt;&lt;LI&gt;Or forceLoad: true&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;is required for changes to take effect.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Lessons Learned&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;During implementation, several approaches were evaluated:&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Decoupling Authentication and Authorization_Pic13.png" style="width: 580px;"&gt;&lt;img src="https://community.hpe.com/t5/image/serverpage/image-id/159397i790134313C7F9810/image-size/large?v=v2&amp;amp;px=2000" role="button" title="Decoupling Authentication and Authorization_Pic13.png" alt="Decoupling Authentication and Authorization_Pic13.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Best Practices&lt;/STRONG&gt;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Keep Azure AD for authentication only&lt;/LI&gt;&lt;LI&gt;Store application roles in your own database&lt;/LI&gt;&lt;LI&gt;Use policy-based authorization for clarity&lt;/LI&gt;&lt;LI&gt;Never depend on Blazor UI state for authorization&lt;/LI&gt;&lt;LI&gt;Always validate role selection on the server&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT size="4"&gt;&lt;STRONG&gt;Conclusion&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;Dynamic role switching in Blazor Server is not just a UI challenge — it is an &lt;STRONG&gt;architecture challenge&lt;/STRONG&gt; involving authentication, authorization, and state management.&lt;/P&gt;&lt;P&gt;The key takeaway is:&lt;/P&gt;&lt;P&gt;Authentication defines &lt;EM&gt;who the user is&lt;/EM&gt;, while application logic defines &lt;EM&gt;what they are allowed to do in a specific context&lt;/EM&gt;.&lt;/P&gt;&lt;P&gt;By separating these concerns and using server-side validation with policy-based authorization, you can build a solution that is:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Secure&lt;/LI&gt;&lt;LI&gt;Maintainable&lt;/LI&gt;&lt;LI&gt;Scalable&lt;/LI&gt;&lt;/UL&gt;</description>
      <pubDate>Mon, 05 Oct 2026 08:55:39 GMT</pubDate>
      <guid>https://community.hpe.com/t5/software-general/decoupling-authentication-and-authorization-a-clean-design-for/m-p/7273559#M1617</guid>
      <dc:creator>SasmitaB</dc:creator>
      <dc:date>2026-10-05T08:55:39Z</dc:date>
    </item>
    <item>
      <title>Re: Decoupling Authentication and Authorization: A Clean Design for Dynamic Role Switching</title>
      <link>https://community.hpe.com/t5/software-general/decoupling-authentication-and-authorization-a-clean-design-for/m-p/7273614#M1618</link>
      <description>&lt;P&gt;Thanks for sharing this informative topic. It is very helpful.&lt;/P&gt;</description>
      <pubDate>Tue, 06 Oct 2026 05:04:46 GMT</pubDate>
      <guid>https://community.hpe.com/t5/software-general/decoupling-authentication-and-authorization-a-clean-design-for/m-p/7273614#M1618</guid>
      <dc:creator>Thaufique_Mod</dc:creator>
      <dc:date>2026-10-06T05:04:46Z</dc:date>
    </item>
  </channel>
</rss>

