redirect to custom "access denied" page for ASP.NET Core - authentication

I writing an ASP.NET Core 1.0 website that uses Windows Authentication. I have implemented Authorization and that is working as expected. Currently, when Authentication fails for a given user, a generic "HTTP 403" error page is shown.
How can I configure ASP.NET Core so that it redirects to my own custom "access denied" page?
I tried the approach outlined in this article, but it didn't work for me (maybe because I'm using Windows Auth instead of Forms Auth?)
How to redirect unauthorized users with ASP.NET MVC 6
Any help would be appreciated.

Use the status code pages middleware.
app.UseStatusCodePages(async context => {
if (context.HttpContext.Response.StatusCode == 403)
{
// your redirect
}
});
You can also choose more generic approach via app.UseStatusCodePagesWithRedirects. The middleware can handle redirects (with either relative or absolute URL paths), passing the status code as part of the URL. For example the following will redirect to ~/errors/403 for 403 error:
app.UseStatusCodePagesWithRedirects("~/errors/{0}");

Related

Blazor WASM Not Redirecting to Login Page

I am new to Blazor and trying to authenticate using oidc. I am trying to use the instructions from Secure an ASP.NET Core Blazor WebAssembly standalone app to set it up.
Here is what I want the app to do (this, I think is a 'normal' app flow):
Start app
Be redirected to a login page (this login page is not within my app)
After login redirect back to app
I must be missing something simple. When I try to run the app I see this error in the Browser Console errors:
Refused to display 'https://xxxx.yyyy.com/' in a frame because it set 'X-Frame-Options' to 'deny'.
In the response headers, I see this:
X-Frame-Options: DENY
X-MS-Forwarded-Status-Code: 500
And in the request headers:
Sec-Fetch-Dest: iframe
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: cross-site
I am trying to emulate an existing, working Angular app and in that app headers, I see this in the header
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: cross-site
I'm not sure if that difference in the header is the difference or not but it's the only thing I see. Looking for advice on how to get this login flow working?
It turns out my scenario - Blazor Webassembly to ADFS is not supported. After days of banging my head, I found this: BLAZOR WASM - ADFS - OIDC - Documentation indicating this is not a supported scenario.
I then found article which pointed me in the correct direction Configure Blazor WASM with ADFS
Turns out the MSAL provider seems to work fine for this scenario:
builder.Services.AddMsalAuthentication(options => {
// Configure your authentication provider options here.
options.ProviderOptions.Authentication.Authority = "https://xxx.yyyy.com/adfs";
options.ProviderOptions.Authentication.ClientId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx";
options.ProviderOptions.Authentication.NavigateToLoginRequestUrl = true;
options.ProviderOptions.LoginMode = "redirect";
});

AXIOS url is case sensitive

I have worked on an Application that uses ASP.NET Core and VueJs. VueJs calls asp.net core controller using AXIOS. Everything is working fine. I was able to publish the site on IIS.
The problem starts when I type url of my web site in lower case.
The url of my web site is
http://10.131.XXX.XXX:94/MyWeb.
Internally axios calls the controller method on the same url.
for example internally in vue js component, I have written something like this
this.API_URL="http://10.131.XXX.XXX:94/MyWeb
axios.post(this.API_URL + '/UserManagement/GetAllUser', postData);
But if type the following url of my web site
http://10.131.XXX.XXX:94/myweb
then axios is not able to call the controller method and return status code 400 -Bad Request.
I am updating my question. because found a few more hint on issues.
[1] Bad Request error gone if I remove ValidateAntiForgeryToken attribute from asp.net core controller method.I add RequestVerificationToken in axios header. but If my request is to myweb this is not avaliable.
[2] My asp.net core controller calls Web API and I am using token authentication there. I keep token in Claim but that Claim is not available when i do request from axios to myweb instead of MyWeb.
Two things on web side using cookie based authentication and for web api using token authentication.
I FIGURE OUT THAT POST REQUEST IS FAILING FROM AXIOS JUST BECAUSE OF ANTIFORGERY TOKEN IN ASP.NET CORE. ALSO WHEN I LOGIN USING LOWERCASE WEBSITE NAME AUTHORIZE ATTRIBUTE REJECTS REQUEST.
I am setting correct token in axios
headers: {
'RequestVerificationToken': xshrfToken,
'Content-Type': 'application/json;charset=utf-8;'
}
so my question is that if I change the website name to lower case why POST request fails.
Any suggestion?
You could use axios interceptor as a hook:
axios.interceptors.request.use(function(response) {
response.url = response.url.toLowerCase();
return response;
});

MVC AntiForgeryToken cookie missing in browser before login.

Application is accessed under https:// url.
In MVC application we have added ##Html.AntiForgeryToken() on cshtml razor engine and ValidateAntiForgeryToken on controller.
It all worked fine for after login pages, but with login page it goes to application error as there was no cookie seen on browser before logging into the system.
Went through several forums, articles and even added the following piece of code in global.asax.
AntiForgeryConfig.CookieName = "CSRF";
AntiForgeryConfig.SuppressIdentityHeuristicChecks = true;
//AntiForgeryConfig.RequireSsl = true; -- only for https.
Even wrote a simple SetCookie in get method of login page, that cookie doesn't show up on browser. What could be the problem.
Why i was able to see the below in cshtml but controller doesn't accept the post with antiforgeryvalidation before login.
.
Any help would be greatly appreciated

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?

How to test Basic Authentication in an MVC.NET application using a browser

I am trying to setup basic auth on my mvc.net web application. I configured my controller using this example: asp mvc 3 ActionFilter for basic authentication
I set a breakpoint where it checks for the Authorization Header, however the header is not present in the HttpRequest. I am accessing the site like this:
http://user1:pass1#localhost/{AppName}/Client/Authorize
If I remove the [BasicAuthorization] attribute from my controller, I am able to access the page.
I am debugging this using IIS 7.0 on a Windows 7 machine.
I think it might have something to do with default authorization settings in IIS. When I throw a HttpUnauthorizedResult() exception, a username/password box pops up in Chrome... I'm not sure how to tell IIS to use my custom code to authenticate the user.
This application won't be accessible by a human user, so the username/password needs to be passed in in the URL like shown above.
I had also found this post: No browser is sending Authorization info in header. I tried sending the request twice after IIS sends the UnauthorizedRequest to the browser, but that's when the username/password dialog pops up. I'm also not sure how to test using that Curl command... Is that through CMD?
I found this post here: SimpleMembership in MVC4 app + WebApi using basic HTTP auth
I was able to refer to the test page used on this tutorial: http://kevin-junghans.blogspot.ca/2013/02/mixing-forms-authentication-basic.html to setup a simple testing page to test that basic authentication was working properly.
I'm not entirely sure on the reason, but I believe that the browser doesn't automatically add an authentication header to the HttpRequest when you try sending the credentials like so:
http://user1:pass1#localhost/{AppName}/Client/Authorize
It must have something to do with the browser requiring a 401 response from the server first before sending the authentication header. I just couldn't figure out how to do it. If anyone knows how to configure IIS/browser properly so you can easily test basic authentication using the above URL format, please let me know.