Not sure why you write ASP.Net Identity 4
. You probably mean Asp.Net Core Identity, right ?
I'm alright with adding an @attribute[Authorize] to each razor page if that's what it takes
But you already have @attribute[Authorize]in the _Imports.razor file, which makes adding this directive to each razor file unnecessary.
I'm not sure I understand the issue. If your _Imports.razor file contains @attribute[Authorize], then unauthorized user is automatically redirected to the login page...
The RedirectToLogin component should only contain code to perform the redirection. It should not contain code to verify if the user is authenticated or not. Code that redirect to the RedirectToLogin component should contain the code that performs this checking. In your case, from AuthorizeRouteView.NotAuthorized
Here's how your code should look like:
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
<NotAuthorized>
@if (!context.User.Identity.IsAuthenticated)
{
var returnUrl =
NavigationManager.ToBaseRelativePath(NavigationManager.Uri);
<RedirectToLogin ReturnUrl="@returnUrl" />
}
else
{
<p>You are not authorized to access this resource.</p>
}
</NotAuthorized>
</AuthorizeRouteView>
Note that when the user is <NotAuthorized>
, we check whether he's authenticated or not, if he's not authenticated, we render the RedirectToLogin
component whose code is :
@inject NavigationManager NavigationManager
@code{
[Parameter]
public string ReturnUrl { get; set; }
protected override void OnInitialized()
{
ReturnUrl = "~/" + ReturnUrl;
NavigationManager.NavigateTo($"Identity/Account/Login?returnUrl=
{ReturnUrl}", forceLoad:true);
}
}
However, if the user is authenticated, we display the message:
You are not authorized to access this resource.
As you may realize by now, a user may be authenticated and still not authorized to access a given resource.
The following is the complete code that should be in your App.razor file
@inject NavigationManager NavigationManager
<CascadingAuthenticationState>
<Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
<NotAuthorized>
@if (!context.User.Identity.IsAuthenticated)
{
var returnUrl =
NavigationManager.ToBaseRelativePath(NavigationManager.Uri);
<RedirectToLogin ReturnUrl="@returnUrl" />
}
else
{
<p>You are not authorized to access this resource.
</p>
}
</NotAuthorized>
</AuthorizeRouteView>
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
</CascadingAuthenticationState>
Note that the CascadingAuthenticationState
should be used once only, and not as you did.