Single Sign-on Shenanigans

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

User avatar
Archgeek
Posts: 128
Joined: Wed May 02, 2007 6:00 am UTC
Location: Central US
Contact:

Single Sign-on Shenanigans

Postby Archgeek » Fri May 22, 2015 4:08 pm UTC

I'm attempting to do a bit of homespun SSO at work featuring PHP and ActiveDirectory, due to persons wearying of CAS's tomfoolery, and I've come across a conceptual quandary that's probably just highlighting some missing information.

The goal is to let users on the internal network who've logged into their win7 boxen rampage on into a test web application without need for further input, and those without authorization for it to be denied.

What I know is that to do this, the webapp must ask ActiveDirectory about who the user is and what groups they are in, as well as confirm their authenticated status. It then checks with its happy little authorization table in the backend and decides if the user's to be admitted.

However, things get stranger when I think on the flow. First, the user logs into windows. At this point, only windows and AD have the username/password pair, and presumably AD's sent back an authentication token semi-analogous to a CAS TGT or PGT. The user then fires up their browser and tries to access test.derp.int/ssoTest/index.php, at which point we switch to the PHP server's persective. The server's got an HTTP request from a user with fresh session, featuring stuff like their browser and version, but no username of yet. It needs to figure out who this clod is, if they're authenticated, and if they're authorized to use ssoTest. So it does an (annonymous?) LDAP bind to the AD server, and asks who the heck this is.

Here's where I run into a quandry, though -- what the heck piece of information does the server even have from the browser request to provide AD that would have a chance in heck of uniquely identifying them in the directory? Did AD also grab the IP to go with the username/password pair, and the LDAP search can lookup by that? I thought one couldn't trust an IP address alone, since they can change or be spoofed rather easily. Or am I missing something else entirely? Any and all elucidation would be much appreciated, because I'm getting downright confused the longer I think about it.
"That big tube down the side was officially called a "systems tunnel", which is aerospace contractor speak for "big tube down the side."

Drumheller769
Posts: 729
Joined: Mon May 11, 2009 7:46 pm UTC
Location: ♞♞♞

Re: Single Sign-on Shenanigans

Postby Drumheller769 » Fri May 22, 2015 4:18 pm UTC

If your AD is set up so that your users have to be authenticated to the work network, then AD should store their logon ID somewhere, use that to uniquely identify them and query against.
The Great Hippo wrote:Arguing with the internet is a lot like arguing with a bullet. The internet's chief exports are cute kittens, porn, and Reasons Why You Are Completely Fucking Wrong.

User avatar
Archgeek
Posts: 128
Joined: Wed May 02, 2007 6:00 am UTC
Location: Central US
Contact:

Re: Single Sign-on Shenanigans

Postby Archgeek » Fri May 22, 2015 4:56 pm UTC

Yes, it should and does store it somewhere, but that's just it, the application server has to have it some how. The issue is that it lacks the ID at the time of first interaction. Windows and AD have it, but the server just has whatever the browser decided to pass along in the page request.
"That big tube down the side was officially called a "systems tunnel", which is aerospace contractor speak for "big tube down the side."

Drumheller769
Posts: 729
Joined: Mon May 11, 2009 7:46 pm UTC
Location: ♞♞♞

Re: Single Sign-on Shenanigans

Postby Drumheller769 » Fri May 22, 2015 5:26 pm UTC

Youll have to read up on the server you are using, but for example IIS stores that data in the LOGON_USER server variable. Maybe you could configure your server to pass an authentication header with that data in it.
The Great Hippo wrote:Arguing with the internet is a lot like arguing with a bullet. The internet's chief exports are cute kittens, porn, and Reasons Why You Are Completely Fucking Wrong.

User avatar
Archgeek
Posts: 128
Joined: Wed May 02, 2007 6:00 am UTC
Location: Central US
Contact:

Re: Single Sign-on Shenanigans

Postby Archgeek » Fri May 22, 2015 6:42 pm UTC

Nope. No IIS (it's not even enabled), running old Zend server 5 on Apache (probably tomcat), no access anything remotely administrative, (save for the POSIX powers in the PHP file API).

SESSION's flat empty, REQUEST has a newly forged session ID, but those aren't useful. Server data includes [HTTP_USER_AGENT] => Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; InfoPath.3; .NET4.0E)
(for IE? I guess it's just refering to supported capabilites.), and [REMOTE_ADDR](IP address) as the only two things associated with the user and their browser, unless [CCSID] => 819 means more than I think it does. 'Seems a little short to uniquely ID a user enough to look up their username in AD, though. I should've mentioned these things in my initial post, it seems.
"That big tube down the side was officially called a "systems tunnel", which is aerospace contractor speak for "big tube down the side."

User avatar
hotaru
Posts: 1023
Joined: Fri Apr 13, 2007 6:54 pm UTC

Re: Single Sign-on Shenanigans

Postby hotaru » Fri May 22, 2015 6:47 pm UTC

Archgeek wrote:Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; InfoPath.3; .NET4.0E)

maybe updating IE would help, but i wouldn't count on it.

Archgeek wrote:unless [CCSID] => 819 means more than I think it does. 'Seems a little short to uniquely ID a user enough to look up their username in AD, though.

it doesn't look useful: https://en.wikipedia.org/wiki/CCSID

Code: Select all

factorial product enumFromTo 1
isPrime n 
factorial (1) `mod== 1

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 5506
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Single Sign-on Shenanigans

Postby Thesh » Fri May 22, 2015 7:22 pm UTC

Maybe I'm not understanding, but when you are having a website with active directory authentication, when you connect the HTTP server sends a "WWW-Authenticate: Negotiate" header with a token, which the client then responds to with the information needed to identify the user and authenticate them.
Honesty replaced by greed, they gave us the reason to fight and bleed
They try to torch our faith and hope, spit at our presence and detest our goals

User avatar
Archgeek
Posts: 128
Joined: Wed May 02, 2007 6:00 am UTC
Location: Central US
Contact:

Re: Single Sign-on Shenanigans

Postby Archgeek » Fri May 22, 2015 8:46 pm UTC

Now that sounds like something I might be missing.

But, what exactly are you refering to as the HTTP server and the client? There are three principal actors in play here: the user agent (the user's browser), the web server (likely from the perspective of an application php script and anything it might include), and AD server.

If you mean the web server just chirps back to the user agent an authentication header, then unless the user agent has said piece of information (the crux of my question is what that might be), it'll just prompt the user to authenticate, violating SSO.

If you mean something else, it might be just what I'm after.
"That big tube down the side was officially called a "systems tunnel", which is aerospace contractor speak for "big tube down the side."

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 5506
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Single Sign-on Shenanigans

Postby Thesh » Sat May 23, 2015 8:28 am UTC

HTTP Server is the web server, client is the web browser. I'm not completely sure of the inner workings, usually that's all handled by a module in the HTTP server or the web programming language (e.g. mod_auth_kerb on Apache).
Honesty replaced by greed, they gave us the reason to fight and bleed
They try to torch our faith and hope, spit at our presence and detest our goals

stevewilson
Posts: 1
Joined: Sat May 23, 2015 6:20 pm UTC

Re: Single Sign-on Shenanigans

Postby stevewilson » Sat May 23, 2015 6:42 pm UTC

I believe the magic words, or in this case magic word (singular), is: SSPI (Security Support Provider Interface)

SSPI is the mechanism by which an AD authenticated user (Windows) AND an AD authenticated web server (difficult under Linux) talk to each other and the domain controller to do a transparent single sign on and pass the result of that conversation onto other modules in the web server (e.g. PHP). mod_auth_sspi is what you want...if you can get it to work.

You'll also need to have each web browser on your network trust your domain name space.

I once tried to set up SSPI with Apache to use in conjunction with Barebones SSO, but nothing I tried worked (specifically, Linux and AD domain controllers don't really like each other) so I ended up just plopping two fields (username/password) on a webpage behind the corporate firewall and testing user credentials via PHP's built-in LDAP support and used some CSS to camouflage it to look like other corporate web logins across the organization. It worked great despite users having to enter their login credentials again into a web form I had control over. Completely transparent sign in is cool but really hard to set up.

DaveInsurgent
Posts: 207
Joined: Thu May 19, 2011 4:28 pm UTC
Location: Waterloo, Ontario

Re: Single Sign-on Shenanigans

Postby DaveInsurgent » Tue May 26, 2015 7:43 pm UTC

HTTP is a stateless application level protocol meaning it contains higher level semantics and each message contains all of the information necessary to be understood and processed.

When a request is made the server is to evaluate it and respond - sounds obvious, but the key is that everything outside of what is contained within the message is an implementation detail. So when you refer to the "third actor" you're conflating the HTTP exchange and the implementation of the response.

Authentication is a concern handled within the semantics of HTTP and is done so using headers. However, the semantics of the actual authorization mechanism are only partly specified.

For example:

(request)
GET /my-resource

(response)
HTTP 401 Unauthorized
WWW-Authenticate: Smoke Signals


The HTTP "layer" is saying "you need to authenticate" (that's what 401 means) and a well-behaved HTTP client would automatically understand this. In addition to that, the WWW-Authenticate header is advertising a way that this can be accomplished. Most people stop here and assume that it's just how browsers work that matters, and so there's WWW-Authenticate: Basic, which means "show that ugly username and password popup box" and forms, but that's the naive understanding. The browser is just one HTTP client that happens to understand what Basic auth is. In this case we've returned Smoke Signals (we can also return multiple options). It's just something we made up.

The body of that response might contain more information - like how to send smoke signals. After the client/user-agent performs that authentication, they should be allowed to repeat the request and provide the appropriate Authorization header. So we might do some smoke signals and get a token that we can place in subsequent requests. Cool, though we don't really want to make up new authentication schemes. And as an aside within an aside, it's possible that the Authorization token/header you provide proves who you are, but does not grant access to said resource. This is evaluated in *another* request (for obvious reasons, I hope) and is how you end up with a HTTP 403 error instead of a 401.

In the real world, non-browser clients (like mobile applications) get written to do some kind of login action that gets an access token. In "pure" HTTP this would all be done by examining responses (including message body and headers) but it's seldom done this way. (This is what REST is from an architecture standpoint).

Like I said, we know about Basic auth. We've probably all seen that prompt. There's also "forms" authentication, which isn't an authentication scheme per se but it's more a delegation (show this HTML to the user and hopefully they fill it out right, then we can proceed).

So your question is actually: What authentication schemes are inherently understood by browsers?

You want your server to challenge clients with a WWW-Authenticate header that browsers understand that kicks off some operating system afforded mechanism of identifying the users login identity, which then you can consume (via a subsequent request with the Authorization header provided) and verify that they have the appropriate permission to see the page. (That later step might not be important to you as an enforcement, but its still How It Works). If memory serves this is the WWW-Authenticate: Negotiate scheme which supports Kerberos and NTLM and blah blah (those are things you can google).

The unfortunate part is that browser support has always been shitty in this respect. Microsoft IE talking to Microsoft IIS from Windows tends to have the better support and everything else is corner cases at best with no straight OOB (i.e. you have to screw with settings panels like adding domains to be trusted).

You can try reading from: https://shibboleth.net/about/basic.html

User avatar
Archgeek
Posts: 128
Joined: Wed May 02, 2007 6:00 am UTC
Location: Central US
Contact:

Re: Single Sign-on Shenanigans

Postby Archgeek » Tue May 26, 2015 10:11 pm UTC

stevewilson wrote:I believe the magic words, or in this case magic word (singular), is: SSPI (Security Support Provider Interface)

SSPI is the mechanism by which an AD authenticated user (Windows) AND an AD authenticated web server (difficult under Linux) talk to each other and the domain controller to do a transparent single sign on and pass the result of that conversation onto other modules in the web server (e.g. PHP). mod_auth_sspi is what you want...if you can get it to work.


Hmm, considering one target is indeed CAS with SPNEGO on Tomcat, mod_auth_sspi sounds like a thing to look into.
So I take it this implies that the answer to the question is "Yup, IP, but with some doublechecking with the DNS"?

DaveInsurgent wrote:When a request is made the server is to evaluate it and respond - sounds obvious, but the key is that everything outside of what is contained within the message is an implementation detail. So when you refer to the "third actor" you're conflating the HTTP exchange and the implementation of the response.
[...]
[Some amusing stuff about smoke signals and WWW-Authenticate headers]
[...]
So your question is actually: What authentication schemes are inherently understood by browsers?
[...]
You want your server to challenge clients with a WWW-Authenticate header that browsers understand that kicks off some operating system afforded mechanism of identifying the users login identity, which then you can consume (via a subsequent request with the Authorization header provided) and verify that they have the appropriate permission to see the page. (That later step might not be important to you as an enforcement, but its still How It Works). If memory serves this is the WWW-Authenticate: Negotiate scheme which supports Kerberos and NTLM and blah blah

Nah, not conflating anything, just considering the whole system of things involved at the surface level (and largely from the perspective of the PHP server).

That was entertaining and edifying. I didn't know that header came in that darn many flavours.

Er, no, not at all. My question is: In the transparent SSO case, what piece of information other than the user id, which has not yet been given outside of inital OS login, is being used by the application server to tell the LDAP server (AD in this case) who it would like to know about; and where the blazes is it getting it from?

Ah, I think I've seen WWW-Authenticate: Negotiate running around the CAS code, or possibly when reading up on SPNEGO.
"That big tube down the side was officially called a "systems tunnel", which is aerospace contractor speak for "big tube down the side."

DaveInsurgent
Posts: 207
Joined: Thu May 19, 2011 4:28 pm UTC
Location: Waterloo, Ontario

Re: Single Sign-on Shenanigans

Postby DaveInsurgent » Wed May 27, 2015 1:17 am UTC

what piece of information other than the user id, which has not yet been given outside of inital OS login, is being used by the application server to tell the LDAP server (AD in this case)


That's sort of my point. Something has to initiate that, and it's the web server sending a 401 with a particular WWW-Authenticate. Browsers (most of them) implement the Negotiate protocol. So this involves doing something outside of the bounds of the browser (i.e. obtaining that "user id" -- but it's not a user id, it's a token of some kind).

If you don't know what part that is, that's part of your problem. Most server technologies let you specify some kind of middleware of filter. If you want to handle the thing "char by char" from the actual text of the HTTP request, you're gonna have a bad time. I don't think that LDAP is sufficient either, but I could be wrong -- that token/ticket is going to get passed through, given to a library as part of the request handling flow, which itself passes it off to some external system - this may be AD, but usually there's configuration required there at least as part of Kerberos (which AD implements AFAIK), and then that system responds. Now maybe that library knows how to take the response and fetch something from LDAP - maybe, but I don't know.

What happens at this point is your system usually tracks some foreign surrogate identifier (an ldap username for example) and then uses that to associate it's own data (i.e. you add it as a column on your own database, or build your own identity table with unique constraints on that value, whatever).

Tub
Posts: 319
Joined: Wed Jul 27, 2011 3:13 pm UTC

Re: Single Sign-on Shenanigans

Postby Tub » Wed May 27, 2015 6:55 am UTC

Thankfully, Firefox will refuse to just pass my logon credentials to any random webserver who's asking, so if you're using firefox, you need to manually whitelist the domain:
http://ole.michelsen.dk/blog/firefox-au ... nd-ad.html

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 5506
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Single Sign-on Shenanigans

Postby Thesh » Wed May 27, 2015 7:04 am UTC

I think all major browsers require white-listing for sending credentials. I know IE does, and a quick google search confirms Chrome does as well.
Honesty replaced by greed, they gave us the reason to fight and bleed
They try to torch our faith and hope, spit at our presence and detest our goals

DaveInsurgent
Posts: 207
Joined: Thu May 19, 2011 4:28 pm UTC
Location: Waterloo, Ontario

Re: Single Sign-on Shenanigans

Postby DaveInsurgent » Wed May 27, 2015 2:19 pm UTC

Tub wrote:Thankfully, Firefox will refuse to just pass my logon credentials to any random webserver who's asking, so if you're using firefox, you need to manually whitelist the domain:
http://ole.michelsen.dk/blog/firefox-au ... nd-ad.html


It's not sending credentials, it's sending a token/ticket that can identify you if that is given another system if the system requesting identification has been allowed. the firefox 'feature' is meh.

User avatar
Archgeek
Posts: 128
Joined: Wed May 02, 2007 6:00 am UTC
Location: Central US
Contact:

Re: Single Sign-on Shenanigans

Postby Archgeek » Wed May 27, 2015 3:03 pm UTC

DaveInsurgent wrote:That's sort of my point. Something has to initiate that, and it's the web server sending a 401 with a particular WWW-Authenticate. Browsers (most of them) implement the Negotiate protocol. So this involves doing something outside of the bounds of the browser (i.e. obtaining that "user id" -- but it's not a user id, it's a token of some kind).

Dang darn... in that case it rather seems like unless the browser itself or a plugin knows quite what to do to get the AD ticket from the OS, transparent SSO winds up being kind of a no-go. (The user id in question is in fact the AD username, and for CAS at least, the ticket includes it.)
"That big tube down the side was officially called a "systems tunnel", which is aerospace contractor speak for "big tube down the side."

DaveInsurgent
Posts: 207
Joined: Thu May 19, 2011 4:28 pm UTC
Location: Waterloo, Ontario

Re: Single Sign-on Shenanigans

Postby DaveInsurgent » Thu May 28, 2015 12:02 am UTC

For sure, I mean, it means setting shit up -- the 'easy way' is usually to put IIS in front and have it handle the Windows authentication part and then your web server runs behind it.

There's also apache mod_auth_kerb which I've never used - but it's important to understand that these are just pieces, that need to be understood somehow by whatever "framework" you're using to build the site. In NodeJS, we use something like passport, as an example, which is just a library/pattern for creating different authentication handlers and letting them participate in the request/response.

Bottom line, shit is hard.

User avatar
Archgeek
Posts: 128
Joined: Wed May 02, 2007 6:00 am UTC
Location: Central US
Contact:

Re: Single Sign-on Shenanigans

Postby Archgeek » Tue Jun 02, 2015 10:12 pm UTC

Just following up on this in case anyone else has such a specific problem as to need a windows username in PHP. Looking further into the IIS case, I tried to find out what makes an IIS 401 header. 'Turns out it's pretty much just NTLM.
So, by pretending to be an NTLM authentication function and engaging in some serious shenanigans with the results:
Spoiler:

Code: Select all

/**
 * messing with NTLM to accquire username
 *
 * solution stolen from http://siphon9.net/loune/2007/10/simple-lightweight-ntlm-in-php/
 * with some modification
 */
$success = '';
if(isset($_SERVER['HTTP_AUTHORIZATION'])){
   $auth = $_SERVER['HTTP_AUTHORIZATION'];
   $_SESSION['auth'] = $auth;
}else{
   //unset($_SESSION['auth']);
   header('WWW-Authenticate: NTLM',401.2);
   //exit;
}

if (substr($auth,0,5) == 'NTLM ') {
   $msg = base64_decode(substr($auth, 5));
   if (substr($msg, 0, 8) != "NTLMSSP\x00")
      die('error header not recognised');

        //such shenanigans
   $_POST['msg'] = $msg;
   if ($msg[8] == "\x01") {
      $msg2 = "NTLMSSP\x00\x02\x00\x00\x00".
            "\x00\x00\x00\x00". // target name len/alloc
            "\x00\x00\x00\x00". // target name offset
            "\x01\x02\x81\x00". // flags
            "\x00\x00\x00\x00\x00\x00\x00\x00". // challenge
            "\x00\x00\x00\x00\x00\x00\x00\x00". // context
            "\x00\x00\x00\x00\x00\x00\x00\x00"; // target info len/alloc/offset
      
      $_SESSION['msg2'] = $msg2;
      header('WWW-Authenticate: NTLM '.trim(base64_encode($msg2)),401.1);
      //exit;
   }
   else if ($msg[8] == "\x03") {  //EACH of the the shenanigans
      $_POST['challenge/response'] = '401.1 response get';
      function get_msg_str($msg, $start, $unicode = true) {
         $len = (ord($msg[$start+1]) * 256) + ord($msg[$start]);
         $off = (ord($msg[$start+5]) * 256) + ord($msg[$start+4]);
         if ($unicode)
            return str_replace("\0", '', substr($msg, $off, $len));
         else
            return substr($msg, $off, $len);
      }
      $user = get_msg_str($msg, 36);
      $domain = get_msg_str($msg, 28);
      $workstation = get_msg_str($msg, 44);

      $success = "You are $user from $domain/$workstation";
   }
}

...a php script can indeed get hold of an unauthenticated user's windows username iff they've got the site whitelisted in their browser. If not, they can claim to be anyone, so grabbing the password hash out of there and comparing it with AD's is probably a thing to do.
"That big tube down the side was officially called a "systems tunnel", which is aerospace contractor speak for "big tube down the side."

User avatar
ucim
Posts: 5634
Joined: Fri Sep 28, 2012 3:23 pm UTC
Location: The One True Thread

Re: Single Sign-on Shenanigans

Postby ucim » Wed Jun 03, 2015 3:58 am UTC

Archgeek, I noticed you put a function definition inside an if statement inside the body of your code. Why did you do it this way instead of defining the function outside your code?

Jose
Order of the Sillies, Honoris Causam - bestowed by charlie_grumbles on NP 859 * OTTscar winner: Wordsmith - bestowed by yappobiscuts and the OTT on NP 1832 * Ecclesiastical Calendar of the Order of the Holy Contradiction * Please help addams if you can. She needs all of us.

User avatar
Archgeek
Posts: 128
Joined: Wed May 02, 2007 6:00 am UTC
Location: Central US
Contact:

Re: Single Sign-on Shenanigans

Postby Archgeek » Wed Jun 03, 2015 2:34 pm UTC

No actual reason, it's just how the original code was built here: http://siphon9.net/loune/2007/10/simple ... lm-in-php/
My modifications were stuff like changing the headers to actually work on the php server I'm working with, little shunts to $_POST and $_SESSION from the debugging process, and putting the result into a variable instead of just printing it.
If that'd been my own bit of sourcery it would've been below the main logic of the script and named in camelCaps instead of with underscores.
"That big tube down the side was officially called a "systems tunnel", which is aerospace contractor speak for "big tube down the side."


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 7 guests