Access Denied query string too long - asp.net-core

I'm developing an Asp.Net Core application. I'm using built-in Identity for login, roles, authorization and authentication. I'm developing/testing/debugging with IIS Express on a Windows machine. When I'm logged in as a non-admin user and try to navigate to a url that only admins have access to (Authorize attribute on the whole controller), the application redirects to an access denied URL, but then I get an error message saying that the url query string is too long. Upon inspecting the url, it appears to have repeated sections. I'll try to paste it below. Should I report this as a bug, or can I change a setting to prevent it?
https://localhost:44383/Account/AccessDenied?ReturnUrl=%2FAccount%2FAccessDenied%3FReturnUrl%3D%252FAccount%252FAccessDenied%253FReturnUrl%253D%25252FAccount%25252FAccessDenied%25253FReturnUrl%25253D%2525252FAccount%2525252FAccessDenied%2525253FReturnUrl%2525253D%252525252FAccount%252525252FAccessDenied%252525253FReturnUrl%252525253D%25252525252FAccount%25252525252FAccessDenied%25252525253FReturnUrl%25252525253D%2525252525252FAccount%2525252525252FAccessDenied%2525252525253FReturnUrl%2525252525253D%252525252525252FAccount%252525252525252FAccessDenied%252525252525253FReturnUrl%252525252525253D%25252525252525252FAccount%25252525252525252FAccessDenied%25252525252525253FReturnUrl%25252525252525253D%2525252525252525252FAccount%2525252525252525252FAccessDenied%2525252525252525253FReturnUrl%2525252525252525253D%252525252525252525252FAccount%252525252525252525252FAccessDenied%252525252525252525253FReturnUrl%252525252525252525253D%25252525252525252525252FAccount%25252525252525252525252FAccessDenied%25252525252525252525253FReturnUrl%25252525252525252525253D%2525252525252525252525252FAccount%2525252525252525252525252FAccessDenied%2525252525252525252525253FReturnUrl%2525252525252525252525253D%252525252525252525252525252FAccount%252525252525252525252525252FAccessDenied%252525252525252525252525253FReturnUrl%252525252525252525252525253D%25252525252525252525252525252FAccount%25252525252525252525252525252FAccessDenied%25252525252525252525252525253FReturnUrl%25252525252525252525252525253D%2525252525252525252525252525252FAccount%2525252525252525252525252525252FAccessDenied%2525252525252525252525252525253FReturnUrl%2525252525252525252525252525253D%252525252525252525252525252525252FAccount%252525252525252525252525252525252FAccessDenied%252525252525252525252525252525253FReturnUrl%252525252525252525252525252525253D%25252525252525252525252525252525252FAccount%25252525252525252525252525252525252FAccessDenied%25252525252525252525252525252525253FReturnUrl%25252525252525252525252525252525253D%2525252525252525252525252525252525252FAdmin%2525252525252525252525252525252525252FEditUser%2525252525252525252525252525252525252Ff61bbba3-42b5-4831-8ff1-4d92e42d5d99

The url you received you have an endless redirection loop, where each loops adds the url again and pass to itself.
In the default ASP.NET Core Identity templates, the AccountController is attributed with [Authorize] attribute, meaning any logged in user can access it.
The fact that you get redirected when trying to access /Account/AccessDenied route/action means the logged in use doesn't have the permission to access it.
This can happen when you use a different authentication scheme [Authorize(Scheme = "SomethingElse")] or as in your case (from your last comment) when a special group is required [Authorize(Roles = "Something")].
Even if you have some valid reason to change it on controller level, you should be able to set
[HttpGet]
[Authorize]
public IActionResult AccessDenied(string returnUrl) { ... }
To make an exception to it or use
[HttpGet]
[AllowAnonymous]
public IActionResult AccessDenied(string returnUrl) { ... }
which will allow any user to access it.

Related

Forgot password in .Net Core 5.0

my login and register methods are working well and i use the Claim when the user try to login or logout.
i saw many example of that ForgotMyPassword page but all of it using
private readonly UserManager<IdentityUser> _userManager; which is based on Microsoft.AspNetCore.Identity; . Can i do ForgotMyPassword action without using UserManager
?? im asking that Claim based authentication and authorization is what i need in my project.
can i use them both,if i can how can i do that ?
it would be so great if someone explain its clearly,regards
When users register, their information will be added to the database. You can pass the registered email of the user to the ForgotMyPassword action. Then send a verification code to the mailbox or send a link to make user redirect to another page to reset the password. Make the user finish changing the password.
You can both use authentication and authorization, they are responsible for different businesses. Authentication has cookie, jwt and other authentication service. cookie authentication is the built-in component. Identity has integrated it. You should have learn about it.
The another service is authorization. Authorization service only works after authentication is successful. It has many authorization methods, about claim-based authorization, when one user access the authorized action, it will go through the middleware app.UseAuthorization(). This middleware will check whether there is a claim corresponding to the action policy's claim. Because you have configured it in startup.
services.AddAuthorization(options=>
{
options.AddPolicy("Policy1",policy=>
{
policy.RequireClaim("claim1",new string[] {"value1","value2" });
});
});
On the authorized action.
[Authorize(Policy = "Policy1")]
public IActionResult get()
{
return Ok();
}
In this scenario, the user should have the claim Claim("claim1","value1") or Claim("claim1","value2").

Role based Access to Static Content in ASP.NET CORE

Is there any way I can give access to static content based on their role. In my application, the authentication is done through Azure Active AD and the contents should be accessed based on their role e.g. employee should access all employee pages and students should access student pages. This is how my solution explorer looks like.
Solution Explorer
I know this is duplicate of Secure requests to .html files in ASP.NET Core but I couldn't find any approach to implement the solution. I have made new folder intranet outside the wwwRoot to serve my static content but still need to know how can I authorize the user and and serve role based static files.
As the document said, you could store the static files outside of wwwroot and any directory accessible to the Static File Middleware (for example: MyStaticFiles folder, like this), then, you could serve them via an action method to which authorization is applied and return a FileResult object:
[Authorize(Roles = "User")]
public IActionResult BannerImage()
{
var filePath = Path.Combine(
_env.ContentRootPath, "MyStaticFiles", "images", "Image1.jpg");
return PhysicalFile(filePath, "image/jpeg");
}
Then, you could view image by click the following link:
<a asp-action="BannerImage" asp-controller="Home">View Image</a>
[Note] After using the above method, if the authorize not working, try to clear the cache, perhaps the issue is related to the browser cache. Besides, if you meet the "HTTP Error 404.15 - Not Found" error, try to add [AllowAnonymous] attribute for other controller action method.

ASP.NET Identity redirect to full URL after login

I have a Blazor website (IdentityApp) that includes scaffolded ASP.NET identity integration. That website is processing logins and setting a shared cookie that my other localhost Blazor application (LogicApp) can see.
When I access LogicApp (https://localhost:9876), I check the context for a recognised user (using the shared cookie) and then manually redirect anonymous users to the scaffolded IdentityApp login page: https://localhost:1234/identity/account/login.
I also pass through the fully encoded URL of LogicApp home page in the returnUrl, for example; https://localhost:1234/identity/account/login?returnUrl=https%3A%2F%2Flocalhost%3A9876%2F
The login process is working OK (the shared cookie is set correctly), but then I get an exception;
InvalidOperationException: The supplied URL is not local. A URL with an absolute path is considered local if it does not have a host/authority part. URLs using virtual paths ('~/') are also local.
Within ASP.NET Identity (.NET Core 3.1);
How can I configure IdentityApp to allow full urls within returnUrl?
or,
How can I override the scaffolded Login logic to take control of the redirect and use my returnUrl value?
So I found an answer to my own problem (but still interested to hear of alternative solutions)..
Within the scaffolded pages locate Login.cshtml.cs and replace the reference to LocalRedirect(...) in in the OnPostAsync(string returnUrl = null) method, for example;
...
if (result.Succeeded)
{
_logger.LogInformation("User logged in.");
//return LocalRedirect(returnUrl); // remove this.
return Redirect(returnUrl); //TODO: define a list of acceptable return Urls (localhost / yourdomain.com etc)
}
...
You may also need to do this in Login2FA.cshtml.cs as well as other places that deal with this ReturnUrl value.
NOTE: LocalRedirect is used to prevent malicious redirects occurring so it would be wise to also add some logic to check the returnUrls that have been passed in.

Razor Pages - HTTP Error 400 (Invalid Anti Forgery Token) when idle the web site

I'm developing a web site in Blazor Server Side. My Login page is a Razor Page and everything works as expected, but if a user leaves their browser open for a period of time around 20 minutes and then performs the login they get an Http Error 400. I think it is for the Anti Forgery Token, because if you delete the cookie ".AspNetCore.Antiforgery" you got the same error. What should I do to solve this issue? What do you recommend?
If the application is being hosted in IIS I recommend setting Load User Profile = True in the application's app pool > Advanced settings menu. I had a similar issue in the past and I noticed every time the application restarted in IIS the keys were not persisted and any form opened before the restart is useless. However as soon as I changed the setting the key persisted. https://codeshorts.com/ASP-NET-Core-IIS-Invalid-Anti-Forgery-Token-Error-400
This also seems to have been an issue with Azure hosted apps
https://stackoverflow.com/a/52302702/1843966
You can try to apply IgnoreAntiforgeryToken Attribute to LoginModel class to skip antiforgery token validation, like below.
[AllowAnonymous]
[IgnoreAntiforgeryToken]
public class LoginModel : PageModel
{
//...
Note: normally, disabling antiforgery token validation is not recommended. But in this thread, applying it to LoginModel (user login functionality) should be fine.
I found this approach using code so you can catch the exception if it does fail

Prevent forms authorisation redirect in MVC when Web Api authentication fails

I'm basically a novice with Web Api, but I have finally added Web Api into an existing project and implemented a basic authorisation filter which allows me to both authenticate the user and use their identity in my apicontroller action methods.
The problem I'm having is that when the user is not successfully authenticated (their authorisation credentials are not valid) I am not able to return a 401 forbidden response as the MVC site automatically redirects to the login page and returns the html with a 302 redirect code.
I have seen fixes like:
protected void Application_EndRequest(Object sender, EventArgs e)
{
HttpApplication context = (HttpApplication)sender;
context.Response.SuppressFormsAuthenticationRedirect = true;
}
in global.asax
Which simply have not worked. Even if it had worked it would prevent the redirect for users browsing the website which I would like to keep.
Is there a way of preventing this redirect from taking place only in instances of failed authorisation with my Web Api, whilst also keeping the redirect for the main MVC site?