Blazor server app + identity server 4


Blazor server app + Idendity Server 4

Blazor server app supports authentitication with external providers like identity server 4 using OpenId Connect.

First of all, install nuget package

dotnet install IdentityServer4

Now, we need to configure services in Startup.cs

services.AddAuthentication(options =>
{
    options.DefaultScheme = "Cookies";
    options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
    options.Authority = "identity server address";
    options.RequireHttpsMetadata = false;

    options.ClientId = "ClientId";
    options.SaveTokens = true;
});

services.AddMvcCore(options =>
{
    var policy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();
    options.Filters.Add(new AuthorizeFilter(policy));
});

This .RequireAuthenticatedUser() line tells aspnet always require authenticated user and challenge oidc scheme if user is not authenticated. It means all pages in your project are not shown for not authenticated user.

If you are in another situation and have pages for unauthorized user, you can remove last part of code and add mvc endpoint

app.UseAuthentication();
app.UseRouting();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}"); //adds mvc endpoint
    endpoints.MapBlazorHub<App>(selector: "app");
    endpoints.MapFallbackToPage("/_Host");
});

Then you need controller which will be responsible for challenging authentication scheme.

public class AccountController : Controller
{
    public IActionResult SignIn([FromRoute] string scheme)
    {
        scheme = scheme ?? "oidc";
        var redirectUrl = Url.Content("~/");
        return Challenge(
            new AuthenticationProperties { RedirectUri = redirectUrl },
            scheme);
    }
}

You can use button like <a href="/account/login">Login <a> for logging in user.

For those pages which need to be protected, we can easily use @attribute [Authorize], also it allows protect pages by roles or policy. AuthenticationStateProvider gives us access to identity context, for example from microsoft index.razor page

@page "/"
@attribute [Authorize]
@inject AuthenticationStateProvider AuthenticationStateProvider

<h1>Hello, world!</h1>

Welcome to your new app.

<AuthorizeView  Roles="admin, superuser">
    <p>You can only see this if you're an admin or superuser.</p>
</AuthorizeView>

<button @onclick="@LogUsername">Write user info to console</button>

@code {

    private async Task LogUsername()
    {
        var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
        var user = authState.User;

        if (user.Identity.IsAuthenticated)
        {
            name = user.Identity.Name;
            Console.WriteLine($"{user.Identity.Name} is authenticated.");
        }
        else
        {
            Console.WriteLine("The user is NOT authenticated.");
        }
    }
}

<AuthorizeView> component alike @attribute [Authorize] supports role-based and policy based authorization.

Buy Me A Coffee

Related Posts

Avoid reflections of mappers and let Mapster generate mappers for you

Mapster generating tool for onion application

Predict Bitcoin price with ML.net

Live time series coin price predictor with machine learning

Throw exceptions from backend to frontend with blazor

One of advantages of using same code language on both frontend and backend

How to avoid violating of SOLID principles while extending service behaviours

Step by step extending service behaviour with decorator pattern respecting SOLID

Blazor render optimization

Best practices

.Net 6 brings application state to blazor webassembly server prerender

It kills strange blinking on screen

Must have libraries for blazor

List of best nuget packages

Blazor virtualize component

Lazy loading of big lists. Rendering optimization.

Blazor grpc - comunication optimization

Smaller and faster requests to your backend from blazor wasm

Free database for your blazor app

Don't pay for the cloud