ADFS v2.0 Error : MSIS7042: The same client browser session has made '6' requests in the last '1' seconds - geneva-framework

Folks,
I've got an ASP.NET MVC application that I am attempting to secure using the Release Candidate version of ADFS v2.0 (Geneva). I have configured the application as a relying party trust, and I've used Fedutil.exe to modify the application's Web.config so that it has the information about the Geneva server and uses the Geneva server as its claims source.
However, when I try and hit the MVC app, it redirects to Geneva, which then (after warning me about self-signed certs) re-directs me to the MVC app again. After accepting both self-signed cert warnings, the two servers play ping-pong with each other in an infinite redirect loop until finally Geneva spews the following message:
The same client browser session has made '6' requests in the last '1' seconds. There could be a possible bad configuration. Contact your administrator for details.
There are no errors in the event logs on the MVC side or on Geneva except for an event containing the above message. If someone could give me some information on how to try and debug, diagnose, and hopefully fix this problem, I would be eternally grateful.
Again, the Geneva box is the ADFS v2.0 Release Candidate and the ASP.NET MVC site was built using the latest (late '09) version of the Windows Identity Foundation SDK with Web.config modified using FedUtil.exe from the WIF SDK.
So you will all get a kick out of this... I tried this same application from Firefox and ... IT WORKS. I get prompted for my domain credentials, the ADFS v2 server re-directs me ONCE and then I end up on the home page of my application, complete with my account name and personalized greeting.
So now the real issue is this: Why the hell is IE8 getting caught in an infinite redirect loop and Firefox ISN'T ??
After even further testing, I've been able to get this scenario working, out of the box, without modification of any of the default pipeline stuff from ADFS v2 (RC) or from WIF (RTW) on BOTH Safari AND Firefox. IE8 is the ONLY browser to exhibit any problem dealing with this authentication scenario. I've tried everything, including installing and trusting the self-signed certs, adding the sites to my local intranet zone and dropping security to low and even setting first AND third party cookies to always allow.

I had the same issue with ADFS 1.0
And to resolve it, I made sure that the URL had a trailing forward slash "/" that would always work in FireFox as well as IE
eg : https://somedomain.com/Application_2/

Turns out that the host name of the relying party had an underscore in it (khoffman_2). Apparently, the underscore is an illegal DNS character and ONLY IE will reject the information with the underscore in it.
I renamed my machine from khoffman_2 to khoffman2 and the ADFS v2/MVC relying party combination works flawlessly on Firefox, Safari, AND IE.

While this isn't your problem, we have had identical problems to what you described. Our solution was to:
Enabled Basic Authentication in IIS (this solved nothing but was required for the next 2 steps)
Disable Windows Authentication in IIS (this solved the problem for some IE browsers but not all)
Disable Anonymous Access in IIS (this solved the problem for the rest of the IE browsers)

Jaxidian's answer is close.
In my case I only had to:
Windows Authentication -> Disabled
Anonymous Auth -> Enabled
ASP.NET Impersonation -> Disabled
Forms Auth -> Disabled
Windows Auth -> Disabled

This loop can occur when a user is not authorized to access a page.
We had a custom authorization attribute on our MVC controller that checks to see if the user was in a role based on the claims provided if the setting for UseADFS was true in the config files. I thought this setting was set to true and was confounded that I kept getting the adfs loop when accessing the page because I was in the groups that were authorized to access the page.
The key to troubleshooting was to make a web page that displayed my adfs claims without necessarily requiring authentication.
#if (User.Identity.IsAuthenticated)
{
<div>UserName: #User.Identity.Name;</div>
var claimsIdentity = User.Identity as System.Security.Claims.ClaimsIdentity;
<table>
#foreach (var claim in claimsIdentity.Claims)
{
<tr><td>#claim.Type</td><td>#claim.Value</td></tr>
}
</table>
}
I noticed that I was getting logged into ADFS, and my claims were getting set, so ADFS was working. The actual issue was my config file had UserADFS="true" instead of UseADFS="true" which basically caused my custom authorization code to return false on authorization. Therefore, the page kept forwarding me back to adfs to authenticate again.
Anyways, if a user does not have the correct claims to access the page, then this adfs login loop can occur, as well.
Also, if you wrote a custom authorize attribute be sure to check out the following link which describes how to prevent the loop.
Redirect loop with .Net MVC Authorize attribute with ADFS Claims
Custom HandleUnauthorizedRequest handler code for AuthorizeAttribute from that link:
protected override void HandleUnauthorizedRequest System.Web.Mvc.AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAuthenticated)
{
//One Strategy:
//filterContext.Result = new System.Web.Mvc.HttpStatusCodeResult((int)System.Net.HttpStatusCode.Forbidden);
//Another Strategy:
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary(
new
{
controller = "u",
action = "LoginStatus",
errorMessage = "Error occurred during authorization or you do not have sufficient priviliges to view this page."
})
);
}
else
{
base.HandleUnauthorizedRequest(filterContext);
}
}

Related

asp.net Identity authentication .net core 2.1

I'm having an issue with a .net core 2.1 MVC application that is running on Linux boxes using kestrel behind an nginx web server. This environment has 2 web servers behind a load balancer.
The issue is the .AspNetCore.Identity.Application cookie used for authentication. I am able to authenticate and redirected to a controller decorated with the
[Authorize]
attribute (sometimes). However, on the next request, the cookie's gone and I get a 401. When we take one server out of the mix and force all traffic to one server, everything works as expected.
With Forms auth, the same problem could be overcome with specifying the machine key. What's the equivalent for .net core using identity? I found some links that went over my head. They mention doing something like this:
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
I have no idea if this will fix the issue and I don't want to try things without knowing what they do.
I suspect what you experience has to do with data protection.
ASP.NET Core cookie authentication relies on the data protection layer to encrypt and decrypt data stored in the cookies. By default, a local key is created on each machine, meaning they can't decrypt cookies created by the other one, as stated in the official documentation.
I suggest that you go through the data protection configuration documentation page and evaluate your options. One of them is to store the keys on a UNC share and encrypt them with a certificate (all the links in this paragraph link to different sections of the same page).

Web api 2 - windows + client cert auth - is it possible?

I currently have an asp.net web api 2 site hosted in IIS secured with windows authentication. A requirement has now come in for us to support client certificate authentication in addition to windows, and I'm struggling to find out:
- if this is possible at all
- if there are any working examples available
I thought might be able to add an additional owin middleware or messagehandler or filter, but can't see any existing ones that do this specifically for windows rather than just relying on IIS. I know thinktecture identitymodel can do client cert, but not sure if the two can be combined?
Example of forms +win that i thought might be similar is here https://techblog.dorogin.com/mixed-windows-forms-authentication-for-ajax-single-page-application-e4aaaac0424a
Right so I managed to figure it out. Thankfully, if a controller returns a 401, IIS automatically adds the negotiate/ntlm headers, so if a user is on a windows browser, it will then automatically authenticate as usual. So with that in mind, to keep windows auth working, I:
updated the site in both IIS and VS to allow anonymous AND windows auth
added the [AuthorizeAttribute] as a global action filter (which causes the 401 to be returned if the user is not authenticated by the time they hit the filter)
To get client certificate auth working, I used the magnificent Thinktecture.IdentityModel library, which allowed me to add only one line to my Startup.cs file (we're using OWIN so this was easy)
app.UseClientCertificateAuthentication();
See https://github.com/IdentityModel/Thinktecture.IdentityModel/blob/master/samples/OWIN/AuthenticationTansformation/KatanaAuthentication/Startup.cs for an example

Https/BotAuthentication breaking botframework bot?

I am having an issue with trying to create a bot. Everything seems to work fine when I am using Http. I can deploy my application to my website and interact with the bot via the emulator or botframework.com.
Unfortunately, when I try to use HTTPS, I get a 401 error from the emulator and nothing shows up when I try to use botframework.com.
Just so that I am crystal clear, the only things that I changed are:
1. Added the [BotAuthentication] attribute to my ApiController like so:
[BotAuthentication]
public class MessagesController : ApiController
Updated the URL in the emulator/botframework.com from http://mywebsite.com/api/messages to https://mywebsite.com/api/messages
Web.config is all set up with the appId and AppSecret. My site already has an SSL certificate.
Is there anything that I am missing? Although I have never used basic authentication before I am assuming there is nothing else that I need to set up, right?
I hit your endpoing and IIS is responding to the basic auth and getting in the way.
Basic Auth is works the following way:
There is a header which contains the UserId:Password encoded as base64
If the server doesn’t see the header it returns a 403 with a “basic” to signal that the web site requires auth token. For a web browser that means it will popup a stock user/password dialog and then it will do submit the request again with the header.
If the header is provided but the user/password is wrong the server returns 401.
Normally basic auth is used to look up in a database, but in our case there is only 1 user, it is the bot appid/appsecret. All the BotAuthorization attribute does is to add an inspector to the request pipeline to look for the header with appid/appsecret in it to make sure that only approved callers can call your bot.
If you don’t care about that you can simply remove the attribute. Regardless, you don’t want IIS sticking it’s nose into the process.
Make sense?
This theoretically should work based on your description of the changes you've made. This is the emulator talking to your cloud service or to the bot on localhost? And you get this error as well from the Bot Framework test control in the portal?
If you send me your BotId to botframework#microsoft.com I can check our logs to see if there's anything interesting (or DM me at #jameslew on twitter).

In ASP.NET is there an event fired on a Windows Authentication log in failure? (Logging the details of a Windows Authentication failure)

I am building a .NET 4.0, ASP.NET MVC 3 intranet application that runs on IIS 7.5 in integrated mode. Windows Authentication is used to govern access to the website. The Windows Authentication module is enabled and all other auth modules are disabled.
Currently when a user provides improper credentials, the Windows Authentication module correctly rejects the credentials and re-displays a login prompt. It does so 3 times, after which a standard .NET 401 Unauthorized Access page is shown. This is expected and desirable.
My goal: I would like to be able to log the details of the failed authentication attempt to my own custom event log. Particularly, to capture the user name that was used in the log in attempt. (I'll accept that capturing the password is not likely to be possible for security reasons.)
Is my goal possible?
I have already built a working an IHttpModule module and added it as an event handler to the WindowsAuthenticationModule, like this:
myWindowsAuthenticationModule.Authenticate += WindowsAuthentication_Authenticate;
But my code does not get called in the case of a failed log in attempt, presumably because WindowsAuthenticationModule has already decided that the log in is failed and so there is no point calling my module. My module does get called after a successful log in attempt, and so I am certain that my event handler is properly set up.
To the best of my knowledge, the WindowsAuthenticationModule does not expose an event that is fired when authentication fails, so that option is out.
Any ideas? Or am I barking up a tree that has no solution?
I was looking at the same issue, and looks like there is no events for windows authentication, even that Authenticate event is common for forms and windows.
But I found a solution to this!
http://www.codeproject.com/Articles/11202/Redirecting-to-custom-401-page-when-quot-Access-de
UPDATE
From original article
protected void Application_EndRequest(Object sender, EventArgs e)
{
HttpContext context = HttpContext.Current;
if (context.Response.Status.Substring(0,3).Equals("401"))
{
if(User.Identity.IsAuthenticated)
{
// this means user is authenticated, but 401 still returned
// which means no access to page or whatever you are trying to access?
}
}
}
UPDATE2
I also found out that this solution doesn't work in all cases. I was testing in different environments, so was working for me, but not for others.
By default IIS will not even run this piece of code and just return it's own error page, what you want to do is tell IIS to let app handle errors.
<httpErrors existingResponse="PassThrough">
</httpErrors>
Now, with that said, IIS won't return any more of custom errors and you will need to handle them in application, ie. not only 401, but 403, 405, etc

Impersonation in ASP.NET web application does not work when running on IIS

I am working on ASP.NET 4.0 MVC3 web application that works in intranet environment. The application makes use of Windows authentication. Its application pool is run by domain user that has spn set on a domain controller. Authentication works using Kerberos (on IE and Firefox after some additional configuration).
Now I want to upload files to sharepoint, but it's important for me to upload the file as the user currently logged in into the application (so the file is created on Sharepoint with his/her credentials).
I have the following code in ResourceExists(Uri uri) function:
'...
Dim identity As System.Security.Principal.WindowsIdentity = HttpContext.User.Identity
Dim impersonationContext = identity.Impersonate()
response = request.GetResponse()
impersonationContext.Undo()
'...
This works when running locally, but when I deploy to the server I get the exception:
System.Net.WebException: The remote server returned an error: (401) Unauthorized.\r\n at WebDav.WebDavClient.ResourceExists(Uri uri)\r\n at Website.Website.WebdavController.Upload(HttpPostedFileBase file, UploadViewModel vm)
I read something about passing on the credentials, that is not possible with NTLM, but I am sure I am using Kerberos (I checked the headers with wireshark and fiddler) and I see the following:
Authorization: Negotiate YIIFpQYGKwYBBQUCoIIFmTCCBZWgJDAiBgkqhkiC9x...
Any ideas why the impersonation does not work when running on the IIS server?
I found the answer here:
http://support.microsoft.com/kb/810572
"Kerberos does not work in a load-balanced architecture and IIS drops back to NTLM authentication. Because you cannot use NTLM for delegation, any applications or services that require delegation do not work. For more information, click the following article number to view the article in the Microsoft"
And that was exactly the case. I tried now with another machine that is not load-balanced and it works.
The only thing that still surprises me is that ImpersonationLevel of the identity is still Impersonate not Delegate...
After setting <identity impersonate="true"/> in your web.config try the following:
using (((WindowsIdentity)User.Identity).Impersonate())
using (var client = new WebClient { Credentials = CredentialCache.DefaultNetworkCredentials })
{
string result = client.DownloadString("http://sharepoint");
}
you need to configure your site correctly in IIS for impersonation to work.
see Configure ASP.NET Impersonation Authentication (IIS 7)

Resources