ChallengeAsync() from HttpContext does not redirect - c#

We have a javascript app "wrapped" in an ASP Core MVC Application. Each AJAX-request from the javascript app hits a controller decorated with [Authorize].
In our startup method we've defined an AuhenticationScheme pointing toward our Identity Server. And then another scheme for the cookies that they are ultimately signed in as.
To ensure that all requests coming in are authenticated we use the following:
app.Use(async (context, next) =>
{
if (!context.User.Identity.IsAuthenticated)
{
string auth = context.Request.Headers["Authorization"];
if (string.IsNullOrEmpty(auth) || !auth.StartsWith("Bearer ", System.StringComparison.OrdinalIgnoreCase))
{
await context.ChallengeAsync("oidce", new AuthenticationProperties {
RedirectUri = "/"
});
}
else
{
await next();
}
}
else
{
await next();
}
});
Now if the cookie expires it triggers the "ChallengeAsync" - that doesn't really work if the call originated from an AJAX request made from the browser. I thought since I had the context here that it would simply override the AJAX and make the browser start the round-trip.
Is there a way to say to the browser that "no, this isn't an AJAX-response, go where I tell you to"?

As Tseng pointed out in the comments I implemented almost to the letter.
app.Use(async (context, next) =>
{
if (!context.User.Identity.IsAuthenticated)
{
if (context.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
// webapp will then do a location.reload() which triggers the auth
context.Response.StatusCode = 401;
}
else
{
string auth = context.Request.Headers["Authorization"];
if (string.IsNullOrEmpty(auth) || !auth.StartsWith("Bearer ", System.StringComparison.OrdinalIgnoreCase))
{
await context.ChallengeAsync();
}
else
{
await next();
}
}
}
else
{
await next();
}
});
The javascript application then catches the Ajax exception and checks if the status is 401 and simply does window.location.reload()
Not an elegant solution, will probably rewrite in the future but it solves the immediate problem.

Related

Net Core MVC Middleware does not work after publish

app.Use((context, next) => {
// Ignore requests that don't point to static files.
if (context.Request.Path.StartsWithSegments("/Cvler"))
{
if (context.User.Identities.Any(identity => identity.HasClaim("pozisyon", "admin")))
{
return next();
}
context.Response.StatusCode = 401;
return Task.FromResult(0);
}
return next();
// Stop processing the request and return a 401 response.
});
Hi all, i want to hide CV folder from everyone except admin while development mode its working after publish middleware does not work everyone can see folder
problem was i write app.usestaticfiles before middleware app.use

Middleware is not properly handling 403, but is properly handling 404

I am trying to build in some custom handling of different error codes, and yet I seem to be having difficulties for my 403 codes. The code is identical between the 404 and 403s, and yet the 404 works correctly, and the 403 does not.
Here is my code:
app.Use(async (context, next) =>
{
await next();
if (context.Response.StatusCode == 404)
{
context.Request.Path = "/Home/Error404";
await next.Invoke();
}
else if(context.Response.StatusCode == 401)
{
string referer = context.Request.Headers["Referer"].ToString();
if (String.IsNullOrWhiteSpace(referer))
{
referer = context.Request.Path;
}
context.Response.Redirect($"/Home/Login?returnUrl={referer}");
}
else if (context.Response.StatusCode == 403)
{
context.Request.Path = "/Home/Error403";
await next.Invoke();
//context.Response.Redirect("/Home/Error403");
}
});
I've verified with breakpoints that the 403 code is triggering, and the code in my home controller is quite simple:
[Route("/Home/Error403")]
public IActionResult Error403()
{
return View("~/Views/Shared/Error403.cshtml");
}
[Route("/Home/Error404")]
public IActionResult Error404()
{
return View("~/Views/Shared/Error404.cshtml");
}
For some reason Error404 gets called but not Error403. My 401 code redirects correctly as well. I just have no idea why it's not working here. I did try a redirect for the 403, and that worked, but it's less than ideal.
Where in your OWIN pipeline is this middleware happening?
If you declare this handler before you declare your Authentication handlers, then you will never have a 403 to handle.
Define this handler after you have declared and configured the Authentication middleware, and it can respond to the 403 status that it will set.

How can I stop a request in Ocelot's PreAuthenticationMiddleware?

I have to do some checks on the request's jwt before ocelot authentication, so I'm doing them within the PreAuthenticationMiddleware like this:
var config = new OcelotPipelineConfiguration
{
PreAuthenticationMiddleware = async (ctx, next) =>
{
var jwt = ctx.HttpContext.Request.Headers["Authorization"];
if (jwtIsOk(jwt)) next.Invoke();
// else ...
}
};
app.UseOcelot(config).Wait();
Instead of not-invoking next, is it possible to return a custom response?
I'd like to return a 401 error
I think this is what you are looking for :
var configuration = new OcelotPipelineConfiguration
{
PreAuthenticationMiddleware = async (ctx, next) =>
{
if (xxxxxx)
{
ctx.Errors.Add(new UnauthenticatedError("Your message"));
return;
}
await next.Invoke();
}
};
In this case I'm using UnauthenticatedError(an Ocelot's class), it will ends with 401. There are more like this. You can also create your own one inheriting from Ocelot.Errors.Error.

In MVC6 how can I block direct access to a folder in wwwroot?

We're developing an application in the latest MVC framework and everything so far has been great. In our application we have decided to embed an angular application in the project under wwwroot/app. I created an app controller and view and prohibited access to the app unless users are authorized. This works great when unauthorized users try to go to localhost/app - it kicks them back to the C# application login page.
I want to take it a step further and also prohibit access to direct files in that folder such as localhost/app/scripts/controllers/name.js or partial html files /app/partials/name-partial.html. In the past I would go into web.config and add the following code but I haven't found the equivalent for the latest framework. Ideally I'd like this to be an entry in startup.cs or appsettings.json if possible
<location path="app">
<system.web>
<authorization>
<allow roles="User" />
<deny roles="*" />
</authorization>
</system.web>
</location>
After additional research, it seems that the easiest way to accomplish what you want is to actually use the OnPrepareResponse StaticFileOption while configuring UseStaticFiles.
The following would be placed inside of Startup.cs:
public void Configure(IApplicationBuilder app, IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
app.UseStaticFiles(new StaticFileOptions()
{
OnPrepareResponse = s =>
{
if (s.Context.Request.Path.StartsWithSegments(new PathString("/app")) &&
!s.Context.User.Identity.IsAuthenticated)
{
s.Context.Response.StatusCode = 401;
s.Context.Response.Body = Stream.Null;
s.Context.Response.ContentLength = 0;
}
}
});
}
The above code will ONLY be run when executing a static file WITHIN wwwroot and specifically within any path that starts with the "/app" segment. If not authenticated, it rewrites the response so that the normal content is not delivered to the client, along with an appropriate status code.
Here's a sightly different approach, that uses an inline middleware to block unauthenticated requests for specific paths:
app.Use((context, next) => {
// Ignore requests that don't point to static files.
if (!context.Request.Path.StartsWithSegments("/app")) {
return next();
}
// Don't return a 401 response if the user is already authenticated.
if (context.User.Identities.Any(identity => identity.IsAuthenticated)) {
return next();
}
// Stop processing the request and return a 401 response.
context.Response.StatusCode = 401;
return Task.FromResult(0);
});
Make sure to register it after your authentication middleware (or context.User won't be populated) and before the other middleware (in your case, before the static files middleware). You'll also have to make sure you're using automatic authentication (AutomaticAuthenticate = true). If not, you'll have to use the authentication API:
app.Use(async (context, next) => {
// Ignore requests that don't point to static files.
if (!context.Request.Path.StartsWithSegments("/app")) {
await next();
return;
}
// Don't return a 401 response if the user is already authenticated.
var principal = await context.Authentication.AuthenticateAsync("Cookies");
if (principal != null && principal.Identities.Any(identity => identity.IsAuthenticated)) {
await next();
return;
}
// Stop processing the request and trigger a challenge.
await context.Authentication.ChallengeAsync("Cookies");
});
Note: if you want to prevent the cookies middleware from replacing the 401 response by a 302 redirect, here's how you can do:
When using Identity (in ConfigureServices):
services.AddIdentity<ApplicationUser, IdentityRole>(options => {
options.Cookies.ApplicationCookie.Events = new CookieAuthenticationEvents {
OnValidatePrincipal = options.Cookies.ApplicationCookie.Events.ValidatePrincipal,
OnRedirectToLogin = context => {
// When the request doesn't correspond to a static files path,
// simply apply a 302 status code to redirect the user agent.
if (!context.Request.Path.StartsWithSegments("/app")) {
context.Response.Redirect(context.RedirectUri);
}
return Task.FromResult(0);
}
};
});
When using the cookies middleware without Identity (in Configure):
app.UseCookieAuthentication(options => {
options.Events = new CookieAuthenticationEvents {
OnRedirectToLogin = context => {
// When the request doesn't correspond to a static files path,
// simply apply a 302 status code to redirect the user agent.
if (!context.Request.Path.StartsWithSegments("/app")) {
context.Response.Redirect(context.RedirectUri);
}
return Task.FromResult(0);
}
};
});
For Prevent user from direct access to a folder, Please try this code
<security>
<requestFiltering>
<hiddenSegments>
<add segment="folderName"/>
</hiddenSegments>
</requestFiltering>
</security>

Unauthorised webapi call returning login page rather than 401

How do I configure my mvc/webapi project so that a webapi method called from a razor view doesn't return the loginpage when its unauthorised?
Its a MVC5 application which also has WebApi controllers for calls via javascript.
The two methods below
[Route("api/home/LatestProblems")]
[HttpGet()]
public List<vmLatestProblems> LatestProblems()
{
// Something here
}
[Route("api/home/myLatestProblems")]
[HttpGet()]
[Authorize(Roles = "Member")]
public List<vmLatestProblems> mylatestproblems()
{
// Something there
}
are called via the following angular code:
angular.module('appWorship').controller('latest',
['$scope', '$http', function ($scope,$http) {
var urlBase = baseurl + '/api/home/LatestProblems';
$http.get(urlBase).success(function (data) {
$scope.data = data;
}).error(function (data) {
console.log(data);
});
$http.get(baseurl + '/api/home/mylatestproblems')
.success(function (data) {
$scope.data2 = data;
}).error(function (data) {
console.log(data);
});
}]
);
So I'm not logged in and the first method successfully returns data. the second method returns (in the success function) data which contains the equivalent of a login page. i.e. what you would get in mvc if you requested a controller action which was stamped with [Authorize] and you weren't logged in.
I want it to return a 401 unauthorized, so that i can display different data for users based on if they are logged in or not. Ideally if the user is logged in i want to be able to access the Controller's User property so i can return data specific to that Member.
UPDATE: Since none of the suggestions below seem to work anymore (changes to Identity or WebAPI) ive created a raw example on github which should illustrate the problem.
Brock Allen has a nice blog post on how to return 401 for ajax calls when using Cookie authentication and OWIN.
http://brockallen.com/2013/10/27/using-cookie-authentication-middleware-with-web-api-and-401-response-codes/
Put this in ConfigureAuth method in the Startup.Auth.cs file:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
OnApplyRedirect = ctx =>
{
if (!IsAjaxRequest(ctx.Request))
{
ctx.Response.Redirect(ctx.RedirectUri);
}
}
}
});
private static bool IsAjaxRequest(IOwinRequest request)
{
IReadableStringCollection query = request.Query;
if ((query != null) && (query["X-Requested-With"] == "XMLHttpRequest"))
{
return true;
}
IHeaderDictionary headers = request.Headers;
return ((headers != null) && (headers["X-Requested-With"] == "XMLHttpRequest"));
}
If you are adding asp.net WebApi inside asp.net MVC web site you probably want to respond unauthorized to some requests. But then ASP.NET infrastructure come into play and when you try to set response status code to HttpStatusCode.Unauthorized you will get 302 redirect to login page.
If you are using asp.net identity and owin based authentication here a code that can help to solve that issue:
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider()
{
OnApplyRedirect = ctx =>
{
if (!IsApiRequest(ctx.Request))
{
ctx.Response.Redirect(ctx.RedirectUri);
}
}
}
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
}
private static bool IsApiRequest(IOwinRequest request)
{
string apiPath = VirtualPathUtility.ToAbsolute("~/api/");
return request.Uri.LocalPath.StartsWith(apiPath);
}
There are two AuthorizeAttribute implementations and you need to make sure you are referencing the correct one for Web API's. There is System.Web.Http.AuthorizeAttribute which is used for Web API's, and System.Web.Mvc.AuthorizeAttribute which is used for controllers with views. Http.AuthorizeAttribute will return a 401 error if authorization fails and Mvc.AuthorizeAttribute will redirect to the login page.
Updated 11/26/2013
So it appears things have drastically changed with MVC 5 as Brock Allen pointed out in his article. I guess the OWIN pipeline takes over and introduces some new behavior. Now when the user is not authorized a status of 200 is returned with the following information in the HTTP header.
X-Responded-JSON: {"status":401,"headers":{"location":"http:\/\/localhost:59540\/Account\/Login?ReturnUrl=%2Fapi%2FTestBasic"}}
You could change your logic on the client side to check this information in the header to determine how to handle this, instead of looking for a 401 status on the error branch.
I tried to override this behavior in a custom AuthorizeAttribute by setting the status in the response in the OnAuthorization and HandleUnauthorizedRequest methods.
actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
But this did not work. The new pipeline must grab this response later and modify it to the same response I was getting before. Throwing an HttpException did not work either as it is just changed into a 500 error status.
I tested Brock Allen's solution and it did work when I was using a jQuery ajax call. If it is not working for you my guess is that it is because you are using angular. Run your test with Fiddler and see if the following is in your header.
X-Requested-With: XMLHttpRequest
If it is not then that is the problem. I am not familiar with angular but if it lets you insert your own header values then add this to your ajax requests and it will probably start working.
I got the same situation when OWIN always redirects 401 response to Login page from WebApi.Our Web API supports not only ajax calls from Angular but also Mobile, Win Form calls. Therefore, the solution to check whether the request is ajax request is not really sorted for our case.
I have opted another approach is to inject new header response: Suppress-Redirect if responses come from webApi. The implementation is on handler:
public class SuppressRedirectHandler : DelegatingHandler
{
/// <summary>
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return base.SendAsync(request, cancellationToken).ContinueWith(task =>
{
var response = task.Result;
response.Headers.Add("Suppress-Redirect", "True");
return response;
}, cancellationToken);
}
}
And register this handler in global level of WebApi:
config.MessageHandlers.Add(new SuppressRedirectHandler());
So, on OWIN startup you are able to check whether response header has Suppress-Redirect:
public void Configuration(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
AuthenticationType = DefaultApplicationTypes.ApplicationCookie,
ExpireTimeSpan = TimeSpan.FromMinutes(48),
LoginPath = new PathString("/NewAccount/LogOn"),
Provider = new CookieAuthenticationProvider()
{
OnApplyRedirect = ctx =>
{
var response = ctx.Response;
if (!IsApiResponse(ctx.Response))
{
response.Redirect(ctx.RedirectUri);
}
}
}
});
}
private static bool IsApiResponse(IOwinResponse response)
{
var responseHeader = response.Headers;
if (responseHeader == null)
return false;
if (!responseHeader.ContainsKey("Suppress-Redirect"))
return false;
if (!bool.TryParse(responseHeader["Suppress-Redirect"], out bool suppressRedirect))
return false;
return suppressRedirect;
}
In previous versions of ASP.NET, you had to do a whole bunch of stuff to get this working.
The good news is, since you are using ASP.NET 4.5. you can disable forms authentication redirect using the new HttpResponse.SuppressFormsAuthenticationRedirect property.
In Global.asax:
protected void Application_EndRequest(Object sender, EventArgs e)
{
HttpApplication context = (HttpApplication)sender;
context.Response.SuppressFormsAuthenticationRedirect = true;
}
EDIT: You might also want to take a look at this article by Sergey Zwezdin which has a more refined way of accomplishing what you are trying to do.
Relevant code snippets and author narration pasted below. Original Author of code and narration -- Sergey Zwezdin.
First – let’s determine whether current HTTP-request is AJAX-request. If yes, we should disable replacing HTTP 401 with HTTP 302:
public class ApplicationAuthorizeAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
var httpContext = filterContext.HttpContext;
var request = httpContext.Request;
var response = httpContext.Response;
if (request.IsAjaxRequest())
response.SuppressFormsAuthenticationRedirect = true;
base.HandleUnauthorizedRequest(filterContext);
}
}
Second – let’s add a condition:: if user authenticated, then we will send HTTP 403; and HTTP 401 otherwise.
public class ApplicationAuthorizeAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
var httpContext = filterContext.HttpContext;
var request = httpContext.Request;
var response = httpContext.Response;
var user = httpContext.User;
if (request.IsAjaxRequest())
{
if (user.Identity.IsAuthenticated == false)
response.StatusCode = (int)HttpStatusCode.Unauthorized;
else
response.StatusCode = (int)HttpStatusCode.Forbidden;
response.SuppressFormsAuthenticationRedirect = true;
response.End();
}
base.HandleUnauthorizedRequest(filterContext);
}
}
Well done. Now we should replace all usings of standard AuthorizeAttribute with this new filter. It may be not applicable for sime guys, who is aesthete of code. But I don’t know any other way. If you have, let’s go to comments, please.
The last, what we should to do – to add HTTP 401/403 handling on a client-side. We can use ajaxError at jQuery to avoid code duplication:
$(document).ajaxError(function (e, xhr) {
if (xhr.status == 401)
window.location = "/Account/Login";
else if (xhr.status == 403)
alert("You have no enough permissions to request this resource.");
});
The result –
If user is not authenticated, then he will be redirected to a login
page after any AJAX-call.
If user is authenticated, but have no enough permissions, then he will see user-friendly erorr message.
If user is authenticated and have enough permissions, the there is no any errors and HTTP-request will be proceeded as usual.
Using Azure Active Directory integration myself, the approach using the CookieAuthentication middleware didn't work for me. I had to do the following:
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
...
Notifications = new OpenIdConnectAuthenticationNotifications
{
...
RedirectToIdentityProvider = async context =>
{
if (!context.Request.Accept.Contains("html"))
{
context.HandleResponse();
}
},
...
}
});
If the request comes from the browser itself (and not an AJAX call, for instance) then the Accept header will contain the string html in it somewhere. Only when the client accepts HTML I will consider a redirect something useful.
My client application can handle the 401 informing the user that the app has no more access and needs to reload to login again.
If you are running your Web API from within your MVC project, you'll need to create a custom AuthorizeAttribute to apply to your API methods. Within the IsAuthorized override you need to grab the current HttpContext in order prevent the redirection, like this:
protected override bool IsAuthorized(HttpActionContext actionContext)
{
if (string.IsNullOrWhiteSpace(Thread.CurrentPrincipal.Identity.Name))
{
var response = HttpContext.Current.Response;
response.SuppressFormsAuthenticationRedirect = true;
response.StatusCode = (int)System.Net.HttpStatusCode.Forbidden;
response.End();
}
return base.IsAuthorized(actionContext);
}
I also had an MVC5 application (System.Web) with WebApi (using OWIN) and just wanted to prevent 401 responses from WebApi being changed to 302 responses.
What worked for me was to create a customised version of the WebApi AuthorizeAttribute like this:
public class MyAuthorizeAttribute : System.Web.Http.AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
{
base.HandleUnauthorizedRequest(actionContext);
HttpContext.Current.Response.SuppressFormsAuthenticationRedirect = true;
}
}
And to use it in place of the standard WebApi AuthorizeAttribute. I used the standard MVC AuthorizeAttribute to keep the MVC behaviour unchanged.
Just install following NeGet Package
Install-Package Microsoft.AspNet.WebApi.Owin
Write following code in WebApiConfig file.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//Web API configuration and services
//Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("multipart/form-data"));
}
}
Mixing MVC and WebAPI, if the request is unauthorized then it will redirect to login page even in WebAPI request also. For that, we can add below code to send a response to mobile application
protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
{
var httpContext = HttpContext.Current;
if (httpContext == null)
{
base.HandleUnauthorizedRequest(actionContext);
return;
}
actionContext.Response = httpContext.User.Identity.IsAuthenticated == false ?
actionContext.Request.CreateErrorResponse(
System.Net.HttpStatusCode.Unauthorized, "Unauthorized") :
actionContext.Request.CreateErrorResponse(
System.Net.HttpStatusCode.Forbidden, "Forbidden");
httpContext.Response.SuppressFormsAuthenticationRedirect = true;
httpContext.Response.End();
}
if you want to catch Content-Type == application/json you can use that code:
private static bool IsAjaxRequest(IOwinRequest request)
{
IReadableStringCollection queryXML = request.Query;
if ((queryXML != null) && (queryXML["X-Requested-With"] == "XMLHttpRequest"))
{
return true;
}
IReadableStringCollection queryJSON = request.Query;
if ((queryJSON != null) && (queryJSON["Content-Type"] == "application/json"))
{
return true;
}
IHeaderDictionary headersXML = request.Headers;
var isAjax = ((headersXML != null) && (headersXML["X-Requested-With"] == "XMLHttpRequest"));
IHeaderDictionary headers = request.Headers;
var isJson = ((headers != null) && (headers["Content-Type"] == "application/json"));
return isAjax || isJson;
}
regards!!
I was having a hard time getting both the status code and a text response working in the OnAuthorization/HandleUnauthorizedRequest methods. This turned out to be the best solution for me:
actionContext.Response = new HttpResponseMessage()
{
StatusCode = HttpStatusCode.Forbidden,
Content = new StringContent(unauthorizedMessage)
};
Thanks guys!
In my case, I combined cuongle & Shiva 's answers, and got something like this:
In Controller's OnException() handler for API Exceptions:
filterContext.ExceptionHandled = true;
//...
var response = filterContext.HttpContext.Response;
response.Headers.Add("Suppress-Redirect", "true");
response.SuppressFormsAuthenticationRedirect = true;
In App startup config code:
app.UseCookieAuthentication(new CookieAuthenticationOptions {
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider {
OnValidateIdentity = ctx => {
return validateFn.Invoke(ctx);
},
OnApplyRedirect = ctx =>
{
bool enableRedir = true;
if (ctx.Response != null)
{
string respType = ctx.Response.ContentType;
string suppress = ctx.Response.Headers["Suppress-Redirect"];
if (respType != null)
{
Regex rx = new Regex("^application\\/json(;(.*))?$",
RegexOptions.IgnoreCase);
if (rx.IsMatch(respType))
{
enableRedir = false;
}
}
if ((!String.IsNullOrEmpty(suppress)) && (Boolean.Parse(suppress)))
{
enableRedir = false;
}
}
if (enableRedir)
{
ctx.Response.Redirect(ctx.RedirectUri);
}
}
}
});
After much fuss trying to avoid the redirections to the login page, I realised that this is actually quite appropriate for the Authorise attribute. It is saying go and get Authorisation. Instead for Api calls which are not authorised, I just wanted not to reveal any information to would be hackers.
This objective was easier to achieve directly by adding a new attribute derived off Authorize which instead hides the content as a 404 error:
public class HideFromAnonymousUsersAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
{
actionContext.Response = ActionContext.Request.CreateErrorResponse(HttpStatusCode.NotFound, "Access Restricted");
}
}
In MVC 5 with Dot Net Framework 4.5.2 we are getting
"application/json, plaint text.." under "Accept" header
It will be nice to use like following:
isJson = headers["Content-Type"] == "application/json" || headers["Accept"].IndexOf("application/json", System.StringComparison.CurrentCultureIgnoreCase) >= 0;

Categories

Resources