Passing Authenticated-ness.



  • A large percentage of the people who use the system I am working on use this OtherSystem as well.  Recently, they've begun complaining that they have to log in to both systems separately.  So, the task at hand is to authenticate people in one system (mine), and then pass them over to OtherSystem already authenticated, so they don't have to go through a separate log in process (bunch of whiners).  Both systems are web sites, and mine is written in ASP .NET 2.0, if that matters.  I have no idea what OtherSystem is written in.


    I have an idea about how to go about accomplishing this, but I'd be interested to hear how you all think something like this should be done.  My main concern is the security of the process, whatever method is used.


    Here is my idea, which I basically have stolen from the way passing people from our system to the credit card payment processing site that we use works:

    When a user of MySystem wants to go to OtherSystem, they will click a button which will then generate a token of some sort that will be stored in my database and posted to OtherSystem.  When OtherSystem receives the user and the token, it will ask MySystem, "Hey!  This guy ok?  He's got this token here."  MySystem will then verify the token, and respond, "Yeah, he's cool.  Let him in," or, "INTRUDER!"  Once OtherSystem gets the ok from MySystem, it logs him in and lets him do whatever it is OtherSystem allows people to do.  Also, MySystem will then get rid of the token so that no one else can use it again.

     

    What do you all think? 



  • I think you shouldn't roll your own solution.

    If both applications are hosted in-house, you may look at sharing the forms authentication cookie between the two web applications.

    If they are not, take a look at Active Directory Federation Services (ADFS)...

    http://www.microsoft.com/WindowsServer2003/R2/Identity_Management/ADFSwhitepaper.mspx



  • @RaspenJho said:

    I think you shouldn't roll your own solution.

    If both applications are hosted in-house, you may look at sharing the forms authentication cookie between the two web applications.

    If they are not, take a look at Active Directory Federation Services (ADFS)...

    http://www.microsoft.com/WindowsServer2003/R2/Identity_Management/ADFSwhitepaper.mspx

     

    Hmmm...

    OtherSystem is hosted by a different organization entirely, so sharing the the authentication cookie wouldn't work, I don't think.


    As for ADFS, MySystem isn't using Active Directory for authentication, and OtherSystem might not even be on a Windows machine at all, for all I know.  So I don't think ADFS will work, unless I missed something in my cursory reading of the white paper to which you linked.



  • I think what you want to do is called "Single Sign-on" or SSO.  Search for that and see if you find something that solves the problem.



  • I hate to be the bearer of bad news...

    Unless you have some kind of trusted relationship running the other site, your chances are slim-to-none to get such a mechanism working. Architecting your web application to use an external authorization system is something that both you and the other site should have considered during design, if you are in the same organization.

    At our organization we have an LDAP directory that can authenticate over SSL using the same password that you use for your email and domain logins. So we make all of our intranet applications (COTS or not) use LDAP internally, querying for credentials with HTTP Basic auth if at all possible, and to trust our LDAP/ADS system. This way people have a single password, and if they're using MSIE, it'll try their domain password first, which will work transparently.

    And password change requests can be handled by the help desk...

    So in the apps we just add domain users to and from roles/groups to give them appropriate rights on the sites. 



  • You are trying to do Single Sign-On. Many people have tried to do this. All have failed. Microsoft tried, with win2k and active directory, and failed spectacularly.

    I really wouldn't bother. It is amazingly difficult and there is very little benefit to be gained. 



  • @UncleMidriff said:

    @RaspenJho said:

    I think you shouldn't roll your own solution.

    If both applications are hosted in-house, you may look at sharing the forms authentication cookie between the two web applications.

    If they are not, take a look at Active Directory Federation Services (ADFS)...

    http://www.microsoft.com/WindowsServer2003/R2/Identity_Management/ADFSwhitepaper.mspx

     

    Hmmm...

    OtherSystem is hosted by a different organization entirely, so sharing the the authentication cookie wouldn't work, I don't think.


    As for ADFS, MySystem isn't using Active Directory for authentication, and OtherSystem might not even be on a Windows machine at all, for all I know.  So I don't think ADFS will work, unless I missed something in my cursory reading of the white paper to which you linked.

    Security holes notwithstanding, there IS another option.

    Assumptions for this to work:
         1)  Both MySystem and OtherSystem authenticate using Forms authentication
         2)  The usernames and passwords are synchronized between the two applications (or you provide a mapping table and store the OtherSystem credentials)
         3)  You don't really care about Security

    Go to OtherSystem's login page, view source, and write down all of the form controls within their login FORM.
    Fabricate a form POST, substituting in the user's OtherSystem username and password.  Do this from your web server using the HttpRequest object.
    When a successful response is received, copy the authentication COOKIE from the OtherSystem's response stream into your MySystem user's cookie collection.
    Redirect the user to OtherSystem's home page.

    Good luck.

    Disclaimer:  All information contained herein is considered hackery of the worst form.  Use it at your own risk.



  • @RaspenJho said:

    @UncleMidriff said:

    Hmmm...

    OtherSystem is hosted by a different organization entirely, so sharing the the authentication cookie wouldn't work, I don't think.


    As for ADFS, MySystem isn't using Active Directory for authentication, and OtherSystem might not even be on a Windows machine at all, for all I know.  So I don't think ADFS will work, unless I missed something in my cursory reading of the white paper to which you linked.

    Security holes notwithstanding, there IS another option.

    Assumptions for this to work:
         1)  Both MySystem and OtherSystem authenticate using Forms authentication
         2)  The usernames and passwords are synchronized between the two applications (or you provide a mapping table and store the OtherSystem credentials)
         3)  You don't really care about Security

    Go to OtherSystem's login page, view source, and write down all of the form controls within their login FORM.
    Fabricate a form POST, substituting in the user's OtherSystem username and password.  Do this from your web server using the HttpRequest object.
    When a successful response is received, copy the authentication COOKIE from the OtherSystem's response stream into your MySystem user's cookie collection.
    Redirect the user to OtherSystem's home page.

    Good luck.

    Disclaimer:  All information contained herein is considered hackery of the worst form.  Use it at your own risk.

    1) I dunno, I'll have to look into that.

    2) They are not synchronized, but we could probably create some sort of mapping if we needed to.

    3) Provided all this POSTing back and forth is done using SSL, why is this approach inherently insecure?  I mean, how would it be any more or less secure than a user POSTing his login data directly from OtherSystem's login form?

    Our systems are on different domains, so what good would MySystem writing the authentication cookie from OtherSystem to the user's cookie collection do?  Would OtherSystem even be able to read it?



  • The main part about the unsecure-ness is that you'll be storing the user's passwords to OtherSystem, either plaintext or using a reversible encryption algorithm.  Any system wherein you can retrieve the password is not good design, and opens the door to attacks from within your organization.

    The smartest way I can think of to store the passwords would be to use the user's existing password as entropy for storing the new password.  This would prevent casual observers from being able to extract login information for OtherSystem from MySystem.

    About the cookie, I think you are right.  You probably have to make the request from the client's web browser itself; but it's still possible.  You may have to be in the users' trusted sites zone in order to do a cross-domain request.

    With this last piece, you also have the added security flaw of potential man-in-the-middle attacks sniffing out the password as you send it down to the browser via script.



  • @RaspenJho said:

    Security holes notwithstanding, there IS another option.

    Assumptions for this to work:
         1)  Both MySystem and OtherSystem authenticate using Forms authentication
         2)  The usernames and passwords are synchronized between the two applications (or you provide a mapping table and store the OtherSystem credentials)
         3)  You don't really care about Security

    Go to OtherSystem's login page, view source, and write down all of the form controls within their login FORM.
    Fabricate a form POST, substituting in the user's OtherSystem username and password.  Do this from your web server using the HttpRequest object.
    When a successful response is received, copy the authentication COOKIE from the OtherSystem's response stream into your MySystem user's cookie collection.
    Redirect the user to OtherSystem's home page.

    Good luck.

    Disclaimer:  All information contained herein is considered hackery of the worst form.  Use it at your own risk.

    This may break when OtherSystem gets upgraded and doesn't recognize the obsolete FORM.

     



  • @newfweiler said:

    @RaspenJho said:

    Security holes notwithstanding, there IS another option.

    Assumptions for this to work:
         1)  Both MySystem and OtherSystem authenticate using Forms authentication
         2)  The usernames and passwords are synchronized between the two applications (or you provide a mapping table and store the OtherSystem credentials)
         3)  You don't really care about Security

    Go to OtherSystem's login page, view source, and write down all of the form controls within their login FORM.
    Fabricate a form POST, substituting in the user's OtherSystem username and password.  Do this from your web server using the HttpRequest object.
    When a successful response is received, copy the authentication COOKIE from the OtherSystem's response stream into your MySystem user's cookie collection.
    Redirect the user to OtherSystem's home page.

    Good luck.

    Disclaimer:  All information contained herein is considered hackery of the worst form.  Use it at your own risk.

    This may break when OtherSystem gets upgraded and doesn't recognize the obsolete FORM.

    Let's file that under risk #02247



  • I thought I'd post a diagram explaining my initial solution (the one i talked about in the first post) to this problem a little bit better.  I suck at making diagrams, so don't be surprised if you need a couple shots for this to start making any sense. :-)

    What glaring, gaping security holes do you see in this? 

    Image of diagram on Flickr



  • You have developer-level access to both systems? Why not just have them both use LDAP or something?

    In any case, in your solution I would just make sure the token verification channel is secured (as in, only the OtherSystem webserver can use the verifier URL/webservice, enforced by ACLs or firewall rules or whatever is appropriate). 

    Also, make sure that you generate secure tokens from a good random number source. Don't just hash the end-user IP and the time of day; this can be guessed. Finally, make sure that those tokens expire after 30 minutes unless the verifier continues to ping the MySystem service for validity.



  • @kirchhoff said:

    You have developer-level access to both systems? Why not just have them both use LDAP or something?

    In any case, in your solution I would just make sure the token verification channel is secured (as in, only the OtherSystem webserver can use the verifier URL/webservice, enforced by ACLs or firewall rules or whatever is appropriate). 

    Also, make sure that you generate secure tokens from a good random number source. Don't just hash the end-user IP and the time of day; this can be guessed. Finally, make sure that those tokens expire after 30 minutes unless the verifier continues to ping the MySystem service for validity.

    I have developer-level access to my system, but no such access to the other system.  Regarding LDAP, I admit to being fantastically ignorant about it, though I am learning more about it now.  It seems to me, though, from what little I know about it now, that it would be a bit difficult to completely change the way our respective systems handle user authentication.  We handle it our way (using ASP .NET 2.0's built in user management features with a SQL Server 2000 back end), and they handle theirs...well, I have no idea how they handle theirs.  But, like I said, I'm ignorant about LDAP, so I could be completely wrong here, an obvious and easy answer staring me in the face.  I'll keep reading up on it.

    About the token verification channel: I am planning on it being secured via SSL, and I can probably convince the web administrators to restrict access to the verifier URL/webservice.  Even if the there were no such access restrictions, what good would it do a hacker to use the token verifier URL/webservice?  All he'd be able to get out of it is a, "Yeah, that's a good one" or a "No, that one's no good" response.  Even if he managed to guess a good one, as soon as the verifier verifies it, it gets deleted from the token storage, so the hacker wouldn't be able to do much with it.  But, if I know this place, it won't be long before the verifier gets changed to start handing out, "Yes, that's a good token, and here is a bunch of personal information about the guy you got it from" -type responses, so restricting access to it would indeed be a good idea.

    Regarding the tokens themselves, would a GUID generated by SQL Server 2000 do the trick?  According to the documentation, the T-SQL function NEWID() "Creates a unique value of type uniqueidentifier (16-byte GUID)."  I'm thinking such a number would be fairly hard to guess, but I don't know for sure.  As for expiration, my plan was for the token to expire 5 minutes from the time of creation or whenever it is used, whichever happens first.

     

    Thanks for your (and everyone else's) help, by the way. 



  • @UncleMidriff said:

    Regarding the tokens themselves, would a GUID generated by SQL Server 2000 do the trick?

    No. GUIDs and UUIDs are not secure against a hostile party unless special steps are taken. Microsoft's implementation in particular is intended only to prevent conflicts within authenticated data, it is not cryptographically secure. If you want to authenticate based on arbitrary generated tokens, you're going to have to use a real entropy generator. 



  • Maybe just a utility or something that autofills username/password info?  I've seen those before.


Log in to reply