ASP.NET MVC 2 and request client certificate (Smart Card authentication) - asp.net-mvc

I need to capture user's X.509 certificates from their cards and map to a user table for forms authentication in ASP.NET MVC. I have created an MVC (ver 2) project in VS 2008, configured to run as a virtual directory under the Default Web Site in the local IIS on Vista using the default template but added RequireHttpsAttribute to the Account/LogOn ActionResult. No other changes. Using the local IIS Manager, I created a self-signed cert and applied it, then set the Account/Logon.aspx page to Require SSL and Require client certificates.
Running in debug, when I click the 'Log On' link from the Welcome page (Home/Index view), it correctly routes to Account/Logon.aspx using https but no prompt for certificate. Using Dynatrace (awesome, http://ajax.dynatrace.com), I can see that the response status is getting set to 403 but again, no cert prompt.
As a sanity check, I set up a default asp.net web app project to run in a virtual directory in the default Web Site (same as MVC project above) in Vista and configured the default.aspx page to Require SSL and Require client certificates, as done in the MVC project above. Ran it, works fine, I get the certificate prompt and can choose cert and enter PIN for card and read my X.509 from request.clientcertificate object in the code behind.
The application pool for both virtual directories is set to Classic .NET AppPool in integrated pipeline mode.
Help?!
Update:
Super kludgy workaround in progress. I added a folder 'Auth' and an 'GetCert.aspx' file to it that is marked SSL/Require client certificates to the MVC project and then added "routes.IgnoreRoute("Auth/{*pathInfo}")" to the global.asax. The codebehind of the GetCert.aspx response.writes the data I want from the X.509. Then I added a jquery.get call in LogOn.aspx which calls GetCert.aspx and returns the cert Subject results as a string to a div in LogOn.aspx. I now get the cert prompt and get the results in my MVC view, but this can't be the way to do this!

I have a working solution using forms authentication and the authorize attribute on my base controller class so all non-authenticated requests go to Account/LogOn. The logOn page post button routes to an action called Authorize which is decorated with the RequireHttps attribute which correctly triggers the prompt for the client cert. Once the cert is selected the Authorize action handles parsing the HttpClientCertificate for the user info I want and doing a match lookup in my users table and writes an authentication cookie. I then have an HttpModule that reads the cookie to create a custom Principal in the AuthenticateRequest event. This all works great. I'm opening another question for the next issue regarding IIS configuration of 'ignore client certificates' here: https://stackoverflow.com/questions/4141272/iis-6-ssl-client-certificates-configuration

Related

IIS hosted app triggers run time error when url contains a "-"

I have an VS2017 AspNet MVC 5 app hosted on a 2016 Server and IIS. Each client has its own website with its own copy of the web app. Using godaddy.com I forward (with keep mask checked) the client domain to the sub-domain in the IIS and everything has been working fine for years. The client can access the web app and see its domain name in the browser url.
Example: myclientdomain.com forward with mask to myclientdomain.mycompanydomain.com but shows in the browser as myclientdomain.com
Now, I have this new client whose domain is newclient-domain.com (It has a dash) and it was forwarded exactly like the others, however, after the page loads, if the user clicks the only button in the page, it triggers a runtime error saying:
"The required anti-forgery cookie "__RequestVerificationToken" is not present.]"
Since all the others don't have this error, I am inclined to think it is the dash in the domain name. Am I right? Is there any solution other than removing the dash from the domain name?

Possible to configure JSF 2.0 web.xml to redirect to another context root if user is not logged in?

I need to implement security for a new JSF web app that is deployed along with a "legacy" JSP/servlet-based app in a single EAR file (container is WebLogic 11g). Right now I have a JSF Phase Listener that checks whether the user has a flag in their session that indicates that they're logged in (note that "shared session data" has been turned on so that both web apps use the same HTTP session).
I would prefer to not use a Phase Listener if possible and instead specify in web.xml to redirect the user to the login page if they're not logged in (this is how the check has been implemented in the legacy web app) However, the login page lives in the "legacy" app at a different context root than the JSF web app. (note the legacy app runs on an older servlet container version than the new JSF web app).
Is there a way to configure the JSF web app's web.xml file to be able to redirect to the first web app's login page if the they have different context roots?
There does not appear to be a way to do this (redirect to another context root's login page) in WebLogic 11g. Appears as though the Phase Listener solution is the best approach.
Note WebLogic 11g does allow sharing session and User Principal information between web apps deployed in a single EAR, but does not support specifying a URL to a login page that is in different context root than that of the current web app where the web.xml lives. So a servlet filter-like solution that can do the redirection to the login page in the other web app is needed.

Unable to get windows authentication to work through local IIS

So I've created a new ASP.NET MVC project using the intranet template. web.config contains the appropriate values (e.g. <authentication mode="windows"/>).
If I fire up the web app using the VS webserver, it all looks fine - the page shows my Windows domain and username and all. However, this works in Opera and Safari as well as IE and FF, which says to me it's not using Windows auth at all (since to the best of my knowledge this doesn't work in any browser except IE/FF).
Next step is to get it working through local IIS. I create a hosts file entry pointing www.mysite.mydomain to 127.0.0.1. So in IIS I create website with a binding to www.mysite.mydomain and enable Windows authentication and disable anonymous authentication.
I have set up IE and FF to enable Windows auth as follows:
IE
Add URL to intranet group
Ensure Windows auth is enabled in the advanced settings
FF
Put 'www.mysite.mydomain' into network.automatic-ntlm-auth.trusted-uris config setting.
But when I dial up www.mysite.mydomain in IE / FF I get a login prompt. Interestingly, even when I type in my Windows login here, it still fails and shows me the login prompt again.
We don't have active directory here but my understanding is that it should work fine with a local account.
I can't think of anything else I need to do. Any suggestions?
Edit: we've recently switched to using Active Directory and the problem remains.
Edit: when I cancel the login prompt, I get taken to an 'IIS 7.5 Detailed Error' page with the following information:
HTTP Error 401.2 - Unauthorized
You are not authorized to view this page due to invalid authentication headers.**
You have to whitelist a domain specified in the hosts file in order for windows authentication to work:
Click Start, click Run, type regedit, and then click OK.
In Registry Editor, locate the following registry key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters
Right-click Parameters, click New, and then click DWORD (32-bit) Value.
Type DisableStrictNameChecking and press ENTER.
Double-click the DisableStrictNameChecking registry value and type 1 in the Value data box, click OK
In Registry Editor, locate and then click the following registry key:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0
Right-click MSV1_0, point to New, and then click Multi-String Value.
Type BackConnectionHostNames, and then press ENTER.
Right-click BackConnectionHostNames, and then click Modify.
In the Value data box, type the host name or the host names for the sites that are on the local computer, and then click OK.
Quit Registry Editor, and then restart the IISAdmin service.
NOTE:
The original Microsoft KB links on this answer were broken and have been removed.
This article provided the instructions for setting DisableStrictNameChecking.
I recently spent three days trying to solve the same problem and it drove me crazy. It was happening on a load-balanced setup where one of the servers was authenticating correctly while the other failed. Investigating the problem - and eventually solving it - it turned out to be unrelated to the load-balanced environment, it could happen with any server when authenticating using Windows Authentication and the server is called with a name other than the one recognized by Active Directory
1. Enable Kerberos logging
To correctly diagnose your issue, you will need to enable Kerberos logging on the machine hosting your IIS site. To do so, add the following registry entry:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters
Add Registry Value LogLevel with ValueType REG_DWORD and value
0x1.
Once you turn on logging, then you try to authenticate, you will get errors logged in your Windows Application Log. You can ignore the error KDC_ERR_PREAUTH_REQUIRED (this is just part of the handshake) but if you get the error KDC_ERR_C_PRINCIPAL_UNKNOWN that means your AD controller doesn't recognize your server therefore you need to follow the steps below.
2. KDC_ERR_C_PRINCIPAL_UNKNOWN
if you're getting KDC_ERR_C_PRINCIPAL_UNKNOWN, that means the name "mysite.mydomain.com" is different from how the AD recognizes your machine so it's unable to provide a valid kerberos ticket. In that case, you need to register a Service Principal Name (SPN) for " 'www.mysite.mydomain" on the AD.
On your AD controller, run this command - you will need Domain Admin privilege:
Setspn -A HTTP/mysite.mydomain YOUR_MACHINE_HOSTNAME
3. Use a custom identity for your Application pool
Finally, make you Application pool use a custom account that belongs to the Active Directory instead of using NetworkService. This can be done in advanced settings of your application pool.
and .. voila.
Notes: The problem could (unlikely) be related to having multiple SPNs registered to the same machine, in that case you will need to run a command to remove duplicate SPNs, but I doubt this is the case. Also try adding a different binding to your site (that doesn't use a custom name) something like htttp://localhost:custom_port_number and see if authentication works. If it works, this is an extra indication that you're suffering from the same problem I had.
Did you try putting the domain in front of the user name?
DOMAIN\username
If you don't have a domain account, try prefixing your username with the machine name:
MYCOMPUTER\myusername
You should check to see if you have Windows Authentication installed/enabled. That may sound weird but in IIS 7 you have to install and enable the various authentication methods. Check out http://support.microsoft.com/kb/942043/ for more info, see quoted section below.
Cause 1
The Web application is configured to use Integrated Windows
authentication. However, the Windows Authentication feature is not
turned on. Or, the Integrated Windows authentication native module
section of the ApplicationHost.config file or of the Web.config file
is not valid. To resolve this problem, see Resolution 1.
Original
Usually when you try to view an asp.net web page hosted on IIS and receive a login prompt it doesn't mean your credentials weren't received or that you aren't authenticated. What it means is that the account that your website is running under doesn't have the right permissions to work with the files.
In IIS 6 and 7 you can easily change the user account that your app pool runs under. Try changing the app pool identity to an account with more access specifically designed for this. Or if you want to stick with the existing account (IUSR_? Network Service?) you can grant that account more permissions on the directory where your website is stored.
This article is specifically targeted at BizTalk but has almost no references to it and focuses on troubleshooting permissions issues with IIS and app pools: http://msdn.microsoft.com/en-us/library/aa954062.aspx
Why local IIS? Can you use local IIS Express?
If so, try this. It seems that IIS Express by default has Windows Authentication set to false.
Change
<windowsAuthentication enabled="false">
to "true" in applicationhost.config file (under 'C:\Users[Profile]\Documents\IISExpress\config' folder). This works for me.
To ensure that IIS uses Windows Authentication, I think you should try to turn of other authtentication methods. If Anonymous Authentication is enabled, Windows authentication will not work. You can also read this Microsoft Support Article which describes IE and IIS requirements in details.
I got this error when I enabled Windows authentication. I wanted to authorize the user based on Windows login and there is no login page in my application.
I got the error fixed by adding the below in my Web config file.
Under the tag system.web, I changed authentication mode="None" to
authentication mode="Forms".
Under the tag appSettings, I added add key="owin:AutomaticAppStartup" value="false"
After reading the answer of Espen Burud, I solved my problem by changing in the root's web.config:
<allow users="*" />
to
<deny users="?" />
The page that needs Windows Authentication is not in the root, but in a sub directory with its own web.config with deny users ? but that did not make Windows Authentication working. Apparently, you need to deny users in the root for that to work.
The IIS config has Anonymous Authentication enabled; that did not matter. After the above change of web.config, Windows Authentication worked.
For Dot Net Core 2.2 and running on IIS, I was having issues with 401.2 Unauthorized when I would check the Enable Windows Authentication within my application. It was a exceedingly simple test website that did basically nothing, just to try and get windows authentication to work. I finally got the auth to work, and here's what you'll need:
Within Startup ConfigureServices:
services.AddAuthentication(IISDefaults.AuthenticationScheme);
Open the application's Properties, click Debug option on the left and make sure you check Enable Windows Authentication.
But here's the kicker that I had forgotten... Configure your system to have Windows Authentication installed on IIS. This was never setup on my machine, and regardless what I did, I would always get a 401 unauthorized error. After installing this (Win 10, IIS v10.0.18362.1) I now get a login prompt. This isn't exactly what I need at this point, but at least it's not the unauthorized error. Good luck and hopefully this helps.

IIS7.5 and MVC 2 : Implementing HTTP(S) security

This is my first ASP.NET MVC application, and my first on an IIS 7.x installation whereby I have to do anything over and above the standard.
I need to enforce Windows authentication on the /Index and /feeds/xxx.svc pages/services. In ASP.NET Web Forms, I would apply the Windows permissions on the files and remove Anonymous authentication in IIS 6. This needs to work over HTTP/S, but don't worry about that, that's in hand.
What happens in MVC/IIS 7?
I have tried modifying the permissions on the /Index.aspx view, which seems to block access. It asks me for a username/password, but does not grant access when I enter a valid username/password. Pressing Escape gives me an exception "**Access to the path 'E:\dev\xxx\xxx.ConsultantRegistration.Web.Admin\Views\ConsultantRegistration\index.aspx' is denied. **", which does get sent as a 401.
So although the username/password does exist on the Index.aspx view, I can't use those credentials to access said view.
I have in my web.config:
What am I missing?
Don't set file permissions. Instead enable the WindowsAuthentication provider in your website in IIS, and add the [Authorize] attribute on the controller action. You can further filter the users that have access to these pages like this:
[RequireHttps, Authorize(Users="MyUser")]
public ActionResult Index()
{
return View();
}

ASP.NET MVC Windows Security issue

I am suddenly getting a Windows Security dialog when requesting:
http://mydomain/Reports/
This happens after I have moved an ASP.NET MVC application from Server 2008 to Server 2008 R2.
This page (like others) are access controlled using Windows Form authentication. The other pages work correctly, just this page is giving me hassles - and only on this server.
Even signing in with my domain credentials fails; after the third failed login a blank page appears.
I have disabled Windows Authentication in IIS and enable Form Authentication.
The request executes:
public ActionResult Index()
{
return View();
}
The index.aspx page associated to his page contains static HTML.
Any ideas what might be causing this?
Update to comments and questions:
Site (mydomain) is running as a web site on its own.
SSRS is installed on the machine but not part of this web site.
Changing the controller name to ReportController instead of ReportsController causes it to work. Something is processing Reports first, where can I find it? I don't see any Reports folder or web sites on the server...
When upgrading sql server, often it adds a virtual directory or virtual application in iis called Reports and ReportManager. Just went through this, so it's worth checking out.
Check the permissions on the folder or file, they are probably not set correctly so IIS is trying to get a valid set of credentials to continue.
Also, is that Reports folder running, say, SSRS?

Resources