Windows Authentication IIS7 - asp.net

I have an ASP.NET Dynamic Data site that should only be accessible to administrators currently logged in and on the domain. I want the site to be able to tell who the user is based on their login and either allow or deny access without challenging for credentials. Due to the nature of a Dynamic Data site, I want to be certain no one else is finding their way in their so I'd like to manage authentication and authorization in IIS rather than the web.config. But no matter what I do, it denies access even as administrator.
Using IIS7 on a 64 bit Windows Server 2008 R2 Standard machine. When clicked on the site and go into Authentication, I have disabled all modes except Windows.
All three available providers are enabled in the following order:
Negotiate:Kerberos
Negotiate
NTLM
In Authorization, I have added a deny rule to deny anonymous users and then allow all users. Eventually will change that to allow role administrator but I can do that once I get this working.
What am I missing? If it matters, the web server, the domain controller, the file server the pages are on are all on the same domain.

You may want to use this little snippet of code:
Public Function GetGroups() As ArrayList
Dim groups As New ArrayList()
For Each group As System.Security.Principal.IdentityReference In System.Web.HttpContext.Current.Request.LogonUserIdentity.Groups
groups.Add(group.Translate(GetType(System.Security.Principal.NTAccount)).ToString())
Next
Return groups
End Function
This returns all the groups the current windows user is part of, that way you can check if the admin group is in the array list and just redirect them if not.
So drop the other access deny/allow and use whether or not they are in the admin group to determine access.
You will need to make sure that the following is in your config file:
<system.webServer>
...etc
<security>
...etc
<authentication>
<windowsAuthentication enabled="true" />
</authentication>
...etc
</security>
...etc
</system.webServer>

Related

Multi tenant httpCookie.domain in web.config

In an existing asp.net application the httpcookies.domain configuration is used for setting the cookie domain.
<system.web>
<httpCookies domain="www.domain.com"/>
</system.web>
I have to make the application multi tenant. Depending on which tenant is requested in the application, the cookie domain might be different, for instance domain1.com or otherdomain2.com.
We would like to keep the approach that the domain is set in some central location. I would like to be able to differentiate in runtime which domain should be used for http cookies, and not have a fixed value from the configuration.
See these articles for explanation abou this setting: description, microsoft documentation

ASP.NET Security: Deny Anonymous access to login page

I'm looking to deny all anonymous access to my login page and only allow people who are in a certain role to be able to view the page or anything under that directory. Is this possible? I have tried to implement this in the web.config but had no joy :(
thanks
This would only be possible in an intranet application where your users would be authenticated against Active directory. See MSDN
Otherwise, how would users log in if they don't have access to the login page?
I would rather implement access control on the actual content pages, or do an additional check when users attempt to log in and let them know that they need to be in a certain role in order to log into the system successfully.
Yes, you can...assuming that your clients are all running Windows workstations that are in the same AD domain as your IIS webservers and are using Internet Explorer (so, intranet only and not over the Internet). You want to configure IIS to only accept Integrated Windows Authentication, which will force the client workstations to use Kerberos to supply authentication information to IIS. Here's a how-to from Microsoft on how to configure this.
In web.config:
<configuration>
<system.web>
<location path="MyLoginPage.aspx">
<system.web>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</location>
</system.web>
</configuration>
The special keyword ? means anonymous users; which is documented in the element schema:
Attribute: users
A comma-separated list of user names that are denied access to the resource.
A question mark (?) denies anonymous users and an asterisk (*) indicates that all user accounts are denied access.
Basically this is the Microsoft long-winded way of saying:
Location: MyLoginPage.aspx
Deny: anonymous
This means that someone will have to be authenticated using a mechanism other than Form; such as Integrated (aka Kerberos, Windows) authentication, or with Basic authentication. You won't be able to use Forms Authentication, because they won't be able to reach the login page to login.

Restrict access to a specific URL, running on IIS7 / ASP.NET

I am deploying a public ASP.NET website on an IIS7 web farm.
The application runs on 3 web servers and is behind a firewall.
We want to create a single page on the website that is accessible only to internal users. It is primarily used for diagnostics, trigger cache expiry, etc.
/admin/somepage.aspx
What is the best way to control access to this page? We need to:
Prevent all external (public) users from accessing the URL.
Permit specific internal users to access the page, only from certain IPs or networks.
Should this access control be done at the (a) network level, (b) application level, etc.?
I found the best solution was to place an irule on our F5 load balancer.
We created a rule that the load balancer would drop all external requests for the specific directory. Internally, we could still hit the pages by connecting directly to the servers in the farm.
Here is how to secure specific page for specific users and only them
<configuration>
<location path="admin/somepage.aspx">
<system.web>
<authorization>
<allow users="User1,User2" />
<deny users="*" />
</authorization>
</system.web>
</location>
</configuration>
To set allowed IP you need to configure web site in IIS via IPv4 Address and Domain Restriction where add a wildcard Deny Entry and specif Allow Entries.
Also you can setup all this programmatically.
A simple implementation would be to set File Security on that File in IIS to Integrated Windows Authentication only.
Then in that file's code behind, check for the user's ID..if they are authenticated, they will have an ID, and let them access the page.
if(!HttpContext.Current.User.Identity.IsAuthenticated)
{
//Direct user to other page or display message.
}
When users go to that page, it will ask them for their network login

Mixing Forms authentication with Windows authentication

I have an (ASP.NET 3.5) intranet application which has been designed to use forms authentication (along with the default aspnet membership system). I also store additional information about users in another table which shares its primary key with the aspnet_users table.
For users who are part of our domain I store their domain account name in the secondary users table, and I want to automatically log in users whose domain account name matches a name stored in the table.
I have read the guides which are available - they're all from two years ago or more and assume that you are able to activate Windows Authentication on a separate login page that allows you to extract the domain account name. From what I can tell, though, this is not possible in IIS7 (the overall authentication method is applied on all pages and cannot be selectively deactivated, and both authentication methods can't be applied on the same page).
Is there a way of getting IIS to pass through the windows domain account name of the requesting user? I don't need proper AD authentication, just the domain name.
Actually, you can do it. Bit late for #dr_draik, but this cropped up in a google result for me so I thought I'd share some knowledge.
If you're in classic mode - Enable both Windows and Forms auth. You'll get a warning about not being able to do both at once, but you can ignore it. Then, you can spelunk around various properties like
Code:
HttpContext.Current.Request.ServerVariables["LOGON_USER"]
and fish the username out of there.
If you're in integrated mode - 4021905 IIS7 Challenge-based and login redirect-based authentication cannot be used simultaneiously leads to IIS 7.0 Two-Level Authentication with Forms Authentication and Windows Authentication which is a module that allows you to selectively change the auth for different pages.
You could always set up 2 separate application in IIS7. One would have Windows Authentication enabled. The other would be the main app with forms authentication. If a user went to the windows authentication app, the page could grab their credentials and pass it to the forms authentication app.
(More for completeness of information really)
I asked a .Net security guy this question at a conference a while back. His response was that it is technically possible, but he'd never seen it done (and to let him know if I did it and it worked!).
He suggested the way it could be done was by making your own ISAPI filter and installing it into IIS. The ISAPI filter would intercept the requests and basically do the job that IIS does when using integrated authentication, but fall back to using forms if this was not present. This involved some complicated challenge/response logic in the filter. This was for IIS6 though, so it might be different in IIS7.
Whilst this might be technically possible, I wouldn't suggest this route as it feels like a bit of a hack, and rolling your own security is never really a good idea (unless you really know what you are doing).
There are plenty articles on mixing the authenticaton by setting config to use the forms with allowing anonymous access to the app. Secondly, a page for integrated auth should be created with IIS settings set to deny anonymous and use Intgrated Authentication. There you would the magic trick by checking the "Logon_User" variable of the requets's ServerVariables collection. And finally for integrated authentication to silently sign in the user it has to have short hosted name. So if your forms authentication piece is exposed to internet via FQDN there should be some kind of redirect to the short host page. I think it is possible to achieve with just one application under IIS with 2 virtual directories.
I found a solution using no special add-ons. It was tricky and involved cobbling together elements from all the pages referenced here.
I posted about it: http://low-bandwidth.blogspot.com.au/2014/11/iis7-mixed-windows-and-forms.html
In essence, forms, windows and anon authentication have to be enabled.
The login screen should be forms based, and contain a button to trigger Windows login, that issues an HTTP 401 response challenge which if successful creates a forms based login ticket.
The issues are rather complex, and the post goes through the principles and the solution in detail.
Unfortunately, what you are trying to do just isn't supported. In order for ASP.NET to know the Windows username, you must use Windows Authentication.
You could set up another site / virtual directory that just forwarded the username information to another page. But what happens when non-Windows authenticated users try to log in?
I've got something you can try - not sure if it will work.
In the past we've used Request.ServerVariables["LOGON_USER"] but obviously for this to return a non-empty value you need to disable Anonymous access.
See this article: http://support.microsoft.com/default.aspx/kb/306359
It suggests keeping Anonymous access on the IIS side, and Forms authentication, but denying the anonymous user as follows:
<authorization>
<deny users = "?" /> <!-- This denies access to the Anonymous user -->
<allow users ="*" /> <!-- This allows access to all users -->
</authorization>

Retrieving the Windows username from a logged-in machine through an intranet application

How can an application, running on a production server, access the login username of the machine that a user is accessing an application from? For example, I am currently logged into my machine on the INTRA corporate intranet. My username will be INTRA\Username.
I have added specific usernames to a database and wish to check this intranet username against the database to restrict access to an application and leverage the username across the application.
Currently, I am using the following code to access the username:
Private username As String = Thread.CurrentPrincipal.Identity.Name
This is working great on localhost, but when authenticating against the database on a development server, I'm getting the following error:
Login failed for user 'NT
AUTHORITY\ANONYMOUS LOGON'.
Is this an incorrect approach? Is this even possible, or is it too much of a security issue? This application will be an internal intranet application running in an IE shop. Relevant pieces of web.config that already exist include:
<identity impersonate="true"/>
<authentication mode="Windows"/>
<authorization>
<deny users="?"/>
</authorization>
<connectionStrings>
<add name="CONNSTR" connectionString="Initial Catalog=DATANAME;Data Source=servername;Integrated Security=True;" providerName="System.Data.SqlClient"/>
</connectionStrings>
When setting up your web application on the server, you need to go into the Document Security section (the name of it changes depending on what version of IIS your server is running, but it's something like that), turn off anonymous authentication, and turn on Windows authentication. That tells the server to request windows login authentication from the browser. (Perhaps someone who knows web.config files better than I [which is nearly anyone] can edit this to point to the relevant bit; I don't think it's impersonate but if I knew, I'd say. I've so far only done this via the UI.)
in your example, you are locating the username that your webserver is running under. What you are after is the username of the user accessing the page.
Try something like this:
How To: Use Windows Authentication in ASP.NET 2.0
If setting the directory security to Windows Authentication is not working, change it to Basic Authentication. You'll also need to specify the domain name to authenticate against. This was the only way we could get the security to propagate through from the IIS layer to the DB. Unfortunately this causes the username and password to be sent through clear text. Its not the best solution, but since things were on the Intranet, it worked while we work on updating our login procedure.

Resources