# Configure Auth

> >

- **Type:** Skill
- **Install:** `agentstack add skill-dotnet-skills-configure-auth`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [dotnet](https://agentstack.voostack.com/s/dotnet)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [dotnet](https://github.com/dotnet)
- **Source:** https://github.com/dotnet/skills/tree/main/plugins/dotnet-blazor/skills/configure-auth

## Install

```sh
agentstack add skill-dotnet-skills-configure-auth
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Configure Auth

## Step 1 — Read AGENTS.md

Read `AGENTS.md` at the workspace root for the project's interactivity mode and scope before making changes.

## Step 2 — Register auth services in Program.cs

```csharp
// Program.cs (server project)
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddAuthorization();
```

For ASP.NET Core Identity add the Identity services:

```csharp
builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = IdentityConstants.ApplicationScheme;
    options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
.AddIdentityCookies();

builder.Services.AddIdentityCore()
    .AddRoles()
    .AddEntityFrameworkStores()
    .AddSignInManager()
    .AddDefaultTokenProviders();
```

## Step 3 — Wire App.razor for auth and render mode

The `App.razor` component must use `AuthorizeRouteView` and conditionally apply the render mode so that pages excluded from interactive routing render statically.

```razor

    

    
    

@code {
    [CascadingParameter]
    public HttpContext HttpContext { get; set; } = default!;

    private IComponentRenderMode? RenderModeForPage =>
        HttpContext.AcceptsInteractiveRouting()
            ? InteractiveServer   // replace with the app's render mode
            : null;
}
```

In `Routes.razor` (or wherever the router lives), use `AuthorizeRouteView`:

```razor

    
        
            
                @if (context.User.Identity?.IsAuthenticated != true)
                {
                    
                }
                else
                {
                    You are not authorized to access this resource.
                }
            
        
        
    

```

## Step 4 — Protect pages and components

### [Authorize] attribute on pages

```razor
@page "/admin"
@attribute [Authorize]
```

With roles or policies:

```razor
@attribute [Authorize(Roles = "Admin")]
@attribute [Authorize(Policy = "RequireManager")]
```

### AuthorizeView for conditional UI

```razor

    Welcome, @context.User.Identity?.Name!
    Log in

```

Role/policy variants:

```razor

    Admin content here

```

### Access auth state in code

```csharp
[CascadingParameter]
private Task? AuthState { get; set; }

protected override async Task OnInitializedAsync()
{
    if (AuthState is not null)
    {
        var state = await AuthState;
        var isAdmin = state.User.IsInRole("Admin");
    }
}
```

## Step 5 — Identity pages must stay static SSR

`SignInManager` and `UserManager` use `HttpContext` internally and **throw in interactive components**. Identity pages (login, register, manage) must render as static SSR.

In a **globally interactive** app, mark every Identity page:

```razor
@page "/Account/Login"
@attribute [ExcludeFromInteractiveRouting]
```

This forces a full-page navigation (exits the interactive circuit) so the page renders through the static SSR pipeline with a real `HttpContext`.

`App.razor` must use `AcceptsInteractiveRouting()` (Step 3) to return `null` for these pages — otherwise the framework still tries to render them interactively.

In a **per-page** app, Identity pages are static by default (no `@rendermode` directive), so `[ExcludeFromInteractiveRouting]` is not needed.

## Step 6 — Auth state in WebAssembly / Auto mode

WebAssembly components run in the browser and have no `HttpContext`. Auth state must be serialized from the server during prerendering and deserialized on the client.

**Server `Program.cs`:**

```csharp
builder.Services.AddAuthenticationStateSerialization();
```

**Client `.Client/Program.cs`:**

```csharp
builder.Services.AddAuthenticationStateDeserialization();
```

Without these calls, `Task` resolves to an anonymous user after WebAssembly takes over from prerendering.

`AddAuthenticationStateSerialization` accepts options to include role and claim data:

```csharp
builder.Services.AddAuthenticationStateSerialization(options =>
    options.SerializeAllClaims = true);
```

## Render Mode × Auth Matrix

| Render mode | HttpContext.User | SignInManager | Auth state source | Key requirement |
|---|---|---|---|---|
| Static SSR | Available | Works | Server pipeline | Use middleware for redirects, `` does NOT render |
| Server (interactive) | NOT available | Throws | `CascadingAuthenticationState` | Use `[Authorize]` + `AuthorizeView`, not `HttpContext` |
| WebAssembly | NOT available | Throws | Serialized from server | `AddAuthenticationStateSerialization` / `Deserialization` |
| Auto | NOT available after WASM | Throws | Serialized from server | Same as WebAssembly; register in **both** Program.cs files |

## Common Mistakes

| Mistake | Symptom | Fix |
|---------|---------|-----|
| Using `HttpContext.User` in interactive component | Null or stale claims | Use `[CascadingParameter] Task` |
| `SignInManager` in interactive component | `InvalidOperationException` | Move to static SSR page with `[ExcludeFromInteractiveRouting]` |
| Missing `AddAuthenticationStateSerialization` | Anonymous user after WASM loads | Add to server Program.cs; add `Deserialization` to client Program.cs |
| `` in static SSR layout | Content never shown | Static SSR uses middleware pipeline; redirect via `LoginPath` or `RedirectToLogin` component |
| Global interactivity without `AcceptsInteractiveRouting` | Identity pages crash | Add `AcceptsInteractiveRouting()` check in App.razor (Step 3) |
| Missing `AddCascadingAuthenticationState()` | `Task` is null | Register in Program.cs (Step 2) |

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [dotnet](https://github.com/dotnet)
- **Source:** [dotnet/skills](https://github.com/dotnet/skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-dotnet-skills-configure-auth
- Seller: https://agentstack.voostack.com/s/dotnet
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
