I have a slightly odd situation whereby I have a C# framework 4.6.2 console application to run background tasks that use a shared library for authentication.
Authentication is important here because there are downstream HTTP API dependencies that require a cookie.
The shared authentication project uses FormsAuthentication.Encrypt(ticket) to create a cookie, however, the FormsAuthentication methods require that you have the appropriate setup in a Web.config file.
In my console app, I only have an app.config file and if I add the <authentication> and <machinekey> elements they do not appear to be picked up by FormsAuthentication.
Unfortunately for me, I am unable to make any wholesale changes to this stack as it is a large legacy application with many dependencies, all with an assumption that forms auth will "just work".
Any ideas much appreciated.
So I was mistaken as to the cause of this problem. I can confirm that the forms authentication settings are indeed taken from the app.config, however, the problem was with the default compatibility mode of the machine key element.
After reading this article I realised that the console application was defaulting to Framework20SP1 but the web API at the other end was defaulting to Framework45.
I will leave this answer here in case anyone else has similar issues - if so check the compatibility mode being used in each service. If (like me) you need to override the default so that they match between services then simply add the compatibilityMode="Framework45" attribute to the <machineKey> element.
Related
ASP.NET Core cannot be run directly in IIS as it requires Kestrel.
This means it is not possible to update a website at runtime like in traditional ASP.NET sites, since the kestrel server have to be shut down during the update.
I want to avoid downtime without adding additional web servers and a load balancer. Is it possible to configure the ASP.NET Core module in IIS to connect to two different Kestrel servers? So if one of them is shut down all requests will go to the other one?
(I was thinking something like having two different folders on disk: C:\inetpub\wwwroot\mysite_instance1 and C:\inetpub\wwwroot\mysite_instance2, thus shutting one down will enable updates of that instance)
If it is possible, are there any considerations we need to be aware of? For example, do the anti forgery token need to be configured in some way? (I do not use sessions.)
I would also be interested in a neat load balancer mechanism, but don't know any way to do it. Yet, you can perfectly switch the directory targeted by a web application from a directory C:\inetpub\wwwroot\mysite_instance1 to a directory C:\inetpub\wwwroot\mysite_instance2, update instance1 and switch it back, and it should do the job.
This is not currently supported due to the way in which IIS and the AspNetCoreModule works.
IIS passes an IHttpContext object to the AspNetCoreModule. The AspNetCoreModule uses the IHttpContext object to query the physical application path. The module then reads the web.config file found in the directory of the application. Once this has been done the module maintains a 1:1 relationship between the IIS application and the dotnet process.
I've raised this as a question and included some additional details on your behalf.
I am using the method mentioned in the link https://learn.microsoft.com/en-us/azure/active-directory/active-directory-signing-key-rollover#vs2012 to automatically rollover the certificates.
However the below line of code searches for <issuerNameRegistry> as a child element of the <identityConfiguration> which is deprecated according to the msdn link https://msdn.microsoft.com/en-us/library/hh568647(v=vs.110).aspx
ValidatingIssuerNameRegistry.WriteToConfig(metadataAddress, configPath);
Is there any updates coming soon to System.IdentityModel.Tokens.ValidatingIssuerNameRegistry nuget package which searches for <issuerNameRegistry> as a child element of <securityTokenHandlerConfiguration>
I am able to get the code working as there is support for backward compatibility. However I do not want to use deprecated methods
What I found worked best was to use the different versions of Visual Studio and Office 365 to see the differences in approach.
The current way has a little different syntax and all of that can be discovered by using the ASP.Net Web Application template.
If you use the template in vs2013 you will see the setup you must currently have with <federationConfiguration> and <identityConfiguration> sections, TenantDbContext, IdentityConfig and it wired up in your global.asax
If you do the same thing in vs2015 you will see that there is no longer any configuration at all besides appSettings. Everything is magically wired up through a partial class at the root called Startup.cs with more of the content hidden in the App_Start folder. This is the OWIN pipeline and has a much different feel than what you have been used to. For the better. A lot of the identity terminology is the same, the keys are the same, the management in AAD is the same so you get to reuse a lot of your code. OWIN does require MVC5 so if you can't upgrade you are pretty good where you are.
The ValidatingIssuerNameRegistry has been replaced by a TokenCache but the concept is the same, EF store for rollover safety.
More Reading:
Authentication, Authorization and OWIN – Who Moved My Cheese?
Understanding OWIN Forms authentication in MVC 5
First of all, I'm not familiar with Web development so I might be missing something basic here. Do excuse me if that's really the case.
I'm currently working on a web application (not created by me), which is based on another web app.
Both applications share similar user log in code, but user account info are stored in different databases.
However, after logging in to 1 of the app, the WebSecurity.IsAuthenticated flag is also true on the other app (detected as logged on). Is this behaviour expected?
In case this information is of any use..
1 of the app uses ASP.NET development server while the other uses ISS express.
This is not exactly an answer to my initial question.
That has been answered by #Esa in the comment above --> Setting machine key to Web.Config.
The following is an answer to the problem I mentioned in the comment.
(Should I have posted this in comment instead?)
Both applications were overwriting the same __RequestVerificationToken cookie, which caused error "The anti-forgery token could not be decrypted..." when navigating.
This is because both applications were at the same path of "localhost:xxxxx" and hence detected as the same site. The error can be avoided by changing the virtual path of either application.
For VS, Project properties -> Web (tab) -> Virtual path
I've just finished developing the core features of my site, and have now uploaded it to a host to test.
Unfortunately, I get the following error:
Security Exception
Description: The application attempted to perform an operation not allowed by the security policy. To grant this application the required permission please contact your system administrator or change the application's trust level in the configuration file.
After tedious searching, I realised that it's because I developed in a full trust environment, and my stubborn host will only allow medium trust.
When I set medium trust in web.config, the debugger doesn't show what exactly needs the full trust environment.
Is there any way to clearly check this, or somehow force the site to co-operate?
I am using MVC with FormsAuthentication, Code-First Databasing, etc.
After a LOT of trial and error, I have found the error.
Microsoft's SignalR requires full trust, and there is no way around it.
Disabling that fixes the issue.
Edit
It also seems that any library that will help the site out in the long run is out. If anyone is getting this error, simply disable (comment out) any tertiary library you use BEFORE altering your core code.
Breakpoints do not help at all, as after disabling SignalR, I had an error on a certain page. Setting a breakpoint didnt stop the code in the error event, as it turns out the Security Exception is thrown somewhere deep inside C#, and not brought to the top.
You have two options
You could have two web.config files, one for debugging and one for publishing and testing under an environment that is as close as posible as your hosting environment.
Another option could be two have a single config file with the medium trust set, and use logging to a file/event logger to allow you to debug
The Mixed Authentication Disposition ASP.NET Module (MADAM) is exactly what I need for the project I'm building in MVC2. I'm not an expert on authentication, could MADAM be quickly retrofitted to work with the MVC pipeline?
http://msdn.microsoft.com/en-us/library/aa479391.aspx
Depending on your Server Version of IIS, you will need to place the MADAM modules into different locations within your web.config file.
IIS 6
<system.web>
<httpHandelers>
<-- Madam Modules go here -->
</httpHandelers>
</system.web>
IIS 7
<system.webServer>
<httpHandelers>
<-- Madam Modules go here -->
</httpHandelers>
</system.webServer>
I have been looking into using MADAM for my current project at work as well, however I cannot seem to get it to fire.
It would appear that something has changed in the way that either ASP.Net processes requests and deals with HttpModules or it is a difference in the ASP.Net MVC pipeline.
The quickest solution that I have been able to find is to split the project into two separate projects and host them as different applications in IIS otherwise the authentication will not work as desire.
As far as I can tell if you leave Forms Authentication on, MADAM does not fire and any paths which you wanted Http-Basic authentication for just redirect to the login/or default page. If you have Forms Authentication off then the Http-Basic authentication will work, but the Forms Authentication will not work as it cannot read the .ASPXAUTH cookie automatically.
Unless I stumble across some way to get it working I will have to split this project into two and host each as a separate application in IIS.
If you have any other work arounds they would be gratefully received.
I haven't used MADAM, but based on the diagram I don't see any reason why you couldn't implement this process in an AuthorizationFilter or wire it up directly to HttpApplication.AuthorizeRequest event. ASP.NET MVC is still subject to the ASP.NET HttpApplication life cycle.