how to change Blazor WASM identity net core 3.1 messages "You are logged out", "checking login state" and "authorizing"? - asp.net-core

I need to know how to personalize and/or change language for this messages, I suppose it has to do with IdentityServer4.
Any ideas?

What you are looking for is the RemoteAuthenticatorView .
You can find more details for your answer in the official documentation.
#page "/security/{action}"
#using Microsoft.AspNetCore.Components.WebAssembly.Authentication
<RemoteAuthenticatorView Action="#Action">
#*authentication/login*
<LoggingIn></LoggingIn>
#*authentication/login-callback*
<CompletingLoggingIn></CompletingLoggingIn>
#*authentication/login-failed*
<LogInFailed></LogInFailed>
#*authentication/logout*
<LogOut></LogOut>
#*authentication/logout-callback*
<CompletingLogOut></CompletingLogOut>
#*authentication/logout-failed*
<LogOutFailed></LogOutFailed>
#*authentication/logged-out*
<LogOutSucceeded></LogOutSucceeded>
#*authentication/profile*
<UserProfile></UserProfile>
#*authentication/register*
<Registering></Registering>
</RemoteAuthenticatorView>
#code{
[Parameter]
public string Action { get; set; }
}

It is necessary to add some tags in Authentication.razor component:
#page "/authentication/{action}"
#using Microsoft.AspNetCore.Components.WebAssembly.Authentication
<RemoteAuthenticatorView Action="#Action">
<LogInFailed>
<div class="alert alert-danger" role="alert">#strLogInFailed</div>
</LogInFailed>
<LogOut>
<div class="alert alert-info" role="alert">#strLogOut</div>
</LogOut>
<LogOutSucceeded>
<div class="alert alert-success" role="alert">#strLogOutSucceeded</div>
</LogOutSucceeded>
<LoggingIn>
<div class="alert alert-info" role="alert">#strLoggingIn</div>
</LoggingIn>
<CompletingLoggingIn>
<div class="alert alert-success" role="alert">#strCompletingLoggingIn</div>
</CompletingLoggingIn>
</RemoteAuthenticatorView>
#code {
[Parameter] public string Action { get; set; }
string strLogInFailed = "Your login was not successful.";
string strLogOut = "Trying to close your session.";
string strLogOutSucceeded = "Your session has been closed successfully.";
string strLoggingIn = "Redirecting to the login screen.";
string strCompletingLoggingIn = "Your login was successful.";
}
I found how to do it in: Custom Authentication User Interface which, by the way, explains a lot on
How to Secure Blazor WebAssembly with IdentityServer4
After read it, I also check the RemoteAuthenticatorView Class
Even accomplished this, still persist the "Authorizing..." message.

To change the message "Authorizing..."
Need to add
<Authorizing>
<h1>Authorization in progress</h1>
<p>Only visible while authorization is in progress.</p>
</Authorizing>
to file App.razor
<CascadingAuthenticationState>
<Router AppAssembly="#typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="#routeData"
DefaultLayout="#typeof(MainLayout)">
<NotAuthorized>
<h1>Sorry</h1>
<p>You're not authorized to reach this page.</p>
<p>You may need to log in as a different user.</p>
</NotAuthorized>
<Authorizing>
<h1>Authorization in progress</h1>
<p>Only visible while authorization is in progress.</p>
</Authorizing>
</AuthorizeRouteView>
</Found>
<NotFound>
<LayoutView Layout="#typeof(MainLayout)">
<h1>Sorry</h1>
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
You can find more details official documentation.

You can use the <Authorizing> tag to override the default text.
<AuthorizeView>
<Authorizing>
<p class="authorizing">Authorizing...</p>
</Authorizing>
<Authorized>
<p class="authorized">Welcome, #context.User.Identity.Name!</p>
</Authorized>
<NotAuthorized>
<p class="not-authorized">You're not authorized, #(context.User.Identity.Name ?? "anonymous")</p>
</NotAuthorized>
</AuthorizeView>
Source:
https://github.com/dotnet/aspnetcore/blob/1ed72f8f5f14dfc5a4ebc9d5d116d63792caa7fc/src/Components/test/testassets/BasicTestApp/AuthTest/AuthorizeViewCases.razor

Related

MAUI AAD Authentication ClaimsPrincipal with IsAuthenticated always false

I have a MAUI app running on localhost and when you start the app, it triggers microsoft login, after the user sucessfull login I catch the ClaimsPrincipal and IsAuthenticated is always false. According to my Main.razor component if the user is not Authenticated it calls the RedirectToLogin Component again and I don't know how to Authorize my logged in user in the app so it might have somethin to do with the IsAuthenticated being false.
I have seen some solutions and they say you have to build ClaimsPrincipal passin the authentication type as parameter to the ClaimsIdentity like this:
new ClaimsPrincipal(new Identity("something"))
The problem is that I get already the ClaimsPrincipal from AAD só I dont know what I should do because I have no way to see the AAD because it is taken care by other team.
This is my Main.razor component:
<Router AppAssembly="#typeof(Main).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="#routeData" DefaultLayout="#typeof(MainLayout)">
<Authorizing>
Authorizing...
</Authorizing>
<NotAuthorized>
<RedirectToLogin />
</NotAuthorized>
</AuthorizeRouteView>
</Found>
<NotFound>
<CascadingAuthenticationState>
<LayoutView Layout="#typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</CascadingAuthenticationState>
</NotFound>
</Router>
This is RedirectToLogin component:
#using Microsoft.AspNetCore.Components.Authorization
#using OfficeManagerApp.Areas.Services.Implementations
#inject AuthenticationStateProvider AuthenticationStateProvider
#inject NavigationManager NavigationManager
<div class="loader loader-bouncing"><span>Redirecting...</span></div>
#code {
protected override async Task OnInitializedAsync()
{
await ((ExternalAuthStateProvider)AuthenticationStateProvider)
.LogInAsync();
NavigationManager.NavigateTo("/", forceLoad: true);
}
}
and here is where I have the break point to see the CLaimsPrincipal inside the ExternalAuthStateProvider class:
Here are the tutorials I followed for this.
PlatformService tutorial
ExternalAuthStateProvider tutorial
I also have a solution using just the PlatformService tutorial with the same problem.
After a while I found the solution!
Basically you receive a ClaimsPrincipal from AAD but you have to create your own ClaimsPrincipal inside the app using the claims from the AAD ClaimsPrincipal.
In ExternalAuthStateProvider.cs, LoginWithExternalProviderAsync() method I did the following:
private async Task<ClaimsPrincipal> LoginWithExternalProviderAsync()
{
var authenticationResult = await _platformService.GetAuthenticationResult();
var authenticatedUser = new ClaimsPrincipal(new ClaimsIdentity(authenticationResult.ClaimsPrincipal.Claims, "Basic"));
return await Task.FromResult(authenticatedUser);
}
You just need to do this and then it works!!
Extra -----------
To improve the flow login logout, I created a LoginPage.razor:
#page "/login"
#using Microsoft.AspNetCore.Authorization
#using Microsoft.AspNetCore.Components.Authorization
#using OfficeManagerApp.Areas.Services.Implementations
#attribute [AllowAnonymous]
#inject AuthenticationStateProvider AuthenticationStateProvider
#inject NavigationManager NavigationManager
<button #onclick="Login">Log in</button>
#code
{
public async Task Login()
{
await ((ExternalAuthStateProvider)AuthenticationStateProvider)
.LogInAsync();
NavigationManager.NavigateTo("/");
}
}
Changed the RedirectToLogin,razor:
#inject NavigationManager NavigationManager
<div class="loader loader-bouncing"><span>Redirecting...</span></div>
#code {
protected override void OnInitialized()
{
NavigationManager.NavigateTo("/login");
}
}
And added a logout method:
private void Logout(){
((ExternalAuthStateProvider)AuthenticationStateProvider)
.Logout();
}
Also did some changes to my Main.razor:
<CascadingAuthenticationState>
<Router AppAssembly="#typeof(Main).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="#routeData" DefaultLayout="#typeof(MainLayout)">
<Authorizing>
Authorizing...
</Authorizing>
<NotAuthorized>
#if (!context.User.Identity.IsAuthenticated)
{
<RedirectToLogin />
}
else
{
<p>You are not authorized to access this resource.</p>
}
</NotAuthorized>
</AuthorizeRouteView>
</Found>
<NotFound>
<LayoutView Layout="#typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
</CascadingAuthenticationState>
Note don't forget to add to your _Imports.razor:
#using Microsoft.AspNetCore.Components.Authorization

Blazor - when open the main page without being authenticated never redirect to login page

I'm using Blazor with .net 6. In the app.razor page I have the defaults for AutorizedRouteView and NotAuthorized. It's working fine, except for main page. If does not have any authenticated, should redirect to login page, but it's always detecting the NotAuthorized page.
App.razor
<CascadingAuthenticationState>
<Router AppAssembly="#typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="#routeData" DefaultLayout="#typeof(MainLayout)">
<Authorizing>
<text> Please wait, we are authorizing the user. </text>
</Authorizing>
<NotAuthorized>
<div class="text-center">
<img src="/assets/img/restrito.png" class="rounded" alt="não encontrado">
<br /><br>
<h1 class="fw-bolder">Não possui acesso a esta página.</h1>
</div>
</NotAuthorized>
</AuthorizeRouteView>
</Found>
<NotFound>
#{
<div class="text-center">
<img src="/assets/img/404.png" class="rounded" alt="não encontrado">
<br /><br>
<h1 class="fw-bolder">Página não encontrada.</h1>
Retornar à página principal
</div>
}
</NotFound>
</Router>
</CascadingAuthenticationState>
AppRouteView.cs
public class AppRouteView : RouteView
{
[Inject]
private NavigationManager _navigationManager { get; set; }
[Inject]
private IAccountService _accountService { get; set; }
protected override void Render(RenderTreeBuilder builder)
{
// var authorize = Attribute.GetCustomAttribute(RouteData.PageType, typeof(AuthorizeAttribute)) != null;
if (_accountService.User == null)
{
_navigationManager.NavigateTo("account/login");
}
else
{
base.Render(builder);
}
}
}
Index.razor
#page "/"
#using VidaConfortoApplication.Client.Services.Interfaces
#attribute [Authorize]
#inject IAccountService _accountService
<div class="p-4">
<div class="container">
<h1>Olá #_accountService.User?.Name!</h1>
<p>Está autenticado na aplicação GesSad!</p>
<p><NavLink href="users">Gerir utilizadores</NavLink></p>
</div>
</div>
Login.razor page does not have any [Authorize] attriute
You need to handle the redirect to the login page yourself, within the <NotAuthorized> tag. Check whether the user is Authenticated, and if not, redirect them to the login page. Here is an example:
<AuthorizeRouteView RouteData="#routeData" DefaultLayout="#typeof(MainLayout)">
<NotAuthorized>
#if (!context.User.Identity.IsAuthenticated)
{
<RedirectToLogin />
}
else
{
<p>You are not authorized to access this resource.</p>
}
</NotAuthorized>
</AuthorizeRouteView>
Note that this also handles the difference between being Authenticated and being Authorized. A user may be logged in to a site (authenticated), without having permissions to access certain resources (authorized).
In your <RedirectToLogin /> component, just redirect the user in OnInitialized() or OnInitializedAsync(). Here is a simple example:
#inject NavigationManager _nav
#code {
protected override void OnInitialized()
{
_nav.NavigateTo("/account/login");
}
}
If you want the user to be returned to the page they initially tried to enter, get the target uri before redirecting to login, and pass it as a query parameter to the login page (to handle the redirection after logging in). Then, the <RedirectToLogin /> component could look like this:
#inject NavigationManager _nav
#code {
protected override void OnInitialized()
{
var path = _nav.ToBaseRelativePath(_nav.Uri);
_nav.NavigateTo($"/account/login?returnUrl={path}");
}
}

get back to login page again after click on forgot password in Blazor web assembly app

I have a "Blazer Web assembly" app with a login page(Component) and a Forgot Password page(Component).
When I click on the "Forgot Password" link on the Login page, instead of sending me to the "forgot password" page, it sends me back again to the login page.
Here is my code:
App.Razor
<CascadingAuthenticationState>
<Router AppAssembly="#typeof(App).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="#routeData" DefaultLayout="#typeof(MainLayout)">
<NotAuthorized>
</NotAuthorized>
</AuthorizeRouteView>
</Found>
<NotFound>
<LayoutView Layout="#typeof(MainLayout)">
</LayoutView>
</NotFound>
</Router>
</CascadingAuthenticationState>
MainLayout.razor:
#inherits LayoutComponentBase
<AuthorizeView>
<Authorized>
<NavBar>
<NavBarLeft>....
#code {
[CascadingParameter]
Task<AuthenticationState> AuthenticationState { get; set; }
protected override async Task OnParametersSetAsync()
{
navBarLeftInjectableMenu.SetContent(null, false);
if (!(await AuthenticationState).User.Identity.IsAuthenticated)
{
NavigationManager.NavigateTo("/login");
}
}
Forgot Password Page:
#page "/ForgotPass"
#layout AuthLayout
<div class=....
Login Page:
#layout AuthLayout
#page "/LoginX"
#inject NavigationManager NavigationManager
<div class="hold-transition login-page">
<div class="login-box">
<button #onclick="ForgotPassword" class="btn btn-primary btn-block">Forgot Password</button>
</div>
</div>
#code {
void ForgotPassword()
{
NavigationManager.NavigateTo("/ForgotPassX", true);
}
}
AuthLayout.razor:
#inherits LayoutComponentBase
<div class="main">
<div class="content px-4">
#Body
</div>
</div>
HttpInterceptor:
private async Task InterceptBeforeSendAsync(object sender, HttpClientInterceptorEventArgs e)
{
var absolutePath = e.Request.RequestUri != null? e.Request.RequestUri.AbsolutePath : string.Empty;
if (!absolutePath.Contains("token") && !absolutePath.Contains("acc"))
{
var token = await _refreshTokenService.TryRefreshToken();
if (!string.IsNullOrEmpty(token))
{
e.Request.Headers.Authorization =
new AuthenticationHeaderValue("bearer", token);
}
}
}
You have 2 options:
1/ Put #attribute [AllowAnonymous] in your forgot password page.
2/ Create a different Layout with no Authorize required then use that for your forgot password page like #layout AnonymousLayout
This is because you call the OnParametersSetAsync method every time you request, and your judgment condition is forcibly directed to the Login page.
You can add an extra judgment to bypass the IsAuthenticated check.
For example: Use the request url to determine whether to execute this check:
protected override async Task OnParametersSetAsync()
{
string currentUrl = NavigationManager.Uri;
if (!currentUrl.Contains("ForgotPass")){
navBarLeftInjectableMenu.SetContent(null, false);
if ((!(await AuthenticationState).User.Identity.IsAuthenticated))
{
NavigationManager.NavigateTo("/Login");
}
}
}

Redirect to login in Blazor Server Azure B2C Authentication

Trying to redirect the unauthenticated users to login page instead of showing a blank Index page.
I tried to modify app.razor to redirect as below:
<NotAuthorized>
#if (!context.User.Identity.IsAuthenticated)
{
<RedirectToLogin />
}
else
{
<p>
You are not authorized to access
this resource.
</p>
}
</NotAuthorized>
That didn't work. Breakpoint on " #if (!context.User.Identity.IsAuthenticated)" never gets hit.
I also tried to add #code section to MainLayout.razor as below:
[CascadingParameter] protected Task<AuthenticationState> AuthStat { get; set; }
protected async override Task OnInitializedAsync()
{
base.OnInitialized();
var user = (await AuthStat).User;
if (!user.Identity.IsAuthenticated)
{
navMan.NavigateTo($"authentication/login?returnUrl={Uri.EscapeDataString(navMan.Uri)}");
}
}
THat goes in some kind of redirect loop i assume because I get a error saying
"Request filtering is configured on the Web server to deny the request because the query string is too long."
and Requested URL:
https://localhost:44385/authentication/login?returnUrl=https%3A%2F%2Flocalhost%3A44385%2Fauthentication%2Flogin%3FreturnUrl%3Dhttps%253A%252F%252Flocalhost%253A44385%252Fauthentication%252Flogin%253FreturnUrl%253Dhttps%25253A%25252F%25252Flocalhost%25253A44385%25252Fauthentication%25252Flogin%25253FreturnUrl%25253Dhttps%2525253A%2525252F%2525252Flocalhost%2525253A44385%2525252Fauthentication%2525252Flogin%2525253FreturnUrl%2525253Dhttps%252525253A%252525252F%252525252Flocalhost%252525253A44385%252525252Fauthentication%252525252Flogin%252525253FreturnUrl%252525253Dhttps%25252525253A%25252525252F%25252525252Flocalhost%25252525253A44385%25252525252Fauthentication%25252525252Flogin%25252525253FreturnUrl%25252525253Dhttps%2525252525253A%2525252525252F%2525252525252Flocalhost%2525252525253A44385%2525252525252Fauthentication%2525252525252Flogin%2525252525253FreturnUrl%2525252525253Dhttps%252525252525253A%252525252525252F%252525252525252Flocalhost%252525252525253A44385%252525252525252Fauthentication%252525252525252Flogin%252525252525253FreturnUrl%252525252525253Dhttps%25252525252525253A%25252525252525252F%25252525252525252Flocalhost%25252525252525253A44385%25252525252525252Fauthentication%25252525252525252Flogin%25252525252525253FreturnUrl%25252525252525253Dhttps%2525252525252525253A%2525252525252525252F%2525252525252525252Flocalhost%2525252525252525253A44385%2525252525252525252Fauthentication%2525252525252525252Flogin%2525252525252525253FreturnUrl%2525252525252525253Dhttps%252525252525252525253A%252525252525252525252F%252525252525252525252Flocalhost%252525252525252525253A44385%252525252525252525252Fauthentication%252525252525252525252Flogin%252525252525252525253FreturnUrl%252525252525252525253Dhttps%25252525252525252525253A%25252525252525252525252F%25252525252525252525252Flocalhost%25252525252525252525253A44385%25252525252525252525252Fauthentication%25252525252525252525252Flogin%25252525252525252525253FreturnUrl%25252525252525252525253Dhttps%2525252525252525252525253A%2525252525252525252525252F%2525252525252525252525252Flocalhost%2525252525252525252525253A44385%2525252525252525252525252F
Please can someone suggest how a user can be redirected to the login page if not authenticated in Blazor Server side project with Azure B2C Authentication?
You can force the user to login with the below changes
Approach 1:
_Host.Cshtml Add the below code
#using Microsoft.AspNetCore.Authorization
#attribute [Authorize]
App.razor
<CascadingAuthenticationState>
<Router AppAssembly="#typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="#routeData" DefaultLayout="#typeof(MainLayout)">
<NotAuthorized>
<h4>Not authorized.</h4>
</NotAuthorized>
<Authorizing>
<h4>Authentication in progress...</h4>
</Authorizing>
</AuthorizeRouteView>
</Found>
<NotFound>
<LayoutView Layout="#typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
</CascadingAuthenticationState>
MainLayout.razor
#inherits LayoutComponentBase
<div class="sidebar">
<NavMenu />
</div>
<div class="main">
<AuthorizeView>
<NotAuthorized></NotAuthorized>
<Authorized>
<div class="top-row px-4 auth">
<LoginDisplay />
About
</div>
<div class="content px-4">
#Body
</div>
</Authorized>
</AuthorizeView>
</div>
Approach 2:
Another way For redirecting the user to login page Please make the below changes
_Host.Cshtml
<environment include="Staging,Production">
<component render-mode="ServerPrerendered" type="typeof(App)" />
</environment>
<environment include="Development">
<component render-mode="Server" type="typeof(App)" />
</environment>
Create RedirectToLogin.razor
#inject NavigationManager Navigation
#code {
protected override Task OnAfterRenderAsync(bool firstRender)
{
Navigation.NavigateTo("/AzureADB2C/Account/SignIn");
return base.OnAfterRenderAsync(firstRender);
}
}
MainLayout.razor
<div class="main">
<div class="top-row px-4 auth">
<LoginDisplay />
About
</div>
<div class="content px-4">
<AuthorizeView>
<Authorized>
#Body
</Authorized>
<NotAuthorized>
<Blazor_B2C.Pages.RedirectToLogin></Blazor_B2C.Pages.RedirectToLogin>
</NotAuthorized>
</AuthorizeView>
</div>
</div>

Blazor #attribute [Authorize] tag is not working

I have a working .NET Core 3.0 MVC website, using AzureAD for authentication, this all works fine. I have started to migrate some of the front-end pages to Blazor (in same project) but cannot get authentication to work.
I have added the #attribute [Authorize] tag to the top of Index.razor but I do not get redirected to Azure to login as I would do when adding it to a standard ASP.NET MVC Controller.
Startup.ConfigureServices
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
Configuration.GetSection("OpenIdConnect").Bind(options);
});
services.AddAuthorizationCore(options =>
{
options.AddPolicy(Policies.AccessRole, Policies.IsAccessPolicy());
options.AddPolicy(Policies.AdminRole, Policies.IsAdminPolicy());
});
Startup.Configure
app.UseAuthentication();
app.UseAuthorization();
Index.razor
#page "/"
#attribute [Authorize(Policy = Policies.AccessRole)]
Policies
public static class Policies
{
public const string AccessRole = "Access";
public const string AdminRole = "Admin";
public static AuthorizationPolicy IsAccessPolicy()
{
return new AuthorizationPolicyBuilder().RequireAuthenticatedUser()
.RequireRole(AccessRole)
.Build();
}
public static AuthorizationPolicy IsAdminPolicy()
{
return new AuthorizationPolicyBuilder().RequireAuthenticatedUser()
.RequireRole(AdminRole)
.Build();
}
}
If I navigate to an MVC page I get authenticated by AzureAD, if I then return to the Blazor page I can use the following successfuly
<AuthorizeView Policy="#Policies.AccessRole">
<p>Is in Access policy.</p>
</AuthorizeView>
<AuthorizeView Policy="#Policies.AdminRole">
<p>Is in Admin policy.</p>
</AuthorizeView>
So to summarise, my Blazor page is not automatically issuing the auth challenge when using the [Authorize] attribute.
Does anyone know what I am doing wrong?
Update
It's as designed
https://github.com/aspnet/AspNetCore/issues/13709
As a workaround I have added a component to redirect to a login page
App.razor
<Router AppAssembly="#typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="#routeData" DefaultLayout="#typeof(MainLayout)">
<NotAuthorized>
<AuthChallenge></AuthChallenge>
</NotAuthorized>
</AuthorizeRouteView>
</Found>
<NotFound>
<CascadingAuthenticationState>
<LayoutView Layout="#typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</CascadingAuthenticationState>
</NotFound>
</Router>
AuthCallenge.razor
#inject NavigationManager Navigation
#code {
protected override void OnInitialized()
{
Navigation.NavigateTo("/Account/SignIn", true);
}
}
Take a look at your App.razor file. Do you use RouteView or AuthorizeRouteView?
You need to define an AuthorizeRouteView as described on the "ASP.NET Core Blazor authentication and authorization" page.
<Router AppAssembly="#typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="#routeData" DefaultLayout="#typeof(MainLayout)">
<NotAuthorized>
<h1>Sorry</h1>
<p>You're not authorized to reach this page.</p>
<p>You may need to log in as a different user.</p>
</NotAuthorized>
<Authorizing>
<h1>Authentication in progress</h1>
<p>Only visible while authentication is in progress.</p>
</Authorizing>
</AuthorizeRouteView>
</Found>
<NotFound>
<CascadingAuthenticationState>
<LayoutView Layout="#typeof(MainLayout)">
<h1>Sorry</h1>
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</CascadingAuthenticationState>
</NotFound>
Seems like the AuthorizeAttribute doesn't do all that much if that component is missing.
You must use CascadingAuthenticationState as root in the XML
<CascadingAuthenticationState>
<Router AppAssembly="#typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="#routeData" DefaultLayout="#typeof(EmptyLayout)">
<NotAuthorized>
<RedirectLogin />
</NotAuthorized>
</AuthorizeRouteView>
</Found>
<NotFound>
<LayoutView Layout="#typeof(MainLayout)">
<h1>404 Error</h1>
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
</CascadingAuthenticationState>
config.AddPolicy("InAdminGroup",
Policies.InAdminGroup()
);
config.AddPolicy("InApproverGroup",
Policies.InApproverGroup()
);
config.AddPolicy("InInvestigatorGroup",
Policies.InInvestigatorGroup()
);