How to Get Current User Principal - asp.net

I want to use Windows Authentication and get User info such as Givenname, Surname, etc.
I used UserPrincipal.Current in IIS and I got an exception, but IIS express looks fine.

I solved by using a Find Method:
var domain = new PrincipalContext(ContextType.Domain);
var currentUser = UserPrincipal.FindByIdentity(domain, User.Identity.Name);

Related

How to get IdentityUser by Username

I have previously worked with Membership through "System.Web.Security.Membership"
Here, you can do the following:
var currentUser = Membership.GetUser();
var otherUser = Membership.GetUser(username);
...giving you a MembershipUser.
Now, with Identity, I can find a load of ways to get the current logged in user.
But no way to get another user.
I can use:
var userStore = new UserStore<IdentityUser>();
var userManager = new UserManager<IdentityUser>(userStore);
var user = userManager.Find(username, password);
But that takes both username and password, with no overload for just username.
How do i get the IdentityUser from only a username?
Almost every answer I find is connected to MVC.
This is for a WCF service, where authorization is made using Identity. And in some cases the user is getting to the site from an other site with a generated "token" - an encrypted string, containing the username. From here, user is logged in and a session-cookie is set, depending on users settings.
Also, is there a shorter way to get UserInformation?
"var currentUser = Membership.GetUser(username);"
is much more convenient than
"var user2 = (new UserManager((new UserStore()))).Find(username, password);"
UserManager has UserManager<TUser>.FindByNameAsync method. You can try using it to find user by name.

SharePoint High trust provider hosted app - user impersonation - Site minder

We are using SiteMinder to authenticate user but all we get from site minder is user identity in header:
ASP.NET Authentication with Siteminder
However since we are using high trust provider hosted SharePoint app we have access to tokenHelper.cs but impersonating a user requires System.Security.Principal.WindowsIdentity
My questions are:
How to get WindowsIdentity in this case?
OR
How to extend tokenHelper to impersonate user just with user identity(without windowsIdentity)?
Check this blog by Steve Peschka. I have set up provider hosted app in SiteMinder protected SharePoint 2013 using that blog. To impersonate a user you need to create a ClaimsIdentity of the user and insert it to the HttpContext as current user. Sample code for that below:
var identity = new ClaimsIdentity(AuthenticationTypes.Federation, "http://schemas.xmlsoap.org/claims/useridentifier", String.Empty);
identity.AddClaim(new Claim("http://schemas.xmlsoap.org/claims/useridentifier", userId, "http://www.w3.org/2001/XMLSchema#string"));
identity.AddClaim(new Claim(ClaimTypes.Email, smtp, "http://www.w3.org/2001/XMLSchema#string"));
identity.AddClaim(new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sip", nameIdentifier, "http://www.w3.org/2001/XMLSchema#string"));
ClaimsPrincipal principal = new ClaimsPrincipal(identity);
Set this ClaimsPrincipalas the Httpcontext user.
The claim values to be passed are smtp= email of user , nameidentifier=loginname of user , userId= Account name of user
I will explain above scenario with my SP+Siteminder environment.
First of all you cant get the ClientContext of the site which is protected by site-minder.
You can only get clientContext of the site using internal url of site [http://hostname:port/sites/xyz].
To get the currenct user :-
var spContext = SharePointContextProvider.Current.GetSharePointContext(HttpContext);
// We store internal url of webapplication in web.config
string strAdminSiteURL = ConfigurationManager.AppSettings["AdminSiteURL"].ToString();
// We have written one function to convert site-minder url to internal url
string webUrl = Helper.Helper.GetInternalSiteUrl(strAdminSiteURL, spContext.SPHostUrl.ToString());
// Use internal url to create client-context
using (ClientContext clientContext = new ClientContext(webUrl))
{
clientContext.AuthenticationMode = ClientAuthenticationMode.FormsAuthentication;
clientContext.FormsAuthenticationLoginInfo = new FormsAuthenticationLoginInfo(uName, pswd);
Web web = clientContext.Web;
clientContext.Load(web);
clientContext.ExecuteQuery();
// Load SP user from login name found from httpcontext
string currentSPUser = string.Concat("<<FBAIdentity>>", User.Identity.Name);
var currentUser = clientContext.Web.EnsureUser(currentSPUser);
clientContext.Load(currentUser);
clientContext.ExecuteQuery();
}
above code will work fine if authentication mode is FBA and will help you in getting current user.

Cannot acces users Active Directory password information on production server

I'm developing an MVC application and I have a routine that gets the currently logged on users password info and it works fine on my PC but when I publish my application to a live server on the domain, I don't seem to be able to gain access to the AD information. I have used very similar code in a currently running asp.net web application and it works just fine. I compared security settings on both applications and they look identical. Here is the routine:
public int GetPasswordExpiration()
{
PrincipalContext domain = new PrincipalContext(ContextType.Domain);
string currUserName = WindowsIdentity.GetCurrent().Name;
UserPrincipal currLogin = UserPrincipal.FindByIdentity(domain, currUserName);
DateTime passwordLastSet = currLogin.LastPasswordSet.Value; //here is where it chokes***
int doyPasswordSet = passwordLastSet.DayOfYear;
int doy = DateTime.Today.DayOfYear;
int daysSinceLastset = (doy - doyPasswordSet);
int daysTilDue = (120 - daysSinceLastset);
return (daysTilDue);
}
I am an administrator on the domain so I think I have an application permissions issue, but since the failing application has the same permissions as the working application, I'm not sure where to look next. Any help is appreciated.
I'm answernig my own question because I want to post the code that works. Wiktor Zychla nailed it when asking if WindowsIdentity.GetCurrent().Name applied to the identity of the application pool rather than the logged in user. As a matter of fact it did, thanks Wiktor!
Here is the modified code that works. I did change the way I got the users identity (explained why below).
Controller Code:
using MyProject.Utilities; // Folder where I created the CommonFunctions.cs Class
var cf = new CommonFunctions();
string user = User.Identity.Name;
ViewBag.PasswordExpires = cf.GetPasswordExpiration(user);
Code in CommonFunctions
public int GetPasswordExpiration(string user)
{
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
UserPrincipal currLogin = UserPrincipal.FindByIdentity(ctx, user);
DateTime passwordLastSet = currLogin.LastPasswordSet.Value;
int doyPasswordSet = passwordLastSet.DayOfYear;
int doy = DateTime.Today.DayOfYear;
int daysSinceLastset = (doy - doyPasswordSet);
int daysTilDue = (120 - daysSinceLastset);
return (daysTilDue);
}
The one thing that clued me in was that I decided to just run all the code in my controller and when I did, I got a red squiggly saying "The name WindowsIdentity does not exist in this context":
string currUserName = WindowsIdentity.GetCurrent().Name;
Also, the reason I retrieved User.Identity.Name in the Controller and passed it to the function is because once I got things working and wanted to thin out my controller, I tried to get User.Identity.Name in the function but I got another red squiggly with the same message under User in this line:
string user = User.Identity.Name;
So I figure this is a .net thing and just went with getting the User.Identiy.Name in the controller, pass it to the function and all is well. This one really tested my patience and I hope this post can help someone else.

Trying to get Facebook Cookie from codebehind, but is getting (OAuthException)

I am using Facebook C# SDK on my site, and is trying to access the cookie made by Facebook when the user has chosen to use Facebook as login, but I am getting the following error:
(OAuthException) An active access token must be used to query
information about the current user.
Here is the code I am using:
var client = new FacebookClient([App ID], [App Secret]);
dynamic me = client.Get("me");
string firstName = me.first_name;
Response.Write(firstName);
What am i doing wrong?
Thanks in advance
You need to authorize first before trying to access the user. This does the necessary redirects and plumbing to have Facebook set the cookie.
var auth = new CanvasAuthorizer { Permissions = new string[] {"user_about_me"} };
if (auth.Authorize()) {
var client = new FacebookClient([App ID], [App Secret]);
dynamic me = client.Get("me");
string firstName = me.first_name;
Response.Write(firstName);
}

Active Directory Authentication

I am have made one web application in asp.net.In my project Authentication was done by matching the username and password in database.But now client ask me for the auto login in application with the help Of Active Directory authentication. Client ask suggest me to use the Email Id of user in AD for the authentication.
I tried to fetch the records in the AD, I could fetch the Fullname of user but I couldn't get the Email id,
I tried the code:
System.Security.Principal.WindowsIdentity wi = System.Security.Principal.WindowsIdentity.GetCurrent();
string[] a = Context.User.Identity.Name.Split('\\');
System.DirectoryServices.DirectoryEntry ADEntry = new System.DirectoryServices.DirectoryEntry("WinNT://" + a[0] + "/" + a[1]);
string Name = ADEntry.Properties["FullName"].Value.ToString();
Further more I Use DirectorySearcher but it genterates Error that Coulnot search the record in the client server..
I had the exact same situation while making a portal for a company.
If they dont want you to get into their AD then what you can do is to request for the NTLogins of the people who will be given access to the portal. make a simple table which have their NTLogin and simply authenticate using the system from which the portal is being accessed.
Check out the sample code i used.
// Checking if the user opening this page is listed in the allowed user list against their NT login.
String sUser = Request.ServerVariables["LOGON_USER"].ToLower();
sUser = sUser.Replace("wt\\", "");
//Authentication using a custom auth method.
DatabaseOperations authenticateUser = new DatabaseOperations();
if (!authenticateUser.authenticate(sUser))
{
//unauthorized users will be redirected to access denied page.
Server.Transfer("AccessDenied.aspx", true);
}
And making sure that you have authentication mode to windows in your web.config file
<authentication mode="Windows"></authentication>
Hope this helps.
For reading AD data, i use this class. It is setup for our AD, but basically you can just pass in all the "fields" you want to find, in the params.
But you need to know what field holds the email address. Sysinternals made a pretty good tool for browsing AD, to figure out what you are looking for, called ADExplorer.
But I don't understand why you need to look in the AD? Can you not assume that the user is already authenticated, if they are on the network, and then rely on the windows identity?
public static Hashtable GetAttributes(string initials, params string[] Attribute)
{
DirectoryEntry directoryEntry = new DirectoryEntry("LDAP://ADNAME");
DirectorySearcher ADSearcher = new DirectorySearcher(directoryEntry);
ADSearcher.Filter = "(sAMAccountName=" + initials + ")";
foreach (string para in Attribute)
{
ADSearcher.PropertiesToLoad.Add(para);
}
SearchResult adSearchResult = ADSearcher.FindOne();
Hashtable hshReturns = new Hashtable();
foreach (string para in Attribute)
{
string strReturn = "";
if (adSearchResult.Properties[para].Count == 0)
strReturn = "";
else
strReturn = ((ResultPropertyValueCollection)adSearchResult.Properties[para])[0].ToString();
hshReturns.Add(para, strReturn);
}
return hshReturns;
}

Resources