I have a web app on our intranet (VS 2005). There are a couple pages that don't require the user to be logged into the app (feedback and the default page). I am trying to get the domain and username to display and/or send with the feedback. Is there a way to do this without requiring the user to log in? I've tried this.Request.ServerVariables["LOGON_USER"] and this.User.Identity.Name, but neither of them worked.
Edit:
I should have mentioned most of the users have Windows 2000 on their machines. It works on my development machine (XP), but not on the production network (where I have 2000).
Theresa, I think this is what you're looking for...
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
WindowsPrincipal principal = (WindowsPrincipal)Thread.CurrentPrincipal;
WindowsIdentity identity = (WindowsIdentity)principal.Identity;
String userName= principal.Identity.Name;
Assuming you have turned Windows Authentication on in IIS for your site:
public string user_Name
{
get
{
string x = Page.User.Identity.Name;
x = x.Replace("YOURDOMAIN\\", "");
return x;
}
}
The x = x.Replace("DOMAIN\", ""); strips out the DOMAIN sectionof the user acccount e.g NISSAN\rmcdonough
Related
I am developing an MVC app and I would like to auto login users into the system by retrieving their email address from Active Directory, use that email address to find a user in my database, if found log them into the system. The Idea is for the system to not force the user to input login details after already logging into their workstation that is setup on a work domain/Active Directory.
Please help me with pointers on this as I've tried most approaches described in many threads.
I've set my IIS app pool to Network Service
ASP.NET Impersonation is disabled..
I've enabled Load User Profile in app pool -> Advanced Settings
When I use the code below, the search fails:
using ( System.Web.Hosting.HostingEnvironment.Impersonate() )
{
PrincipalContext ctx = new PrincipalContext( ContextType.Domain );
UserPrincipal user = UserPrincipal.FindByIdentity( ctx, User.Identity.Name );
Response.Write( "User: " + User.Identity.Name );
Response.Write( user.EmailAddress );
Response.Flush();
Response.End();
}
Error: The (&(objectCategory=user)(objectClass=user)(|(userPrincipalName=)(distinguishedName=)(name=))) search filter is invalid.
Can someone please point me into the right direction of what I am trying to achieve? Am I approaching my requirement wrongly?
Thanks in advance.
For users to be logged in automatically, you need to use Windows Authentication. For that to work, there are a few prerequisites:
The users must be logged into Windows with the account they will use to authenticate to your website.
Your website must be added to the Trusted Sites in Internet Options in Windows (or considered an "Intranet Site") so that IE and Chrome will automatically send the credentials. Firefox has its own setting called network.negotiate-auth.trusted-uris.
Your server must be joined to a domain with a trust to the domain of the users (usually it's the same domain).
If all those things are true, then you can follow the instructions here to install the Windows Authentication feature in IIS (depending on your version). If you're using IIS Express for running it locally, then you can skip this step on your development machine.
Then enable the use of Windows Authentication in your website by modifying your web.config file. Add this under the <system.web> tag:
<authentication mode="Windows" />
And add this under <system.webServer>:
<security>
<authentication>
<windowsAuthentication enabled="true" />
<anonymousAuthentication enabled="false" />
</authentication>
</security>
Then, as long as your website is trusted by the browser (step 2 above), you will automatically be logged in. The username of the logged on user will be User.Identity.Name. All of the code you show will work, however you don't need to call System.Web.Hosting.HostingEnvironment.Impersonate().
public bool CheckUserInGroup(string group)
{
string serverName = ConfigurationManager.AppSettings["ADServer"];
string userName = ConfigurationManager.AppSettings["ADUserName"];
string password = ConfigurationManager.AppSettings["ADPassword"];
bool result = false;
SecureString securePwd = null;
if (password != null)
{
securePwd = new SecureString();
foreach (char chr in password.ToCharArray())
{
securePwd.AppendChar(chr);
}
}
try
{
ActiveDirectory adConnectGroup = new ActiveDirectory(serverName, userName, securePwd);
SearchResultEntry groupResult = adConnectGroup.GetEntryByCommonName(group);
Group grp = new Group(adConnectGroup, groupResult);
SecurityPrincipal userPrincipal = grp.Members.Find(sp => sp.SAMAccountName.ToLower() == User.Identity.Name.ToLower());
if (userPrincipal != null)
{
result = true;
}
}
catch
{
result = false;
}
return result;
}
I believe there are many ways on how we can retrieve AD users from C# MVC. http://www.codedigest.com/posts/5/get-user-details-from-active-directory-in-aspnet-mvc please take a look at this good example using the galactic API(free and open source package).
I have an MVC5 web app that I utilize the following to obtain current user info. I have enabled windows login for the web app on IIS.
private readonly string _userName = UserPrincipal.Current.DisplayName;
item.CreatedBy = _userName;
This works when running the app on my development machine, however when I publish to IIS, it throws exceptions:
The
(&(objectCategory=user)(objectClass=user)(|(userPrincipalName=)(distinguishedName=)(name=)))
search filter is invalid.
How do I get this to work on the IIS server to correctly obtain user info?
BTW - I've also tried this:
private readonly PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
var user = UserPrincipal.FindByIdentity(ctx, User.Identity.Name);
item.CreatedBy = user.DisplayName;
but to no avail.
This may be what you mean by "I have enabled windows login for the web app on IIS", but confirm that you have Windows Authentication enabled on IIS itself. Details on what's going wrong in your "to no avail" case may also be helpful.
Looks like anonymous authentication was still enabled on the Default Web Site in IIS. I disabled, and now it works with the following code:
private readonly PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
var user = UserPrincipal.FindByIdentity(ctx, User.Identity.Name);
item.CreatedBy = user.DisplayName;
This is not necessarily an issue, I am just curious as to how it works. I have a method:
public static bool UserIsAuthenticated()
{
bool isAuthed = false;
try
{
if (HttpContext.Current.User.Identity.Name != null)
{
if (HttpContext.Current.User.Identity.Name.Length != 0)
{
FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicket ticket = id.Ticket;
isAuthed = true;
string MyUserData = ticket.UserData;
}
}
}
catch { } // not authed
return isAuthed;
}
The HttpContext.Current.User.Identity.Name returns null if the user does not exist, but how does it know which usernames exist or do not exist?
For windows authentication
select your project.
Press F4
Disable "Anonymous Authentication" and enable "Windows Authentication"
The HttpContext.Current.User.Identity.Name returns null
This depends on whether the authentication mode is set to Forms or Windows in your web.config file.
For example, if I write the authentication like this:
<authentication mode="Forms"/>
Then because the authentication mode="Forms", I will get null for the username. But if I change the authentication mode to Windows like this:
<authentication mode="Windows"/>
I can run the application again and check for the username, and I will get the username successfully.
For more information, see System.Web.HttpContext.Current.User.Identity.Name Vs System.Environment.UserName in ASP.NET.
How does [HttpContext.Current.User] know which usernames exist or do
not exist?
Let's look at an example of one way this works. Suppose you are using Forms Authentication and the "OnAuthenticate" event fires. This event occurs "when the application authenticates the current request"
(Reference Source).
Up until this point, the application has no idea who you are.
Since you are using Forms Authentication, it first checks by parsing the authentication cookie (usually .ASPAUTH) via a call to ExtractTicketFromCookie. This calls FormsAuthentication.Decrypt (This method is public; you can call this yourself!). Next, it calls Context.SetPrincipalNoDemand, turning the cookie into a user and stuffing it into Context.User (Reference Source).
Assume a network environment where a "user" (aka you) has to logon. Usually this is a User ID (UID) and a Password (PW). OK then, what is your Identity, or who are you? You are the UID, and this gleans that "name" from your logon session. Simple! It should also work in an internet application that needs you to login, like Best Buy and others.
This will pull my UID, or "Name", from my session when I open the default page of the web application I need to use. Now, in my instance, I am part of a Domain, so I can use initial Windows authentication, and it needs to verify who I am, thus the 2nd part of the code. As for Forms Authentication, it would rely on the ticket (aka cookie most likely) sent to your workstation/computer. And the code would look like:
string id = HttpContext.Current.User.Identity.Name;
// Strip the domain off of the result
id = id.Substring(id.LastIndexOf(#"\", StringComparison.InvariantCulture) + 1);
Now it has my business name (aka UID) and can display it on the screen.
Also check that
<modules>
<remove name="FormsAuthentication"/>
</modules>
If you found anything like this just remove:
<remove name="FormsAuthentication"/>
Line from web.config and here you go it will work fine I have tested it.
Actually it doesn't! It just holds the username of the user that is currently logged in. After login successful authentication, the username is automatically stored by login authentication system to "HttpContext.Current.User.Identity.Name" property.
To check if the current user is authenticated, you MUST (for security reasons) check "HttpContext.Current.User.Identity.IsAuthenticated" boolean property that automatically holds this information instead of writing your own code.
If the current user is NOT authenticated, "HttpContext.Current.User.Identity.Name" property will be null or an empty string or "can take other values" (https://learn.microsoft.com/en-us/dotnet/api/system.security.principal.iidentity.name?view=netframework-4.8) obviously depending on the authentication mode used.
See: https://learn.microsoft.com/en-us/dotnet/api/system.security.principal.iidentity?view=netframework-4.8
Windows authentication gives the information about the user who is logged in. Here is how to set the windows authentication in your project:
you can select project from the menu bar, select yourProject Properties, select Debug, and check the "Enable Windows Authentication" as the image below,
then you will be able to know the user who is logged in by running this code in any controller
var strUserName = User;
Here is the problem, I am using IIS7 inorder to host my asp.net web site , Now the thing is no matter what method is used, I am always getting the app pool identity as the current logged on user (authentication mode is windows). The following are the pieces of code i used to get the logged on user(all of them return the app pool identity).
WindowsIdentity.GetCurrent().Name
Convert.ToString(Request.ServerVariables["LOGON_USER"])
WindowsPrincipal p.Identity.Name
Convert.ToString(Request.ServerVariables["AUTH_USER"]).Trim()
Please help me regarding this cause this is troubling me a lot.
You should use asp.net impersonation:
http://support.microsoft.com/kb/306158
http://msdn.microsoft.com/en-us/library/aa292118%28v=vs.71%29.aspx
http://msdn.microsoft.com/en-us/library/ff647076.aspx
<identity impersonate="true" />
---UPDATE----
look at IIS configuration:
ASP.NET impersonation problem
----Update 2 ----
public string GetLoggedUserName()
{
string rtn = string.Empty;
if (CurrentContext.User != null)
{
if (CurrentContext.User.Identity.IsAuthenticated)
{
var gp = CurrentContext.User as WindowsIdentity;
if (gp!=null)
{
rtn = gp.Identity.Name;
}
}
}
return rtn;
}
Thanks for all the information. The problem was due to some kind of bug in the ASP.NET , What I was doing is that I was redirecting from default.aspx to Home.aspx in the web application but the problem was that after redirection some how the logged in user information was being lost. So I changed the home page to Home.aspx and stored all the required information there and now it is working perfectly.
Thanks giammin for your help , really appreciate it/.
I have a strange scenario that I hope you guys can help with, I need to validate the current logged in user with active directory, this isn't a problem if they are on the network but in some instances they will be on another network (visiting clients) and in order for them to use the software they need to validate against AD.
At present I am using the following code am I correct in saying this will work locally and remotely? If not how can I get it to validate credentials?
DomainServer = new ActiveDirectory(Microsoft.Exchange.WebServices.Data.ExchangeVersion.Exchange2010, "LDAP://DOMAIN.NAME", "https://exchange.domain.name/ews/exchange.asmx");
DomainServer.connect();
if (!DomainServer.isConnected())
{
domain_errors = "Unable to connect to Active Directory.";
}
class ActiveDirectory
{
private ExchangeService _ExchangeServer;
private DirectoryEntry _searchRoot;
private DirectorySearcher _search;
private SearchResult _searchresult;
private ExchangeVersion _ExchangeVer;
private string _ActiveDirectoryAddress;
private string _ActiveDirectoryURL;
public ActiveDirectory(ExchangeVersion Ver, string ActiveDirectoryAddress, string ActiveDirectoryURL)
{
_ActiveDirectoryURL = ActiveDirectoryURL;
_ActiveDirectoryAddress = ActiveDirectoryAddress;
_ExchangeVer = Ver;
}
public void connect()
{
_ExchangeServer = new ExchangeService(_ExchangeVer);
_ExchangeServer.UseDefaultCredentials = true;
_ExchangeServer.Url = new Uri(_ActiveDirectoryURL);
_ExchangeServer.Timeout = 60;
}
public bool isConnected()
{
if (_searchRoot.Properties.Count > 0){
return true;
} else {
return false;
}
}
}
Windows caches usernames and passwords on local machines so that a domain user can login even if the machine, such as a laptop, is not connected to the domain. Since Windows is essentially handling the authentication for you, all you really need to do is authorize who can use the software. I can think of a few possibilities.
First, in the database, you could maintain a user table with the SIDs and usernames of those users with access to the software. When a user executes the program, check that the SID of the currently logged in user is in that table. This way, you can restrict what users can actually execute the software without connecting to Active Directory. This would also allow you to revoke access at the database level.
Secondly, does the database server have access to the Active Directory? If so, create a group in AD for users with access to this system, then grant that group access in the database. Set the database connection to use Windows authentication. Therefore, if the person is in that group, they have access to the database. Otherwise, they do not. Then, you can control access just by adding or removing them from that group and security will be controlled at the database level.
Third (and I'm not a fan of this one), if you have a web server, run a web service (using HTTPS of course) that accepts a username and password and then use that web service to connect through your firewall and authenticate against AD. Then, just return a result to your application. This presents some security concerns with passing credentials to a web service and opening connections through the firewall.