Day 9: Authentication & Authorization
Secure your Blazor app with user login, role-based access, and protected routes.
1. Key Concepts
Authentication: Verify user identity (e.g., login).
Authorization: Control access to resources (e.g., admin-only pages).
2. Setup Authentication
Step 1: Add Required Services
Register authentication services in Program.cs:
csharp
Copy
using Microsoft.AspNetCore.Components.Authorization; // Add this
builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();
builder.Services.AddAuthorizationCore(); // Enable authorization
Step 2: Create a Custom Authentication State Provider
csharp
Copy
// CustomAuthStateProvider.cs
public class CustomAuthStateProvider : AuthenticationStateProvider
{
private ClaimsPrincipal _user = new ClaimsPrincipal(new ClaimsIdentity());
public override Task<AuthenticationState> GetAuthenticationStateAsync() =>
Task.FromResult(new AuthenticationState(_user));
// Call this method after login
public void SetUserAuthenticated(string username)
{
var identity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, username),
}, "custom-auth");
_user = new ClaimsPrincipal(identity);
NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
}
// Call this method on logout
public void SetUserLoggedOut()
{
_user = new ClaimsPrincipal(new ClaimsIdentity());
NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
}
}
3. Create a Login Page
razor
Copy
@page "/login"
@inject AuthenticationStateProvider AuthStateProvider
@inject NavigationManager Navigation
<h3>Login</h3>
<EditForm Model="@loginModel" OnValidSubmit="HandleLogin">
<InputText @bind-Value="loginModel.Username" placeholder="Username" />
<InputText type="password" @bind-Value="loginModel.Password" placeholder="Password" />
<button type="submit">Login</button>
</EditForm>
@code {
private LoginModel loginModel = new();
private async Task HandleLogin()
{
// Simulate authentication (replace with real logic)
if (loginModel.Username == "admin" && loginModel.Password == "password")
{
var authProvider = (CustomAuthStateProvider)AuthStateProvider;
authProvider.SetUserAuthenticated(loginModel.Username);
Navigation.NavigateTo("/");
}
}
public class LoginModel
{
public string Username { get; set; }
public string Password { get; set; }
}
}
4. Protect Routes with [Authorize]
Add the [Authorize] attribute to restrict access to authenticated users:
razor
Copy
@page "/admin"
@attribute [Authorize]
<h1>Admin Dashboard</h1>
5. Role-Based Authorization
Add roles to the user’s claims and restrict access by role:
csharp
Copy
// In CustomAuthStateProvider.cs
public void SetUserAuthenticated(string username, string role)
{
var identity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, username),
new Claim(ClaimTypes.Role, role) // Add role claim
}, "custom-auth");
_user = new ClaimsPrincipal(identity);
NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
}
Restrict a page to users with the Admin role:
razor
Copy
@page "/admin"
@attribute [Authorize(Roles = "Admin")]
6. Display Auth State with AuthorizeView
Show/hide content based on login status:
razor
Copy
<AuthorizeView>
<Authorized>
<p>Welcome, @context.User.Identity.Name!</p>
<button @onclick="Logout">Logout</button>
</Authorized>
<NotAuthorized>
<a href="/login">Login</a>
</NotAuthorized>
</AuthorizeView>
@code {
[Inject] AuthenticationStateProvider AuthStateProvider { get; set; }
[Inject] NavigationManager Navigation { get; set; }
private void Logout()
{
var authProvider = (CustomAuthStateProvider)AuthStateProvider;
authProvider.SetUserLoggedOut();
Navigation.NavigateTo("/");
}
}
7. Update App.razor
Wrap the app in <CascadingAuthenticationState> to propagate auth state:
razor
Copy
<CascadingAuthenticationState>
<Router ...>
<!-- Your existing routes -->
</Router>
</CascadingAuthenticationState>
8. Real-World Integration Tips
Secure APIs: Use JWT tokens for API requests.
ASP.NET Core Identity: Integrate with a backend for user management.
Third-Party Auth: Use Auth0, Azure AD, or Google OAuth.
9. Practice Task
Add a Registration Page:
Create a
/registerroute.Collect username, email, and password (simulate saving to a backend).
Redirect to login after registration.
10. Key Takeaways
AuthenticationStateProvider: Manages user authentication state.[Authorize]: Restrict access to authenticated users or roles.AuthorizeView: Conditionally render UI based on auth status.