How do I get the username using DotNetOpenAuth with Google - c#

I have an ASP.NET MVC project that uses DotNetOpenAuth as authentication provider. How do I get the username (or email address) when the user logs using https://www.google.com/accounts/o8/id?
switch (response.Status)
case AuthenticationStatus.Authenticated:
string userOpenId = response.FriendlyIdentifierForDisplay;
break;
(...)

I hope your userOpenId local variable isn't what you're using for a username, because as the property you're assigning it from is aptly named, it's for display only. You should only use IAuthenticationResponse.ClaimedIdentifier for usernames.
That aside, you can get the Google email address (you can never get the username) by sending a FetchRequest for email marked as a required attribute. This has been asked many times already, for instance this one.

Related

Different username and email causes login to fail in ASP NET CORE 2.1

I'm working on a solution using ASPNET Core 2.1 with Individual autentication. I was able to implement a seed class which creates the Identity roles, the admin user and assigns a role to the admin user when the host runs for the first time. After the first run, I check the database and everything is working fine. I don't like the 'Hello, userdummy#domain.com' welcome format message so I intend to change this in the future switching from email format to something more friendly as a username. Because of that, I use a different username from email address. When I assign this different username, login fails, but if I switch back to email-email for username and email fields, login works. I want a different username from email address. Any ideas about why is that happening?
This is the piece of code in my seed class which creates a new user:
if (!_dbContext.Users.Any()) // if users table is empty
{
// instantiate a user-store class
var _userStore = new UserStore<IdentityUser>(_dbContext);
// create a new user object with a different username
var admin = new IdentityUser
{
Email = "admin#admin.com",
UserName = "Administrador" // it makes login to fail
};
try
{
// ask the store-guy to create a new admin user with the given ridiculous password :D
var result = await _userStore.CreateAsync(admin,"123456");
}
catch (System.Exception ex)
{
_logger.Error(ex, "Sorry. Something went wrong here.");
}
}
If I change the username to have the same string than the email address, I can login with no problems.
I don't want to login using username. I want to login using email address but show a different string, like a name, in welcome message.
The default convention is for an IdentityUser to login against the 'UserName` field.
You can allow an email address as a username by turning off "AllowOnlyAlphanumericUserNames"
UserManager.UserValidator = new UserValidator<TUser>(UserManager) { AllowOnlyAlphanumericUserNames = false }
See answer and usage here
As a final solution to my question, guided by the help of you guys, would be either change the validation rules for registration and sign-in forms to point to UserName (the real field being checked against User table) or try to create a claim and use it as the name to be shown in welcome and other messages. This last one would be a valid, simple and harmless workaround. Thank you all.

Find User mailbox GUID using their email address EWS

I am working on Outlook add-in and doing some Encryption and Decryption. I created some hashed string on the server during POST request. That string is later passed to GET request and on the server I need to compare that hashed string to see if the user is the same user who did POST request.
When I make a GET request I also send user smtp using Office.context.mailbox.userProfile.emailAddress.
Question: How can find user mailboxGUID(or account information which will include mailboxGUID and more) using their email address?
Do you want the AD/Directory GUID or the ExchangeGUID ? you can get the ADGuid using ResolveName and specifying the property set (this works from 2010 up) eg
PropertySet exProp = new PropertySet(BasePropertySet.FirstClassProperties);
NameResolutionCollection ncCol = service.ResolveName("user#domain.com", ResolveNameSearchLocation.DirectoryOnly, true, exProp);
if (ncCol.Count == 1)
{
Console.WriteLine(ncCol[0].Contact.DirectoryId);
}
The MailboxGUID makes up part of the FolderId format so can be parsed out that https://msdn.microsoft.com/en-us/library/ee217297(v=exchg.80).aspx if you really need it.

How to integrate LDAP in WPF application that consumes WCF service

I will start by describing how my application works today without LDAP.
I have WPF application that consumes WCF services (authentication windows or UserName depends on users choice). This services allows communication with database.
I display to user a "Login screen" in order to allow him set her "user name" and "password" then application connects to service and consumes function that checks if UserName and Password exist in database. (see img below)
Now I need also to integrate LDAP for authenticating user accounts against their existing systems instead of having to create another login account.
I'm bit ignorant about LDAP and confused about many things. Please excuse the possible use of wrong terminology.
I googled but I still don't have answers of many questions.
1- What is the relation between users that exist in my database table "User" and profiles that I should be created in LDAP ?
2- What is the check I should do to allow user come from LDAP to access to my application and use all functionnalities of my service ?
3- Should I have service type "LDAP" like other authentications types I have today in my application ("Windows" and "UserName") ?
4- If I want to update my application architecture described in picture above where should I add LDAP ?
First I am going to answer your questions one by one,
The user on LDAP is the same on DB, you can hold LDAP's Username and it's domain in your Users Table,
but the profile on the LDAP may vary with your profile table, but it can be fetched from LDAP address.
It's enough to check username and password over LDAP, just need to hold LDAP addresses in a Table (example ExternalPath) and make a relation between User and ExternalPath tables. LDAP address is contains some specifications.
Yes, you have to have a separate mechanism for identifying LDAP Users which I will explain more further.
This is not hard if everything be atomic and designed right, in further steps you may see it is easy.
So let me tell about my experience in LDAP and Authenticate users on LDAP and DB and our architecture.
I was implemented a WCF service named Auth.svc, this service contains a method named AuthenticateAndAuthorizeUser this is transparent for user which came from LDAP or anywhere.
I hope you get the clue and architecture to Authenticate user over LDAP and DB in below steps:
1- First I have a table named Users which hold users info and one more field named ExternalPath as foreign key, if it is null specify UserName is in DB wit it's password otherwise it is came from UserDirectory.
2- In second step you have to hold LDAP address (in my case LDAP addresses are in ExternalPath table), all LDAP addresses are on port 389 commonly.
3- Implementing authenticate User, if is not found(with Username and Password) then check it's ExternalPath to verify over LDAP address.
4- The DB schema should be something like below screenshot.
As you can see ExternalPath field specify user is from LDAP or not.
5- In presentation layer I am defining LDAP servers like below screenshot also
6- In the other side while adding new user in system you can define LDAP for user in my case I am listing LDAP titles in a DropDown in adding User form (if admin select LDAP address then don't need to get password and save it in DB), as I mentioned just need to hold LDAP username not password.
7- But last thing is authenticating user on LDAP and DB.
So the authenticate method is something like:
User userLogin = User.Login<User>(username, password, ConnectionString, LogFile);
if (userLogin != null)
return InitiateToken(userLogin, sourceApp, sourceAddress, userIpAddress);
else//Check it's LDAP path
{
User user = new User(ConnectionString, LogFile).GetUser(username);
if (user != null && user.ExternalPath != null)
{
LDAPSpecification spec = new LDAPSpecification
{
UserName = username,
Password = password,
Path = user.ExternalPath.Path,
Domain = user.ExternalPath.Domain
};
bool isAthenticatedOnLDAP = LDAPAuthenticateUser(spec);
}
}
If userLogin does not exist in DB by entered UserName and Password then we should authenticate it over related LDAP address.
In else block find User from Users table and get it's ExternalPath if this field was not null means User is on LDAP.
8- The LDAPAuthenticateUser method is :
public bool LDAPAuthenticateUser(LDAPSpecification spec)
{
string pathDomain = string.Format("LDAP://{0}", spec.Path);
if (!string.IsNullOrEmpty(spec.Domain))
pathDomain += string.Format("/{0}", spec.Domain);
DirectoryEntry entry = new DirectoryEntry(pathDomain, spec.UserName, spec.Password, AuthenticationTypes.Secure);
try
{
//Bind to the native AdsObject to force authentication.
object obj = entry.NativeObject;
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = "(SAMAccountName=" + spec.UserName + ")";
search.PropertiesToLoad.Add("cn");
SearchResult result = search.FindOne();
if (null == result)
{
return false;
}
}
catch (Exception ex)
{
Logging.Log(LoggingMode.Error, "Error authenticating user on LDAP , PATH:{0} , UserName:{1}, EXP:{2}", pathDomain, spec.UserName, ex.ToString());
return false;
}
return true;
}
If exception raised in LDAPAuthenticateUser means User does not exist in User Directory.
The authentication code accepts a domain, a user name, a password, and a path to the tree in the Active Directory.
The above code uses the LDAP directory provider the authenticate method calls LDAPAuthenticateUser and passes in the credentials that are collected from the user. Then, a DirectoryEntry object is created with the path to the directory tree, the user name, and the password. The DirectoryEntry object tries to force the AdsObject binding by obtaining the NativeObject property. If this succeeds, the CN attribute for the user is obtained by creating a DirectorySearcher object and by filtering on the SAMAccountName. After the user is authenticated and exception not happened method returns true means user find on given LDAP address.
To see more info about Lightweight Directory Access Protocol and authenticate over it THIS Link can be useful which tells about specification more.
Hope will help you.

Login to different active directories programaticly in c#

The company that I work for has two active directories (ad1.com, ad2.com) because it has two different stores that had nothing to do with each other and plenty of users but now the managers of both stores need a page in common.
So I need to create a login where the users could access using just their Active Directory username and password.
In the login page there should be a list to choose the active directory and after that the user Paul(paul#ad1.com) and the user Paul(paul#ad2.com) with their respective password should be able to access to the page.
I have the code needed for the logIn page for one AD and works great but I don't know if it's possible to make the page available for two ADs.
Do I need some extra configuration on the server?
I google this but didn't find anything related.
If you have the code required for one AD, you could very well use the same code with slight modifications to authenticate against another AD.
Based on the domain name, you can identify the settings for AD and perform your authentication.
In cases where you use two AD, only identifying the domain name matters E.g.
ad1\username or username#ad1.com. You will not be able to achieve a login without the user specifying the domain name.
Have you tried using LDAP Authentication and just definining it differently based on the dropdown list?
Something like:
string adPath = string.Empty;
string domainName = string.Empty;
switch (ddlOption.ToString())
{
case "ad1":
adPath = "ad1Path";
domainName = "ad1";
break;
case "ad2":
adPath = "ad2Path";
domainName = "ad2";
break;
}
LdapAuthentication adAuth = new LdapAuthentication(adPath);
if (adAuth.IsAuthenticated(domainName, username, password))
{
//redirect Logic
}

How to tell if SPUser is Active Directory account

I'm working on a project where the client wants to restrict some content to only Active Directory users . Is there any way to identify that a SPUser is an AD user short of parsing the username string for the domain (or something along those lines). Something like SPUser.IsADUser would be awesome.
Edit
This seems to work, but I'm not sure if this is reliable enough? For this use case, identifying that a user is a windows user is enough (there are no local system accounts)
SPUser user = SPContext.Current.Web.CurrentUser;
string userName = user.LoginName.Substring(user.LoginName.IndexOf('|') + 1);
SPPrincipalInfo info = SPUtility.ResolveWindowsPrincipal(SPContext.Current.Site.WebApplication, userName, SPPrincipalType.User, false);
if(info != null){
//THIS IS A WINDOWS ACCOUNT
}
In my experience it is much better to use audiences for this purpose. You then can easily trim any web part using "Audience" property. You can read about audiences here. Of course it will only work if you have user profile synchronization configured.

Categories