Enable CORS for ASP API Token request - asp.net-mvc

I have a project that has both an API and an Area that contains some web forms.
Recently the Token endpoint of the API started throwing CORS errors and I can't figure out why or how to fix it.
I've updated the Startup.Auth.cs file with:app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
Also tried adding config.EnableCors(new EnableCorsAttribute("*", "*", "GET,POST")); to the WebApiConfig.cs file.
Neither of these have added the 'Access-Control-Allow-Origin' header that is needed. (I do get a different error if both of these are implemented at the same time, so I know that is not the issue.)
Is there another location in the project that I need to set to allow CORS requests for an auth token?

I had to this in ApplicationOAuthProvider.cs/GrantResourceOwnerCredentials to work. The first three lines are for reference point only, "context.OwinContext" line was added to make it work.
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);
**context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "http://localhost:24589" });**
Use above if you want to individually configure and allow CORS at different access points. If you want to allow application wide then you may modify ApplicationOAuthProvider.cs/ConfigureAuth like below. Either approach works.
public void ConfigureAuth(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);

Okay, found the problem(s).
First, my test harness was pointing at the wrong location so any changes I was making were having no effect and my break points were not being hit. My bad.
Second, the configuration that finally got me working is to have the following code:
ApplicationOAuthProvider.GrantResourceOwnerCredentials:
var allowedOrigin = context.OwinContext.Get<string>("as:clientAllowedOrigin");
if (allowedOrigin == null) allowedOrigin = "*";
WebApiConfig.Register:
config.EnableCors(new EnableCorsAttribute("*", "*", "GET,POST"));
I hope this helps anyone else that is struggling with CORS and Katana/OWIN middleware.

After enable CORS in WebApiConfig.cs , you should also config the web.config to also enable CORS . It's work in my application :
<system.webServer>
<!--Enbale CORS-->
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="http://yourwebsite" />
</customHeaders>
</httpProtocol>
<modules>
...
</modules>
</system.webServer>

I also struggled and spent around 5 hours, finally I got the solution.
Technology : Asp.net Framework
solution: need to install "Microsoft.Owin.Cors"
And Add the below line into "Startup.Auth.cs/ConfigureAuth()" method
app.UseCors(CorsOptions.AllowAll);
we don't want to add anything in any where, this is sufficient and it is working fine for me.
I got the answer from here: Getting token from web API2 from Angular2 leads to CORS issues or null

Related

CORS is not working in ASP.NET MVC older version But working in WebAPI2 [duplicate]

I need to enable CORS for my Web API and I can't upgrade to Framework 4.5.
I've tried to add the following to my Web.config to see if it worked, but it didn't:
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Accept,Content-Type,X-Requested-With"/>
I am accessing the URL http://localhost:8484/api/values/ from ajax call
and getting bellow error
XMLHttpRequest cannot load http://localhost:8484/api/values. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 405.
I found this simple solution by charanjit singh.
It worked nicely especially if you are stuck with older visual studio 2010 , on .Net 4.0 and of course web api 1.
Basically add this function to your Global.asax.cs
protected void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers",
"Content-Type, Accept");
HttpContext.Current.Response.End();
}
}
ref. links: note you must scroll to the bottom comments for the answer.
http://www.codeguru.com/csharp/.net/net_asp/using-cross-origin-resource-sharing-cors-in-asp.net-web-api.html
Web API 1.0, you need to enable CORS support using the following statements in the Application_BeginRequest event handler of the Global.asax.cs file.
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", allowedOrigin);
Support for CORS can be enabled at three levels. These include the following:
Action level
Controller level
Global level
refer link

Is it possible to edit the custom Content-Security-Policy header set by IIS / web.config?

I am wondering if it's possible to modify the Content-Security-Policy header that is set under <customHeaders> within web.config.
I would like to inject a nonce value if possible. I am currently doing this but I need to remove the header from web.config entirely and add it via Application_BeginRequest()
I have poked around global.asax to grab the header. It doesn't seem exist at this point in the pipe line. I can only assume it is injected later on?
<customHeaders>
<add name="Content-Security-Policy" value="myCsp nonce-{injectMe}" />
</customHeaders>
// would like to do something akin to this:
protected void Application_BeginRequest()
{
var nonce = 'myNonce';
Response.Headers["Content-Security.Policy"] =
Response.Headers["Content-Security.Policy"].Replace("{injectMe}", nonce);
}
The goal being to keep the CSP within web.config and not having to rebuild when changing it.
Is this possible at all?
I believe what you're looking for is Context.Response.Headers["Content-Security.Policy"].Replace("{injectMe}", nonce);
This should grab the current Context of the request being initiated, if I'm correct.

ADFS with existing ASP.Net MVC App

I've been looking around, trying to find an example of how to add ADFS authentication to an existing ASP.Net MVC application. I found lots of example of how to do it using the wizard when you create a new app.
I could create a new app and copy the code and config over, but this seams like a strange approach.
Does anyone know of a good guide or resource?
We found this blog entry on Cloud Identity to be really helpful to get started with something similar. We are using Web API so it's not exactly the same.
You will need to add this to your Startup.Auth.cs file:
app.UseActiveDirectoryFederationServicesBearerAuthentication(
new ActiveDirectoryFederationServicesBearerAuthenticationOptions
{
Audience = ConfigurationManager.AppSettings["ida:Audience"],
MetadataEndpoint = ConfigurationManager.AppSettings["ida:MetadataEndpoint"]
});
In your web.config you will need keys to point to those entries:
<add key="ida:AdfsMetadataEndpoint" value="https://adfs.yourdomain.com/federationmetadata/2007-06/federationmetadata.xml" />
<add key="ida:Audience" value="https://yourmvc.yourdomain.com" />
Note that what version of ADFS you are using makes a big difference. We found that while trying to get tokens to work with version 3.0 of ADFS they are somewhat broken at the moment. On premises ADFS will also work much differently than Azure.
We needed to customize the claims for our implementation and this post helped immensely. Startup.Auth.cs will look similar to this:
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Audience = ConfigurationManager.AppSettings["ida:Audience"],
Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
Provider = new OAuthBearerAuthenticationProvider()
{
OnValidateIdentity = async context =>
{
context.Ticket.Identity.AddClaim(
new Claim(http://mycustomclaims/hairlenght,
RetrieveHairLenght(userID),
ClaimValueTypes.Double,
"LOCAL AUTHORITY");));
}
}
});

How can I add “X-Content-Type-Options: nosniff” to all the response headers

I am running an ASP.NET MVC 3 website on IIS. Is there a flag in web.config or something similar that can do this?
As long as you're using IIS 7 or above, it's as simple as adding it to your web.config.
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="X-Content-Type-Options" value="nosniff" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
Or you can add them using the IIS Management GUI, or even command line. Take a look at http://www.iis.net/configreference/system.webserver/httpprotocol/customheaders
This question originates from MVC 3, but as this problem is still relevant in ASP.NET Core, I'll let myself propose a solution for the recent versions:
public static IApplicationBuilder UseNoSniffHeaders(this IApplicationBuilder builder)
{
return builder.Use(async (context, next) =>
{
context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
await next();
});
}
Then simply add this in Startup.cs:
app.UseNoSniffHeaders();
The beauty of this approach is that it makes it independent from your web server and deployment process. At the same time you may need to extend this solution if you want it to apply to static files as well.
In case whenever you deploy new application and its replacing the web.config file. its better to add the configuration IIS site level as below.
Click on site and select the 'HTTP response headers".
Click on 'add' on left side corner and add the name and value as below.
name: X-Content-Type-Options
value: nosniff
The nosniff response header is a way to keep a website more secure. Security researcher Scott Helme describes it like this: “It prevents Google Chrome and Internet Explorer from trying to mime-sniff the content-type of a response away from the one being declared by the server.

All ASP.NET Web API controllers return 404

I'm trying to get an API Controller to work inside an ASP.NET MVC 4 web app. However, every request results in a 404 and I'm stumped. :/
I have the standard API controller route from the project template defined like:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
The registration is invoked in Global.asax:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
// Register API routes
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
I have a basic API controller like this:
namespace Website.Controllers
{
public class FavoritesController : ApiController
{
// GET api/<controller>
public IEnumerable<string> Get()
{
return new [] { "first", "second" };
}
// PUT api/<controller>/5
public void Put(int id)
{
}
// DELETE api/<controller>/5
public void Delete(int id)
{
}
}
}
Now, when I browse to localhost:59900/api/Favorites I expect the Get method to be invoked, but instead I get a 404 status code and the following response:
<Error>
<Message>
No HTTP resource was found that matches the request URI 'http://localhost:59900/api/Favorites'.
</Message>
<MessageDetail>
No type was found that matches the controller named 'Favorites'.
</MessageDetail>
</Error>
Any help would be greatly appreciated, I'm losing my mind a little bit over here. :) Thanks!
One thing I ran into was having my configurations registered in the wrong order in my GLobal.asax file for instance:
Right Order:
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
Wrong Order:
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
WebApiConfig.Register(GlobalConfiguration.Configuration);
Just saying, this was my problem and changing the order is obvious, but sometimes overlooked and can cause much frustration.
Had essentially the same problem, solved in my case by adding:
<modules runAllManagedModulesForAllRequests="true" />
to the
<system.webServer>
</system.webServer>
section of web.config
I have been working on a problem similar to this and it took me ages to find the problem. It is not the solution for this particular post, but hopefully adding this will save someone some time trying to find the issue when they are searching for why they might be getting a 404 error for their controller.
Basically, I had spelt "Controller" wrong at the end of my class name. Simple as that!
Add following line
GlobalConfiguration.Configure(WebApiConfig.Register);
in Application_Start() function in Global.ascx.cs file.
I had the same problem, then I found out that I had duplicate api controller class names in other project and despite the fact that the "routePrefix" and namespace and project name were different but still they returned 404, I changed the class names and it worked.
Similar problem with an embarrassingly simple solution - make sure your API methods are public. Leaving off any method access modifier will return an HTTP 404 too.
Will return 404:
List<CustomerInvitation> GetInvitations(){
Will execute as expected:
public List<CustomerInvitation> GetInvitations(){
For reasons that aren't clear to me I had declared all of my Methods / Actions as static - apparently if you do this it doesn't work. So just drop the static off
[AllowAnonymous]
[Route()]
public static HttpResponseMessage Get()
{
return new HttpResponseMessage(System.Net.HttpStatusCode.OK);
}
Became:-
[AllowAnonymous]
[Route()]
public HttpResponseMessage Get()
{
return new HttpResponseMessage(System.Net.HttpStatusCode.OK);
}
Create a Route attribute for your method.
example
[Route("api/Get")]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
You can call like these http://localhost/api/Get
Had this problem. Had to uncheck Precompile during publishing.
I'm a bit stumped, not sure if this was due to an HTTP output caching issue.
Anyways, "all of a sudden it started working properly". :/ So, the example above worked without me adding or changing anything.
Guess the code just had to sit and cook overnight... :)
Thanks for helping, guys!
I'm going to add my solution here because I personally hate the ones which edit the web.config without explaining what is going on.
For me it was how the default Handler Mappings are set in IIS. To check this...
Open IIS Manager
Click on the root node of your server (usually the name of the server)
Open "Handler Mappings"
Under Actions in the right pane, click "View ordered list"
This is the order of handlers that process a request. If yours are like mine, the "ExtensionlessUrlHandler-*" handlers are all below the StaticFile handler. Well that isn't going to work because the StaticFile handler has a wildcard of * and will return a 404 before even getting to an extensionless controller.
So rearranging this and moving the "ExtensionlessUrlHandler-*" above the wildcard handlers of TRACE, OPTIONS and StaticFile will then have the Extensionless handler activated first and should allow your controllers, in any website running in the system, to respond correctly.
Note:
This is basically what happens when you remove and add the modules in the web.config but a single place to solve it for everything. And it doesn't require extra code!
Check that if your controller class has the [RoutePrefix("somepath")] attribute, that all controller methods also have a [Route()] attribute set.
I've run into this issue as well and was scratching my head for some time.
WebApiConfig.Register(GlobalConfiguration.Configuration);
Should be first in App_start event. I have tried it at last position in APP_start event, but that did not work.
I found this in a comment here: https://andrewlock.net/when-asp-net-core-cant-find-your-controller-debugging-application-parts/
Add the following to your Program.cs:
app.UseRouting();
app.UseEndpoints(endpoints =>
{
// DP: I don't know the purpose of this, but without it, all controllers report 404
endpoints.MapControllerRoute("default", "WTF is this");
});
For me this is all it took to make it work after hours of trying to find a solution. If this doesnt work for you, try adding
builder.Services.AddControllers();
Add this to <system.webServer> in your web.config:
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
<remove name="OPTIONSVerbHandler"/>
<remove name="TRACEVerbHandler"/>
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0"/>
</handlers>
Adding <modules runAllManagedModulesForAllRequests="true" /> also works but is not recommended due performance issues.
I have solved similar problem by attaching with debugger to application init. Just start webserver (for example, access localhost), attach to w3wp and see, if app initialization finished correctly. In my case there was exception, and controllers was not registered.
I had the same 404 issue and none of the up-voted solutions here worked. In my case I have a sub application with its own web.config and I had a clear tag inside the parent's httpModules web.config section. In IIS all of the parent's web.config settings applies to sub application.
<system.web>
<httpModules>
<clear/>
</httpModules>
</system.web>
The solution is to remove the 'clear' tag and possibly add inheritInChildApplications="false" in the parent's web.config. The inheritInChildApplications is for IIS to not apply the config settings to the sub application.
<location path="." inheritInChildApplications="false">
<system.web>
....
<system.web>
</location>
I have dozens of installations of my app with different clients which all worked fine and then this one just always returned 404 on all api calls. It turns out that when I created the application pool in IIS for this client it defaulted to .net framework 2.0 instead of 4.0 and I missed it. This caused the 404 error. Seems to me this should have been a 500 error. Very misleading Microsoft!
I had this problem: My Web API 2 project on .NET 4.7.2 was working as expected, then I changed the project properties to use a Specific Page path under the Web tab. When I ran it every time since, it was giving me a 404 error - it didn't even hit the controller.
Solution: I found the .vs hidden folder in my parent directory of my VS solution file (sometimes the same directory), and deleted it. When I opened my VS solution once more, cleaned it, and rebuilt it with the Rebuild option, it ran again. There was a problem with the cached files created by Visual Studio. When these were deleted, and the solution was rebuilt, the files were recreated.
If you manage the IIS and you are the one who have to create new site then check the "Application Pool" and be sure the CLR version must be selected. In my situation, it had been selected "No Managed Code". After changed to v4.0 it started to work.
i try above but not sucess all
add ms webhost and GlobalConfiguration.Configure(WebApiConfig.Register);

Resources