Microsoft Edge Issue - The requested resource requires user authentication - angularjs

I have a website and api hosted on IIS 8.5 and lately users of the site are getting the following console error when attempting to POST data to the api when using Microsoft Edge:
HTTP401: DENIED - The requested resource requires user authentication.
(XHR)OPTIONS - http://my-local-address/api/customers/approval/post
Note: Users are authenticated by using Windows Authentication.
This occurs spontaneously and to get around the issue the users are forced to do a hard refresh (Ctrl + F5) on MS Edge and then they can continue with their process. Could there be a setting on IIS that's releasing the user authentication after a period of time?
I've listed my attempts to resolve the issue below:
I've got my organisation to add in a trusted policy for my local web address.
Changed the providers of the API. Moved NTLM above Negotiate.
Removed Negotiate based on this stackoverflow post Windows authentication failing in IIS 7.5.
Try and catch the error from the POST request but I'm returning null every time.
Configured CORS to allow for cross origin.
NB: I'm using angularjs for my front end and ASP.NET Web API 2 for the API.
The following code snippet details how the Web Api is configured:
WebApiConfig.cs
var cors = new EnableCorsAttribute("*", "*", "*") { SupportsCredentials = true };
config.EnableCors(cors);
Web.config
<system.web>
<identity impersonate="true" />
<compilation debug="true" targetFramework="4.5.1">
<assemblies>
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</assemblies>
</compilation>
<httpRuntime targetFramework="4.5.2" />
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="TRACEVerbHandler" />
<remove name="OPTIONSVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
Angular module config using $httpProvider to supply $http requests with credentials
$httpProvider.defaults.withCredentials = true;

Related

Not able to signin to a WebForms using ITFoxtec

Have tried to use ITFoxtec in my webform application but getting an error as below when I click on Login. I have registered the app in my default directory of my Azure AD.
<appSettings> <add key="Saml2:Issuer" value="urn:itfoxtec:identity:saml2:testwebapp" /> <add key="Saml2:SingleSignOnDestination" value="https://test-adfs.itfoxtec.com/adfs/ls/" /> <add key="Saml2:SingleLogoutDestination" value="https://test-adfs.itfoxtec.com/adfs/ls/" /> <add key="Saml2:SignatureAlgorithm" value="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" /> <add key="Saml2:CertificateValidationMode" value="None" /></appSettings> This I have added in the web.config
I think you need an administrator to consent/approve your application in Azure AD.
The config in the question looks like the sample config, and not the config you are using.

401 Unauthorized error when accessing webapi from angular

I need to capture a user's domain\username when they access my webapi app. On my dev machine I have my webapi at localhost:10570 and my angularjs website which makes calls to the webservice at localhost:34575.
If I make a call directly to my webapi app everything works fine. I can see the users domain and username and the service returns the requested data as JSON. But if I access my angularjs site and angular makes the call to webapi then I get 401 unauthorized for every call against the service.
In my WebApi app's web.config I have:
<system.web>
<compilation debug="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2" />
<authentication mode="Windows" />
</system.web>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="http://localhost:34575" />
<add name="Access-Control-Allow-Methods" value="POST, PUT, DELETE, GET, OPTIONS" />
<add name="Access-Control-Allow-Headers" value="content-Type, accept, origin, X-Requested-With, Authorization, name" />
<add name="Access-Control-Allow-Credentials" value="true" />
</customHeaders>
</system.webServer>
I have this in IIS Express for Visual Studio 2015's applicationhost.config file:
<location path="MyNamespace.WebAPI">
<system.webServer>
<security>
<authentication>
<windowsAuthentication enabled="true" />
<anonymousAuthentication enabled="false" />
</authentication>
</security>
</system.webServer>
</location>
My angularjs site is part of the same solution at "MyNamespace.Client".
Why does accessing the web service directly work fine, but accessing it via the angular app fail?
I didn't realize you have to tell Angular to send your credentials to the server. I just had to change my API calls from:
$http.get(url);
to
$http.get(url, { withCredentials: true });

prevent access to static content of asp.net - mvc app

We have asp.net MVC & angular application. We are using identityserver3 for access control to the application.
Everything is working as expected, except one thing.
Unauthorized users still have access to static content of the application.
Is there any way to deny access to those files before user log in ?
Here is the link to the great post which led me to the solution => Intercepting file requests
Steps I've taken to solve my problem:
Added this line to my webconfig file.
This will make sure that js files request wil not be processed by handler.
<system.webServer>
<handlers>
<add name="JSFileHandler" path="*.js" verb="GET"
type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
Register route.
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.RouteExistingFiles = true;
routes.MapRoute(
"staticfiles"
, "{*src}"
, new { Controller = "Main", action = "GetJS" }
, new { src = #"(.*?)\.(js)" } // URL constraints
);
Return file from controllers action
public ActionResult GetJS()
{
var path = this.Url.RouteUrl("staticfiles");
return File(path,
System.Net.Mime.MediaTypeNames.Application.Octet,
Path.GetFileName(path));
}
You can add this to your web.config
<location path="your/path/tostaticfiles">
<system.web>
<authorization>
<deny users="?" /> //Denies unauthorized users
</authorization>
</system.web>
</location>
Apart from the location section you also need to indicate IIS that ASP.NET will process these files (runAllManagedModulesForAllRequests="true").
Next to (sibling of system.web node):
<location path="Scripts">
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</location>
Under system.webServer node:
<modules runAllManagedModulesForAllRequests="true">
Note: use users="*" instead of users="?" if you don't want to let any user access your files. In my case I did that to prevent access to my JS files and I serve them using bundles.

How to serve static files (for CORS / OPTION request) in IIS?

I have an AngularJS application that I am trying to use an AJAX request to pull in a static file from a ASP.NET WebApi2 application running on IIS 8.5. Similar to the example below-
ng-include="http://server/Content/icon.svg"
If I navigate to that URL in the browser, IIS happily serves that file as a static file. However, when I use an AJAX request, Angular attempts an OPTIONS request first, since it is CORS request, and IIS throws a 405 Method Not Allowed.
I have tried adding these headers to the static Content folder in the web site-
However this made no difference. Also, the IIS server does not have WebDAV installed, which is a thing I have seen around as something that could cause issues.
I had an IIS site with a virtual directory from which I serve my static files.
In order to do CORS from the browser, what I did was configuring the "En tetes de réponses HTTP" of the site, which in english should be something like "HTTP Response Headers".
There I added a new header named "Access-Control-Allow-Origin" with value "*".
From this moment, I can use static files in XHR.
My actual problem was serving OpenStreetMap tiles to a file:///c/xxx/index.html and the error in chrome was
Image from origin 'http://myhost' has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
This works for me for accessing .png files in a subdirectory under forms authentication. You should be able to change the extension.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
<system.webServer>
<staticContent>
<mimeMap fileExtension=".*" mimeType="image/png" />
</staticContent>
<handlers>
<clear />
<add name="StaticFile" path="*" verb="*" type="" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" scriptProcessor="" resourceType="Either" requireAccess="Read" allowPathInfo="false" preCondition="" responseBufferLimit="4194304" />
</handlers>
</system.webServer>
</configuration>
What if you add the OPTIONS as a verb for the Access-Control-Allow-Methods As answered in this question.
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE,OPTIONS" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>
</httpProtocol>
</system.webServer>
If you want to serve static files to the public internet without any authorization you can set your CORS polity to:
Allow GET request
From any Origin
Allow all request Headers
Allow the OPTIONS reply to be cached for 24h
Internet Information Server this can be configured with the following IIS configuration for your site
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Methods" value="GET,OPTIONS" />
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="*" />
<add name="Access-Control-Max-Age" value="86400" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>

Connecting to a deployed WCF on IIS with Silverlight

I've deployed a WCF service on IIS 7.
Browsing to the service from a browser shows that it's running fine.
Connecting to the service from a Silverlight application produces the following error:
The HTML document does not contain Web service discovery information.
Metadata contains a reference that cannot be resolved: 'http://localhost:81/SdkService.svc'.
Content Type application/soap+xml; charset=utf-8 was not supported by service http://localhost:81/SdkService.svc. The client and service bindings may be mismatched.
The remote server returned an error: (415) Cannot process the message because the content type 'application/soap+xml; charset=utf-8' was not the expected type 'text/xml; charset=utf-8'..
If the service is defined in the current solution, try building the solution and adding the service reference again.
The service project is complied with .Net 4.0 and the Application pool for that service is also .Net 4.0
The Silverlight client is also compiled with .Net 4.0
Here's the service web.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</assemblies>
</compilation>
</system.web>
<system.serviceModel>
<diagnostics>
<messageLogging logMalformedMessages="true" logMessagesAtTransportLevel="true" />
</diagnostics>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true" />
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="6553600"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="false" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
</configuration>
enter code here
Silverlight only supports basicHttpBinding. I believe the WCF default is wsHttpBinding so you may need to change this and then update your service reference.

Resources