Unable to get logon user no matter what procedure is used - c#

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/.

Related

Why does testing the user's group membership not produce the expected result?

Please check the following code.
WindowsIdentity identity = HttpContext.Current.Request.LogonUserIdentity;
WindowsPrincipal principal = new WindowsPrincipal(identity);
bool result = Principal.IsInRole("Active Directory Group Name");
if(result == true)
{
// Able to access the page
}
else
{
// No access to this page
}
I have a pin in my organization and it is added to "Active Directory Group". Now, I am able to access the pages in the localhost. I made some changes in the code and deployed code in DEV and trying to access the pages in DEV to test the application. In DEV, I was unable to access the pages. It is supposed to execute the if block but instead executes the else block.
Could you please help me with:
Where is security blocking me?
What else do I have to make sure of?

C# Get Logged in user email address from logged in user in Active Directory, IIS

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).

How does HttpContext.Current.User.Identity.Name know which usernames exist?

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;

IAuthenticationResponse.GetExtension<ClaimsResponse>() always returning null

Update
Thanks to a comment by #IvanL, it turns out that the problem is Google specific. I have since tried other providers and for those everything works as expected. Google just doesn't seem to send claims information. Haven't yet been able to figure out why or what I need to differently to get Google to send it.
A wild stab in the dark says it may be related to the realm being defaulted to http://:/ as I have seen an answer by Andrew Arnott that Google changes the claimed identifier for the same account based on the realm passed with the authentication request.
Another possibly important tidbit of information: unlike many of the examples that can be found around the web for using dotnetopenauth, I am not using a "simple" textbox and composing the openIdIdentifier myself, but I am using the openID selector and that is providing the openIdIdentifier passed to the ValidateAtOpenIdProvider. (As per the Adding OpenID authentication to your ASP.NET MVC 4 application article.)
Question is: why is IAuthenticationResponse.GetExtension() always returning null when using Google as the openId provider, when otherwise all relevant gotcha's with regard to Google (Email requested as required, AXFetchAsSregTransform, etc) have been addressed?
Original
I am struggling with getting DotNetOpenAuth to parse the response returned from the provider. Followed the instructions of Adding OpenID authentication to your ASP.NET MVC 4 application up to the point where the login should be working and a login result in a return to the home page with the user's name (nick name) displayed at the top right. (That is up to "The user should at this point see the following:" just over half way down the article).
I am using Visual Studio Web Developer 2010 Express with C#. DotNetOpenAuth version is 4.0.3.12153 (according to the packages.config, 4.0.3.12163 according to Windows Explorer).
My web.config was modified following the instructions in Activating AXFetchAsSregTransform which was the solution for DotNetOpenId - Open Id get some data
Unfortunately it wasn't enough to get it working for me.
The openid-selector is working fine and resulting in a correct selection of the openid provider. The authentication request is created as follows:
public IAuthenticationRequest ValidateAtOpenIdProvider(string openIdIdentifier)
{
IAuthenticationRequest openIdRequest = openId.CreateRequest(Identifier.Parse(openIdIdentifier));
var fields = new ClaimsRequest()
{
Email = DemandLevel.Require,
FullName = DemandLevel.Require,
Nickname = DemandLevel.Require
};
openIdRequest.AddExtension(fields);
return openIdRequest;
}
This all works. I can login and authorize the page to receive my information, which then results in a call to GetUser:
public OpenIdUser GetUser()
{
OpenIdUser user = null;
IAuthenticationResponse openIdResponse = openId.GetResponse();
if (openIdResponse.IsSuccessful())
{
user = ResponseIntoUser(openIdResponse);
}
return user;
}
openIdResponse.IsSuccessful is implemented as an extension method (see linked article):
return response != null && response.Status == AuthenticationStatus.Authenticated;
and always is successful as the ResponseIntoUser method is entered:
private OpenIdUser ResponseIntoUser(IAuthenticationResponse response)
{
OpenIdUser user = null;
var claimResponseUntrusted = response.GetUntrustedExtension<ClaimsResponse>();
var claimResponse = response.GetExtension<ClaimsResponse>();
// For this to work with the newer/est version of DotNetOpenAuth, make sure web.config
// file contains required settings. See link for more details.
// http://www.dotnetopenauth.net/developers/help/the-axfetchassregtransform-behavior/
if (claimResponse != null)
{
user = new OpenIdUser(claimResponse, response.ClaimedIdentifier);
}
else if (claimResponseUntrusted != null)
{
user = new OpenIdUser(claimResponseUntrusted, response.ClaimedIdentifier);
}
else
{
user = new OpenIdUser("ikke#gmail.com;ikke van ikkenstein;ikke nick;ikkeclaimedid");
}
return user;
}
My version above only differs from the code in the linked article by my addition of the final else block to ensure that I always get the home page with a user name and a logoff link displayed (which helps when trying to do this several times in succession).
I have tried both Google and Yahoo. Both authenticate fine, both return an identity assertion as logged by the WebDev server. However, GetUntrustedExtenstion and GetExtension always return null. I always get to see "ikke nick" from the last else, never the name I actually used to authenticate.
I am at a loss on how to continue to try and get this to work. It probably is some oversight on my part (I am an experienced developer but just started dipping my toes in C# and web front-end development), and I can't see it.
Any and all suggestions on how to proceed / debug this are very much welcome.
Are you using Google as OpenId provider to test your solution against? Because Google has/had the habit of including the Claims only the first time you authenticate the application. So perhaps try using a fresh google account and see if that works?
Sorry for the slow response, doing a big migration at a client this week :-) Glad that this little comment resolved your issue.

getting domain\username for web app on intranet without logging in

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

Categories

Resources