Azure Handle custom HTTP 401 - asp.net

I have a web service with basic auth (via custom database check in code) that returns HTTP 401 + SOAP FAULT message when user credentials are wrong. This works in my local IIS 7 but not in Azure...
When I move it to Azure, via App Service, and I insert bad credentials, I always get the following message:
HTTP 401
"You do not have permission to view this directory or page.".
But I want my custom error message in SOAP Fault format!
After hours of research I have found that if my code returns a response with HTTP 401 status, Azure translate this to the end-user like the message above, ignoring my custom error message.
I made another example with a "hello world" SOAP endpoint:
[WebMethod]
public string HelloWorld()
{
HttpContext.Current.Response.StatusCode = 401;
return "Hello world";
}
In my local IIS I got HTTP 401 "Hello world", but when I deploy this to Azure I got the same "Yout do not have permissions..."
¿How can I disable/avoid/dodge Azure 401 message transformation and return my own custom error message (SOAP FAULT)?
Note: I've already tried to disable authentication in Azure app service, enabling with "allow anonymous requests", etc.
Solution
The problem was in IIS. Adding the following line to my web.config works.
<httpErrors existingResponse="PassThrough" />
More info: https://stackoverflow.com/a/47307706/3763467
I will keep the same title/tags for other people facing the same problem and thinks the problem is in Azure.

It sounds like your web.config file might be setup to have custom errors turned on.
Can you please check your web.config file and set customer errors to on?
<customErrors="off" />

Related

Spring SAML 2.0 behind Nginx

I have a Spring-boot web app that uses SAML authentication provided by https://samltest.id/ .
It works fine on localhost but now I'm trying to put it on a server that has Nginx. Ngnix is configured so that any http request is redirected to https and https://myserver.company.com/myApp/ is sent to http://local_ip:local_port/ .
This cfg works fine if the application has no security but with SAML the result is: when I access the home page of the app I'm redirected to the login page (correct) and after successful login I'm redirected to https://myserver.company.com/saml/SSO/ instead of https://myserver.company.com/myApp/saml/SSO so Nginx gives a 404.
The metadata.xml contains:
<md:AssertionConsumerService Location="http://myserver.company.com:80/saml/SSO"
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" isDefault="true" index="0"/>
<md:AssertionConsumerService Location="http://myserver.company.com:80/saml/SSO"
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" index="1"/>
Note that URLs are http-based.
After a lot of Google search I have tried the following: I modified SAMLProcessingFilter configuration so that filterProcessesUrl property is "/myApp/saml/SSO" instead of the default value "/saml/SSO".
Now the metadata.xml contains:
<md:AssertionConsumerService Location="http://myserver.company.com:80/myApp/saml/SSO"
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" isDefault="true" index="0"/>
<md:AssertionConsumerService Location="http://myserver.company.com:80/myApp/saml/SSO"
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" index="1"/>
and after login I'm redirected to https://myserver.company.com/myApp/saml/SSO but this time I get a 404 from the web application instead of Nginx (the error page is different).
What am I missing?
UPDATE: the 3rd attempt
Restored SAMLProcessingFilter cfg to its default,
modified the context root of my app to be http://local_ip:local_port/myApp ,
modified Nginx cfg so that https://myserver.company.com/myApp/ maps
to http://local_ip:local_port/myApp (same context root),
set entityBaseURL property of MetadataGenerator to https://myserver.company.com/myApp ,
uploaded the new metadata.xml to https://samltest.id/ (now it contains https URLs).
Now, after a successful login I'm redirected to https://myserver.company.com/myApp/saml/SSO as expected but I get a 401 from the application with message "Authentication Failed: Incoming SAML message is invalid" and in the application log there is "org.opensaml.common.SAMLException: Unsupported request".
After several attempts I have found the solution.
No need to modify SAMLProcessingFilter or the context root. The key is to use SAMLContextProviderLB instead of SAMLContextProviderImpl as described in the chapter "Advanced configuration" of the manual. Also the entityBaseURL change already described in my question is necessary (it is in the manual too).

XSRF token expired after website publish to IIS

I am using ASP.NET Boilerplate framework, I put the below code in everypage.
#inject IAbpAntiForgeryManager AbpAntiForgeryManager
#{
AbpAntiForgeryManager.SetCookie(Context);
}
I call the app service as below:
var xhr = abp.services.app.order.add(data);
xhr.done(function (data) {
alert(data);
});
Everything works fine when I run in localhost, XSRF token will not expired even if I rebuild the project. Every time when I click [Publish website to IIS], all the ajax request will return 400 Bad Request, I guess it is because the XSRF token has expired, everything back to normal after I click F5 in browser. It was so annoying for the user, any thing I can do to prevent this error? Or auto refresh token?
Thank you!
update
error message in LOG file:
ERROR 2019-02-12 13:40:09,773 [71 ] .Antiforgery.Internal.DefaultAntiforgery - An exception was thrown while deserializing the token.
Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException: The antiforgery token could not be decrypted. ---> System.Security.Cryptography.CryptographicException: The key {996d31d2-0fa3-4ffe-8e82-e155c1486d33} was not found in the key ring.
Based on the error it sounds like your Data Protection keys have rotated on publish.
Check out the docs on Data Protection here: https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/introduction?view=aspnetcore-2.2.
There's a bunch of options how to configure it, where to store keys etc.
You'll want to change how it is storing them.
More on configuring Data Protection: https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview?view=aspnetcore-2.2.

Passing hostname to Invoke-WebRequest to warm up web application

I'm trying to generate requests to fire at our new versions of our .net web apps in IIS in order to start the app pools and warm them up.
The different versions are bound to local IPs and I'm trying to hit them with the following request as it looks like it will do the job:
Invoke-WebRequest 'http://172.28.36.31' -Headers #{host="www.mydomain.com"}
Now got the above working.
Any ideas on getting the same request to work over https and ignore and self signed cert warnings? There's a couple of options to ignore the warnings but haven't seen anything to use an ip with a custom host (akin to a local host entry)
You are getting a non-success http status code from the server which makes PowerShell throw an exception. Based on the "Object moved to here" message I assume it's going to be a redirect response.
You can check the status code by modifying your call like this:
try {
$response = Invoke-WebRequest 'http://172.28.36.31' -Headers #{host="www.mydomain.com"}
} catch {
$_.Exception.Response.StatusCode.Value__
}

Apparently my API Proxy does not exist

I've created a new API Proxy and deployed revision 1 into production, but when I call my API I just get:
HTTP 500 Internal Server Error
{
"fault": {
"faultstring": "Internal server error APIProxy revision 1 of MyProxy does not exist in environment prod of organization MyOrg",
"detail": {
"errorcode": "messaging.adaptors.http.ServerError"
}
}
}
Not the most helpful error message in history. Any pointers where to start debugging this would be very helpful, thanks!
You appear to be using the wrong url for your API, so it could not be found. If you haven't added any API key checking or additional authorization, you should be able to copy the url directly from the API details page in the prod Deployments line. Start a trace session and paste that url into the URL box. Test what happens when you do that trace.
If you have any additional security or other features that would alter the API, you would need to make those changes to the URL before sending it. If you're still having a problem, send an email to help#apigee.com.

Classic asp "An error occurred when verifying security for the message." iis7 transport level security

On II7 we host a WCF/asp.net based API. In order to allow users of a classic asp application to connect to the API we had to publish a version we refer to as "transport". This Transport version is written in asp.net too, it points to the same assembly , its just the security layer is different to allow classic asp to authenticate. Transport level security is used as opposed to message based security.
When using a browser to load the service reference i can loading the svcutil.exe ... WDSL page.
When using my test asp page to call a web method from this reference i get the following returned:
Finished calling Web Service.
Status = Internal Server Error
ResponseText = a:InvalidSecurityAn error occurred when verifying security for the message.
This suggests that the authentication is failing. When testing using asp.net or the application WCF storm to contact the normal API everything works well.
The API was recently migrated , it would appear something has not been setup correctly but i am at a loss to explain what.
I can browse to the svcutil.exe ... WDSL service reference, when selecting it via the browser i get the expect XML response.
The USER NAME and password utilised work when using the non-classic asp publicaiton of the API using the message based secuirty.
Would it be possible to post some troubleshooting tip that may help diagnoise the issue please specifically regarding transport level security fault finding and setup ?
Thank you
Scott
EDITED TO ADD THE FOLLOWING UPDATE:
Attempted to use the Default App Pool and a new App Pool but same problem persists.
My test page error: ResponseText = a:InvalidSecurityAn error occurred when verifying security for the message.
IIS LOG shows:
v3/transport/testclassicasptransportwcfservice.asp ( 200 0 0 ) (i.e iis 200)
/V3/Transport/DeviceService.svc/DeviceService (500 0 0) (i.e iis error 500)
note: virtual dir defined on TRANSPORT and V3. V3 works ok using .net as opposed to classic asp to authenticate.
EVENT LOG:
The Template Persistent Cache initialization failed for Application Pool 'transport' because of the following error: Could not create a Disk Cache Sub-directory for the Application Pool. The data may have additional error codes.
This reference appears to suggest a fix but many of the DIR paths and references in "appcmd" dont exist.
_http://theether.net/kb/100127
REF http://theether.net/kb/100127
load cmd prompt
CD to C:\Windows\System32\inetsrv
enter: appcmd list config -section:system.webServer/asp
the following path is displayed: c:\inetpub\conf\temp\ASP compiled templates
check path exists (it does)
Check if the NETWORK SERVICE has permissions to access "ASP compiled templates" If not from appcmd execute;
icacls "c:\inetpub\conf\temp\ASP Compiled Templates" /grant "NETWORK SERVICE:(OI)(CI)(M)"
should read "sucessfully processed 1 files"
restarted app pool.
THE "InvalidSecurityAn error occurred when verifying security for the message" problem still persists but the "COULD NOT CREATE A DISK CACHE SUB-DIRECORY .... " error from the eventlog is no longer occurring.
Sorry another update. The network service permission change DID NOT resolve the issue , changeing to the DEFAULT APP POOL solved the problem.
Got a lead at last. Examined:
ServiceSecurityAudit set in service behaviour. Ref http://intrepiddeveloper.wordpress.com/2008/08/07/security-event-logging-auditing/#
IIS logs (simply shows the non-specific error 500.)
Fault tracing enabled( also shows error 500).
Custom errors were off
Friendly IE messages were off
Asp client side and server side debugging on
ProcessMon running , no errors.
Web.config httpErrors errorMode="Detailed" /> +
ServiceSecurityAudit found me an "Object reference not set to an instance of an object" so sounds like our app has a bug.
Follow up (17/08/11):
Service Security Audit documented here:
http://intrepiddeveloper.wordpress.com/2008/08/07/security-event-logging-auditing/
Was the key for us to resolve this issue. Uncovered the Object Reference Error which indicated out Business Objects and Data Access dlls were out of alignment. Using CLASSIC ASP to contact the WCF.NET API using TRANSPORT AUTHENTICATION there was abolutely no indication of this error until Service Security Audit was enavled on the behaviour.config file in the WCF deployment.

Resources