Developer forum

Forum » Development » Authenticate user through API

Authenticate user through API

Dmitrij Jazel
Reply

Hi guys,

Have an issue, not sure what is wrong.

1) When someone requests website with a specific parameter, F.eks: http://mysite.com/whateverpage.aspx?userref=12345

In live example there will be much more to that and security is taken seriously, but to make example simple, I am using this url above.

Here userref is userID of the user I will eventually have to authenticate.

2) in API I am using this method:


[Subscribe(Dynamicweb.Notifications.Standard.Page.Loaded)]
public class PageLoaded : NotificationSubscriber
{
    public override void OnNotify(string notification, Dynamicweb.Extensibility.NotificationArgs args)
    {
        if (args == null)
            return;

        var userref = HttpContext.Current.Request.QueryString["userref"]; 
        var userid_int = Convert.ToInt32(userref);
        var user = User.GetUserByID(userid_int); 
        var security = new Dynamicweb.Security(); 
        security.ExtranetLogin(user.UserName, user.Password); 

        HttpContext.Current.Items["pageload_debug"] = string.Format("user {0} should be authenticated",user.UserName); 

    }
}

And I am getting message that my user should be authenticated, but in front-end that is not beying reflected. Not sure why.

3) I am sure user is able to login to this site and that page, and all extranet is configured correctly.

 

My question is: Am I doing something wrong in API? Am I using correct NotificationSubscriber, or should I use something else?

 

/Dmitrij


Replies

 
Nicolai Høeg Pedersen
Reply

If your users passwords are encrypted in the database, you cannot do this... User.Password would contain an encrypted string which cannot be used for authenticatioin.

Basically you cannot login a user without there password - you can use a pwtoken (?username=usr&pwtoken={token}) - but the token is based on the password, so if you do not have that, you cannot do it like this.

You can however, update the accessusertable with a password your code knows, i.e. "whateverpasswordstring" storing the original string from the password field in a local variable, login using security.ExtranetLogin(user.UserName, "whateverpasswordstring"), and put back the original password string. Risky but doable...

BR Nicolai

 
Dmitrij Jazel
Reply

Hi Nicolai,

Thanks for reply.

That makes sense, will give it a shot.

Regarding Notification subscriber:

Am I using correct NotificationSubscriber? Since we are playing with security here, NotificationSubscriber should not play that much difference here, right?

 

Regarding ExtranetLogin() method and Token:

Ok, if password is actually what is stored in DB (makes total sense), than something like this should work.

security.ExtranetLogin(user.UserName, "cc03e747a6afbbcbf8be7668acfebee5"); // that is actual encripted value from DB.

But that did not work.

Regarding the token, getting recoveryToken only, http://screencast.com/t/a4A6cWecJDU

But as you suggested, I should try sending it via url aswell? Not exactly sure how to use it.

The issue here could be that 3rd party service (that is going to use this) would not be able to send password along with this one. Here password cannot be "" or hardcoded as that user will be actively used to the actual user himself.

 

Some observations:

Too bad security.ExtranetLogin() returns Void. Would be great if it could return bool for login atempt sucseeded or failed.

Surrounded this method with try-catch but did not encounter any exceptions.

 

/Dmitrij

 

 

 

 
Dmitrij Jazel
Reply

Hi guys,

In case it is not clear what I am trying to achieve here:

1) I want to know how can you authenticate user in Dynamicweb API.

2) Can notification subscriber somehow affect "security.ExtranetLogin(user.UserName, user.Password);", if Yes - than would like to know what Notifications do Affect, and how.

Or what Notification subscriber you would recomend using.

3) Are there any other reasons why "security.ExtranetLogin(user.UserName, user.Password);" would not authenticate a user, if I would try executing this in Runtime?

 

Hope this makes a bit more clear what I am trying to achieve here.

 

/Dmitrij

 
Nicolai Høeg Pedersen
Reply

Dw executes security.ExtranetLogin in runtime, so it works.

But as I said, if you pass in a hashed string, i.e. cc03e747a6afbbcbf8be7668acfebee5, it will not authenticate. You need the original password string like "MySecretPassword" to use that method.

So, if you in whatever notification subscriber, reacts on if request("userref") has a value, lookup username for the user, then update password column for that user with a temp password, i.e. "Dmitrijstemppassword", and calls ExtranetLoing(usernameFromDatabase, "Dmitrijstemppassword") it should work.

BR Nicolai

 
Dmitrij Jazel
Reply

Hi Nicolai,

Thanks for that info, it helped! :-)

Atleast now I know that I have to provide un-hashed password into the password fiend.

And now I know that user.Password returns Hash of the password, and not the password itself.

 

Here I bump into another issue.

How can I get not hashed password without compromising the security? Or without leaving passwords in clear text?

 

The requirenment is that user (3rd party service) is going to sent "userref=12345" through URL and this should be enough to authenticate the user.

User can also send additional URL parameters if neccesery. But we can't allow passwords be unhashed in DB, and we can't allow creating "Duplicate user" work arround.

 

One way or another, would be great to hear some solutions options for this.

Appreciate your help guys :-)

 

/Dmitrij

 
Nicolai Høeg Pedersen
Reply

Hi Dmitrij

You cannot get the unhashed passwords - hashing is a one way operation and has been chosen for security reasons. If it was just encrypted in a manner that it could be unecnrypted, we would not be far...

And still - to solve your issue, just do what I describe - it will work.

A login that relies solely on the userid is a giant security hole, and I recommend that you do something else.

 
Dmitrij Jazel
Reply

Ok, so basically what you suggested was something like this, right?

string username = user.username;
string token = HttpContext.Current.Request.QueryString["token"]; // password is "hidden" here.
string password = recoverPassword(token); // Recover hidden password from token.
security.ExtranetLogin(user.UserName, password);
// Bingo, now we are loggedin.

If your answer is yes - that's right. Than here is why this would fail.

1) As I mentioned before, it's a 3rd party service that will have to "use url" and than route it for it's users towards our site.

2) Those are real user accounts for day-to-day users. And those users would use website, and possibly update their passwords, than this would require updating (notifying) 3rd party service about the password change, and that's not really possible.

3) I can include a static URl parameter in URL, but I can't realy make that 3rd party to do some password hiding/hashing for me.

 

At the same time I totally understand what risks associated with it. Simply allowing someone loggin just by providing correct URL. User access is not something that should be granted simply by providing correct static URL.

Well, yes but if that what customer is asking, Not sure how to go arround this than.

 

 

But if we imagine that this actually is implemented, and  IF someone WOULD be able to login as that user - what would be the worst thing that could happen?

 

IMHO It's not like this user (when loggedin) could get this user password (cause it's safe encrypted in DB and never exposed, and not hidden in some string pattern that is probably possible to guess/predict (maybe)) or somehow steal any other user sensetive data. Unless there is something very serious about this, why you would not do that under any circumstances. I would very much like to hear them out.

 

The passwords of other users are not accessible. No access to Backend. Worst thing Hacker could do would be to - attempt placing "false order". That could be easilly get tracked, and removed. It's B2B solution. What else can hacker create, if he (let us imagine) loggsin to as a user, that only has front-page access.

 

If you are worried for the implementation I provided for this exmple (see my first post) I simplyfied it for the sake of example. In reality there would be a special code that would define what user I need to pull from the DB, and it's not DW AccessUserID - it's something else, but the idea is the same...

 

And Lastly, Speaking of possibilities and security in DW in general.

(my personal oppinion) I think that allowing AccessUserPassword to be Unhashed/Unencrypted represents probably the biggest risk there can be.

Can't imagine what is worser than keeping password (ALL user passwords) in cleartext in DB. http://screencast.com/t/KGKy9Na7dlvb

 

What I am trying to say here is: If this is allowed, than why can't we allow users to login through url, or just somehow authenticate in API without known password.

 

/Dmitrij

 

 
Nicolai Høeg Pedersen
Reply
This post has been marked as an answer

Hi

That was not my suggestion. This is:

var userref = HttpContext.Current.Request.QueryString["userref"];
var userid_int = Convert.ToInt32(userref);
var user = User.GetUserByID(userid_int);
var originalPasswordStringFromDatabase = user.Password;
user.Password = "DmitrijsSecretTempPassword";
user.Save();
var security = new Dynamicweb.Security();
security.ExtranetLogin(user.UserName, "DmitrijsSecretTempPassword");
user.Password = originalPasswordStringFromDatabase;
user.Save();

Having a login that supports just the user id is even worse than having the passwords in clear text. We offer that option because some need it - like you in this case.

NP

string token = HttpContext.Current.Request.QueryString["token"]; - See more at: http://developer.dynamicweb.com/forum/development/development/authenticate-user-through-api.aspx#sthash.tIpVFB7Q.dpuf
Dmitrij
Dmitrij
Dmitrij
Votes for this answer: 1
 
Dmitrij Jazel
Reply

Hi Nicolai,

Thanks for bearing with me on this one.

"Having a login that supports just the user id is even worse than having the passwords in clear text. We offer that option because some need it - like you in this case"

Totally agree, that is why i said in my previous post.

"If you are worried for the implementation I provided for this exmple (see my first post) I simplyfied it for the sake of example."

So that is not the case, I assure you. Besides there is way more logic that is implemented into this method.

 

But still I will try discussing more possibilities/alternatives arround this with customer. To make it more secure.

 

Regarding your example, that is exactly what we needed. A bit interesting :-) with double user password update :-)

But that will do for now, pretty sure.

Thanks allot for help! :-)

 

/Dmitrij

 

You must be logged in to post in the forum