Using LDAP with UAA

1,725 views
Skip to first unread message

Mike Heath

unread,
Apr 30, 2012, 3:59:43 PM4/30/12
to vcap...@cloudfoundry.org
The UAA documentation makes reference to using LDAP for authentication. However, I can't find anything in UAA with regard to LDAP outside of the documentation. Is this something that's currently supported?

-Mike

Joel D'sa

unread,
Apr 30, 2012, 5:12:48 PM4/30/12
to vcap...@cloudfoundry.org
The design is extensible so that LDAP can be easily supported but it is not currently supported.

- Joel

Mike Heath

unread,
Apr 30, 2012, 7:01:58 PM4/30/12
to vcap...@cloudfoundry.org
Is there a timeline for supporting LDAP? Or should I roll up my sleeves, sign the CLA, and get to work? :)

-Mike

Jesse Zhang

unread,
Apr 30, 2012, 7:35:29 PM4/30/12
to vcap...@cloudfoundry.org
You are more than welcome to contribute!

Dave Syer

unread,
May 1, 2012, 6:18:56 AM5/1/12
to vcap...@cloudfoundry.org
On 01/05/12 00:01, Mike Heath wrote:
> Is there a timeline for supporting LDAP? Or should I roll up my
> sleeves, sign the CLA, and get to work? :)

I'm not going to stop you from doing it yourself, but there is a story
in our current sprint to demonstrate how to do this and document it. If
you want to know what it will look like, it will be very much like this:
https://github.com/SpringSource/spring-security/tree/master/samples/ldap.
Switching authentication strategy is pretty trivial in Spring Security.

Longer term, we are also looking at extracting the user authentication
into a separate server on cloudfoundry.com, which would then probably
become a sample app in the uaa repository. This would make it really
easy to use LDAP or OpenId or whatever you like as an authentication
front end, and to brand it however you please (if it's a private cloud).

Dave.

--
Dave Syer
ds...@vmware.com

karl.gy...@anatas.com

unread,
Dec 7, 2012, 10:10:55 AM12/7/12
to vcap...@cloudfoundry.org, ds...@vmware.com, david...@googlemail.com
Bumping this question :)

Has there been progress on this issue? We're looking to do the same integration and any existing code/config would be quite useful.

Thanks

Dave Syer

unread,
Dec 7, 2012, 10:24:20 AM12/7/12
to vcap...@cloudfoundry.org
On 07/12/12 15:10, karl.gy...@anatas.com wrote:
> Bumping this question :)
>

No we haven't done any more work on this. The sample I linked to is
still there and the statement that "Switching authentication strategy is
pretty trivial in Spring Security" is still true.

--
Dave Syer
ds...@vmware.com

karl.gy...@anatas.com

unread,
Dec 7, 2012, 11:43:34 AM12/7/12
to vcap...@cloudfoundry.org, ds...@vmware.com
Thanks for the information. Having looked at the example code, it isn't apparent how these might apply to the UAA setup. Can you provide any pointers on which particular configuration changes from the spring example code we need to apply?

and...@activestate.com

unread,
Dec 7, 2012, 2:34:09 PM12/7/12
to vcap...@cloudfoundry.org, ds...@vmware.com
I've been looking at the "login" sample app to see how to adapt this to use LDAP as the backend for UAA. This app doesn't seem like it actually does anything with UAA (in the way of getting UAA tokens). It's mainly just an openid demo app, but can also pass-through uaa email/password. Even if I switched out openid for LDAP in this sample, it would then just be an LDAP demo spring app, and I would be no closer to using LDAP with UAA. Can someone on the UAA team please clarify how this is supposed to work?

Thanks
Andrew

Dave Syer

unread,
Dec 7, 2012, 5:19:02 PM12/7/12
to vcap...@cloudfoundry.org
On 07/12/12 19:34, and...@activestate.com wrote:
> Even if I switched out openid for LDAP in this sample, it would then
> just be an LDAP demo spring app, and I would be no closer to using
> LDAP with UAA.

I don't think that's correct. The Login server (now at
http://github.com/cloudfoundry/login-server) is just a front end for
OAuth authorization which is passed through to the UAA, but it does real
authentication. So if you switch the authentication to LDAP (or OpenId
like in the old sample) then you immediately have both a custom
authentication and the real UAA for OAuth. And really it is just a few
lines of configuration.

If you prefer not to use the Login Server that's fine - you just need to
change the authentication filters and UI in the UAA itself instead of
the Login Server. The reason we split it up like this is to make it
easier to see where the responsibility lies - Login=UI + Authentication,
UAA=OAuth Authorization Server (even though the Login Server acts as a
proxy in that role).

I'm writing another blog on this, so this is all useful input if you
want to tell us what is needed, and what is hard to understand. Thanks
for the feedback.

and...@activestate.com

unread,
Dec 13, 2012, 1:26:45 PM12/13/12
to vcap...@cloudfoundry.org, ds...@vmware.com
Thanks for that, Dave. I had missed the login-server project and was looking at the openid login sample contained in the uaa repo. Might I suggest removing the latter or perhaps adding a prominent note in the readme about the former? Now that I've had time to look at login-server I have some questions.

Regarding this architecture: the flaw I see in this approach is that a lot of functionality relevant to authc is in UAA. If authc were truly in login-server (rather than proxying authc to UAA), then the interface between the two would become cumbersome. For example, I modified login-server to authenticate username/password against LDAP bind. Now how does UAA know about those users? Should login-server use SCIM to create those users in UAA just-in-time? And then get tokens for them using an admin client? If you wanted to use a normal server-flow for Oauth (rather than the implicit flow used currently), it seems awkward to have to proxy both token requests through login-server. Should login-server report failed authc to UAA to take advantage of failed-login auditing/lockout/etc. contained in UAA?

I'm very interested in your recommendation for implementing pluggable authentication systems in the login-server+UAA architecture.

Thanks
Andrew

Mike Heath

unread,
Jan 8, 2013, 11:31:03 PM1/8/13
to vcap...@cloudfoundry.org, ds...@vmware.com
Please help me verify that I understand this correctly. In the login project's spring-servlet.xml file, it has the Spring bean "remoteAuthenticationManager". Could I just replace this bean with one that does an LDAP bind (or whatever I want to validate the username/password.)

Could I also simply modify the login.yml so that uaa.login.url points to an HTTP end-point that does the LDAP bind and have it return the appropriate response? (BTW - The expected response is a little gimicky. A location header indicates success? What happened to HTTP response codes? :) )

-Mike

Dave Syer

unread,
Jan 9, 2013, 11:20:33 AM1/9/13
to Mike Heath, vcap...@cloudfoundry.org, ds...@vmware.com
On 09/01/13 04:31, Mike Heath wrote:
> Could I just replace this bean with one that does an LDAP bind (or
> whatever I want to validate the username/password.)

Yes, broadly speaking. Normally you would replace it just by adding a
<ldap-authentication-provider/> to the <authentication-manager/> (using
standard Spring Security namespace). That will get you authentication.
There is a decent sample app in the Spring Security codebase on github
(which I already posted a link to).

> Could I also simply modify the login.yml so that uaa.login.url points
> to an HTTP end-point that does the LDAP bind and have it return the
> appropriate response?

I guess you could do that. It's an interesting idea, but probably not
necessary since Spring Security already supports LDAP/AD out of the box
(as above).

> (BTW - The expected response is a little gimicky. A location header
> indicates success? What happened to HTTP response codes? :) )

Sorry you lost me on that. Expected response to what?

--
Dave Syer
ds...@vmware.com

Mike Heath

unread,
Jan 9, 2013, 12:07:27 PM1/9/13
to ds...@vmware.com, vcap...@cloudfoundry.org
Thanks for the quick reply Dave.

Modifying authentication-manager is definitely the most straight forward approach and that's the route I started down (having configured Spring Security to use LDAP many times before.) The reason I'm thinking of going the HTTP end-point route is so that I don't have to make too many modifications to our BOSH release. Unfortunately, UAA is kept as a blob in BOSH instead of a compiled src so that complicates modifying it and deploying it through our BOSH.

So really I'm weighing my options. Do I make a simple change to login but a big change to our BOSH release, or do I set up a simple HTTP end-point that does an LDAP bind and just change the login config via BOSH? I'm not sure which route is the easiest.

My biggest concern is getting an HTTP end-point deployed and having the contract between org.cloudfoundry.identity.uaa.login.RemoteUaaAuthenticationManager and UAA's /login.do change and hence breaking our authentication.

The "gimicky" response that I was referring to this snippet from RemoteUaaAuthenticationManager:

ResponseEntity<Void> response = restTemplate.exchange(loginUrl, HttpMethod.POST,
new HttpEntity<MultiValueMap<String, Object>>(parameters), Void.class);  
if (response.getHeaders().getLocation() != null) {
String location = response.getHeaders().getLocation().toString();
// Successful authentication redirects to the home page with no error
if (!location.contains("error=true")) {
logger.info("Successful authentication request for " + authentication.getName());
return new UsernamePasswordAuthenticationToken(username, password, UaaAuthority.USER_AUTHORITIES);
}
}

Of course, I've done basically the same thing many times before when integrating with other Spring Security based apps. :)  I would just prefer build something that returns a 200 on success and a 403 on failure. Not a big deal.

-Mike

Dave Syer

unread,
Jan 9, 2013, 12:17:30 PM1/9/13
to vcap...@cloudfoundry.org
On 09/01/13 17:07, Mike Heath wrote:
> Unfortunately, UAA is kept as a blob in BOSH instead of a compiled src
> so that complicates modifying it and deploying it through our BOSH.

It's the Login Server you need to change (not the UAA), but the same
argument applies. However, I'd have said it was pretty easy to change
the bytes and update the config/blobs.yml - it's only one source file to
change in the cf-release. (The fact that BOSH puts all blob IDs in a
single file is irritating actually and I wish someone would fix it, but
that's irrelevant.)

> The "gimicky" response that I was referring to this snippet from
> RemoteUaaAuthenticationManager:

I see. That comes from simply re-using the UAA /login.do (which is part
of the UI realluy, not a machine endpoint). We did that to make
introducing the Login Server as easy as possible and not cause changes
to ripple into the UAA. I suppose it might make sense to add a
"machine" endpoint to now that things are stable. The difficulty is
only really that we are using Spring Security to supply the /login.do
endpoint and it probably doesn't expect people to want to respond to
machine clients. Feel free to propose a change.

D.

--
Dave Syer
ds...@vmware.com

Mike Heath

unread,
Jan 9, 2013, 12:39:54 PM1/9/13
to vcap...@cloudfoundry.org
Right sorry. I meant login not uaa in that case. It is certainly easy to change the bytes, but only if you have your own blob server. :) Maybe it's time for us to move our blobs over to AWS.

Thanks for helping me think this through Dave. You're feedback has been invaluable to me.

-Mike

Mike Heath

unread,
Feb 4, 2013, 5:46:02 PM2/4/13
to vcap...@cloudfoundry.org
I have finally modified login to authenticate against our internal LDAP directory. I have deployed it using BOSH into my dev environment. When I hit my login app directly, I can see that it's using LDAP and works fine.

However, when I use VMC to go through UAA, I can see that UAA is attempting to authenticate using the database and doesn't even touch the login server, contrary to what was said in this thread. My BOSH release is using UAA 1.2.6 (same as cf-release). Browsing through the UAA 1.2.6 code, it's not clear at all what I need to change to point UAA to my login server instead of the database.

Do I need to use a newer version of UAA? I see the master branch in Git is version 1.3.x.

-Mike

P.S. For the record, forking cf-release and creating your own blob store isn't as straight forward as I would like but whatever. It's done and it works.

Dave Syer

unread,
Feb 5, 2013, 3:05:19 AM2/5/13
to vcap...@cloudfoundry.org
On 04/02/13 22:46, Mike Heath wrote:
> when I use VMC to go through UAA, I can see that UAA is attempting to
> authenticate using the database and doesn't even touch the login
> server, contrary to what was said in this thread.

I did say we hadn't tried it yet. Once installed, the Login Server is
the source of truth for authentication, so VMC should be sending
credentials to it really, not the UAA (the UAA has no way to
authenticate a user from your directory). VMC takes its authorization
endpoint URL from the cloud controller info, so that's where I would
start. I think the cloud controller should have a link to both the
Login Server and UAA if both are present, but the one it needs for VMC
is the one that can handle authentication (so the Login Server if it is
there).

> Do I need to use a newer version of UAA? I see the master branch in
> Git is version 1.3.x.

I don't think that would help. We had some issues with 1.3.x in staging
so it never got promoted to production. It's main feature was
supporting multiple nodes (horizontal scalability / resilience).
> P.S. For the record, forking cf-release and creating your own blob
> store isn't as straight forward as I would like but whatever. It's
> done and it works.

I would like to see instructions somewhere in the public domain. Did you
keep notes?

--
Dave Syer
ds...@vmware.com

Mike Heath

unread,
Feb 5, 2013, 1:00:19 PM2/5/13
to vcap...@cloudfoundry.org, ds...@vmware.com
The json string returned by CC's /info has an "authorization_endpoint". With the existing BOSH template, it always points to uaa. I manually modified my CC config to point to login.

Now when I do 'vmc login -t' I can see that it's getting login information from my login server instead of UAA.

After I enter my login credentials, VMC tries to authenticate against UAA. It looks like VMC is broken. (BTW - This would be MUCH easier to troubleshoot if vmc -t would show the host being used. Perhaps logging the full URL in the REQUEST output instead of just the HTTP method and URI.)

At this point, I can't help but wonder if I'm barking up the wrong tree. We're fairly confident that in our org we're going to want to modify the user registration workflow. Perhaps we should just modify UAA and forget about the login server.

As far as forking cf-release goes, I have notes, I just need to find time to clean them up and post them.

-Mike

Dave Syer

unread,
Feb 5, 2013, 4:39:40 PM2/5/13
to vcap...@cloudfoundry.org
On 05/02/13 18:00, Mike Heath wrote:
> After I enter my login credentials, VMC tries to authenticate against
> UAA. It looks like VMC is broken.

Quite possibly. I have been using it recently with a modified CC that
sends the login URL instead and it worked, but I suppose I was using
cf.com, so the UAA would be just as happy to accept the credentials as
the Login Server (but not in your case).

> (BTW - This would be MUCH easier to troubleshoot if vmc -t would show
> the host being used. Perhaps logging the full URL in the REQUEST
> output instead of just the HTTP method and URI.)

The VMC guys are quite responsive if you ping them directly. Pull
requests especially welcome I expect. I always end up using tcpdump to
debug what it is doing.

>
> Perhaps we should just modify UAA and forget about the login server.

Not a bad move I would say. The Login Server was only really supposed
to be a very thin shell that was branded for cf.com. I would expect it
would be easy to replicate (hence it was only a sample for many months,
and there are more sampels for ruby and SAML versions of the same
thing). If you FInd any snags or think there is any code there that
should be moved to a common library please suggest a change.

James Bayer

unread,
Feb 10, 2013, 9:27:57 PM2/10/13
to vcap...@cloudfoundry.org, ds...@vmware.com
I'm just catching up on this thread. Mike this functionality is very important to me too. Lots of people are going to want this. Let's keep updating this thread with progress. I've asked Shannon Coen on the PM team to work with Dave and team about these basic requirements.

- have vmc and web logins from a login server both authenticate against a cloud operator specified LDAP
- initially just use the OAuth scopes that the UAA associates to that user identified by their email address

- in the future, it would be a nice feature to map OAuth scopes onto users based on their LDAP directory group memberships, but not initially required

does this look about right to you or are you looking for other things?

Mike Heath

unread,
Feb 11, 2013, 1:06:24 PM2/11/13
to vcap...@cloudfoundry.org, ds...@vmware.com
Write now I've modified the AuthzAuthenticationManager.java code to use the LDAP/Spring Security integration we use in most of the custom Java apps we have in our organization. I'm ok with this because I'm very comfortable with Java, Spring, and Spring Security. I can see others having serious heartburn over this, unfortunately.

I like the idea of having a login server that is responsible for authentication and UI because these are the things that people are going to want to customize.

The problem, in my opinion, is that the way login server works is backwards. It relies on UAA for doing authentication. That should be reversed. If a login server is present, it should do the authentication and UAA should make calls to login. Currently login calls UAA. Also, when a browser goes to uaa for authentication, the browser should be redirected to login.

Granted, this is probably easier said than done with all the OAuth work that UAA is doing and admittedly I don't understand oauth2 as well as I should, just yet.

In the future, it would a be a really nice feature to allow the login server to specify OAuth scopes whether that comes from LDAP groups or some other source. The ability to easily customize this is what's most important to me.

-Mike

Dave Syer

unread,
Feb 11, 2013, 1:23:47 PM2/11/13
to vcap...@cloudfoundry.org
On 11/02/13 18:06, Mike Heath wrote:
> If a login server is present, it should do the authentication and UAA
> should make calls to login. Currently login calls UAA.

Actually the login server *does* do the authentication, and (as you have
pointed out elsewhere) the Cloud Controller should be sending clients
like vmc to the Login Server not to the UAA. The Login Server actually
only calls the UAA for authentication in "default", "native" or "legacy"
mode if you will, which we were more or less forced to do by the fact
that we need to support CF.com with it's native user account data. In
general a login server is free to do authentication any way it likes.
It's pretty easy to strategise for browser clients. For vmc you need to
be able to accept authentication parameters as key=value pairs, but that
hopefully isn't too strict a constraint.

> Also, when a browser goes to uaa for authentication, the browser
> should be redirected to login.

That's a possibility. Instead we have gone with a whitelabel UAA, which
works, but is ugly and contains a message with a link saying something
like "If you see this page you are probably in the wrong place". We
don't wan t to prevent the UAA from being used as an authentication
source for native user accounts, but we want to discourage client apps
from trying to use it for SSO. You should see that coming out in UAA
1.4 pretty soon.

> In the future, it would a be a really nice feature to allow the login
> server to specify OAuth scopes whether that comes from LDAP groups or
> some other source. The ability to easily customize this is what's most
> important to me.

Agree, and we are definitely going to have to support that pattern. But
it goes beyond authentication, which is what we are focused on currently
with several internal and external deployments. Your experience might
be valuable when we get to the groups and scopes. My sense is that the
UAA will always need a database with that information in it, but it
might be automatically provisioned by the login server.

Mike Heath

unread,
Feb 11, 2013, 4:28:11 PM2/11/13
to vcap...@cloudfoundry.org
On Mon, Feb 11, 2013 at 11:23 AM, Dave Syer <ds...@rbcon.com> wrote:
On 11/02/13 18:06, Mike Heath wrote:
If a login server is present, it should do the authentication and UAA should make calls to login. Currently login calls UAA.

Actually the login server *does* do the authentication, and (as you have pointed out elsewhere) the Cloud Controller should be sending clients like vmc to the Login Server not to the UAA.  The Login Server actually only calls the UAA for authentication in "default", "native" or "legacy" mode if you will, which we were more or less forced to do by the fact that we need to support CF.com with it's native user account data.  In general a login server is free to do authentication any way it likes. It's pretty easy to strategise for browser clients.  For vmc you need to be able to accept authentication parameters as key=value pairs, but that hopefully isn't too strict a constraint.

That's the point I'm trying to make. login does NOT do the authentication. It delegates to UAA. In my opinion, this should be reversed. Take the authentication code out of AuthzAuthenticationManager and put it in login. Then change UAA so that it delegates to login. Legacy clients can still hit UAA for authentication or hit login (as they should.)

As we discussed previously, even if you tell your CC to use login as its "authorization_endpoint", the latest VMC will send a GET to login.appdomain/login, use the prompt provided by the login server and then do the actual authentication request to UAA and not login. If UAA delegated the authentication to login, this wouldn't matter. (VMC should still, of course, be fixed.)
 


Also, when a browser goes to uaa for authentication, the browser should be redirected to login.

That's a possibility.  Instead we have gone with a whitelabel UAA, which works, but is ugly and contains a message with a link saying something like "If you see this page you are probably in the wrong place".  We don't wan t to prevent the UAA from being used as an authentication source for native user accounts, but we want to discourage client apps from trying to use it for SSO.  You should see that coming out in UAA 1.4 pretty soon.


In the future, it would a be a really nice feature to allow the login server to specify OAuth scopes whether that comes from LDAP groups or some other source. The ability to easily customize this is what's most important to me.

Agree, and we are definitely going to have to support that pattern. But it goes beyond authentication, which is what we are focused on currently with several internal and external deployments.  Your experience might be valuable when we get to the groups and scopes. My sense is that the UAA will always need a database with that information in it, but it might be automatically provisioned by the login server.

Certainly. And we can kick this can down the road since I think that we both agree that there are bigger priorities atm.
 


D.

--
Dave Syer
ds...@vmware.com


P.S. Thanks for being so incredibly responsive on this issue. This is easily one of the best, most professional open source communities I've ever been involved with.

Dave Syer

unread,
Feb 11, 2013, 5:12:43 PM2/11/13
to vcap...@cloudfoundry.org
On 11/02/13 21:28, Mike Heath wrote:
> login does NOT do the authentication. It delegates to UAA. In my
> opinion, this should be reversed. Take the authentication code out of
> AuthzAuthenticationManager and put it in login. Then change UAA so
> that it delegates to login. Legacy clients can still hit UAA for
> authentication or hit login (as they should.)

I'm not really sure I agree yet, , or maybe we are agreeing and we
haven't hit the right words, or maybe we mean something different by
"authentication". You can't take the authentication code out of
AuthzAuthenticationManager - it's the only way the UAA can authenticate
anything and we need that as a "native" implementation when there is no
Login Server. If there is a Login Server the AuthzAuthenticationManager
should be redundant (and should pretty much always fail with an external
authentication source unless the user accounts actually have their
passwords accidentally the same).

--
Dave Syer
ds...@vmware.com

Dave Syer

unread,
Feb 14, 2013, 12:03:02 PM2/14/13
to vcap...@cloudfoundry.org
On 05/02/13 18:00, Mike Heath wrote:
> After I enter my login credentials, VMC tries to authenticate against
> UAA. It looks like VMC is broken. (BTW - This would be MUCH easier to
> troubleshoot if vmc -t would show the host being used.

I finally got round to trying this myself and reproduced the problem you
were seeing. It's not vmc, it's the Login Server that is sending your
credentials to the UAA (but only for vmc clients, i.e. if you use a
browser instead of vmc the flow works). I fixed the bug so you can see
what I did on the "develop" branch [cfid-616] (you need the "develop"
branch of the UAA to match that if you want to try it yourself, or you
can wait a short while for us to release onto "master").

cedric....@gmail.com

unread,
May 13, 2013, 10:07:35 AM5/13/13
to vcap...@cloudfoundry.org, ds...@vmware.com
Hello David,

I'm currently struggling to use LDAP in place of the UserDatabase. I've just heard of the "login" application and now i'm pretty confused...

What i want to achieve is the following : use the "password" grant to get an access token from this url : http://localhost:8080/uaa/oauth/token (via an LDAP instead of the database). Then, the oauth client will send the token over to a ResourceServer which will validate the token and return the protected resource. As you can notice, we won't use the SSO mechanism.

What i've done so far is modifying the "tokenEndpointAuthenticationFilter" to use my own authenticationManager for LDAP lookup. It actually works (my user is authenticated), but now i need to modify UaaTokenServices so it won't lookup the original database when creating the encrypted token. Maybe i will encounter the same problem when verifying the token later on.

My question is : Am i on the right track, or am i not supposed to adapt the "uaa server", but the "login" application instead. I don't have any notions of Ruby or whatsoever...

Thanks in advance !

Dave Syer

unread,
May 13, 2013, 10:38:15 AM5/13/13
to vcap...@cloudfoundry.org
On 13/05/13 15:07, cedric....@gmail.com wrote:
> Am i on the right track, or am i not supposed to adapt the "uaa server",
> but the "login" application instead. I don't have any notions of Ruby or
> whatsoever...

There is no need for any Ruby wrangling, and the Login server is
optional (but it does provide SSO and an opportunity to customize the UI
without touching the UAA). In either case (Login Server or UAA) you
should only need to replace an authentication manager to make it work.

The Login Server even has this set up for you with the ldap profile
(Spring Profile, ie. "spring_profiles: ldap" in login.yml or
-Dspring.profiles.active=ldap on command line).

You could copy that into the UAA, and the only thing that will change is
the bean name. I think you must have been on the right track but just
overrode the wrong authentication manager - the one you want is the one
in the <password/> grant declaration (authzAuthenticationMgr).

--
Dave Syer
ds...@gopivital.com


cedric....@gmail.com

unread,
May 13, 2013, 11:00:07 AM5/13/13
to vcap...@cloudfoundry.org
Thank you for your swift reply !

Actually, that is what i did (replacing authzAuthenticationMgr). However, "UaaTokenServices" gets called afterwards for creating the refresh and access tokens... And it looks for my Principal in the database, which can never be found since it's only known in ldap. 
I'm currently overriding UaaTokenServices to create the tokens with my own UserInfo... Is that wrong ?

P.S : in UaaTokenServices : UaaUser user = userDatabase.retrieveUserByName(((Principal) authentication.getPrincipal()).getName());

Dave Syer

unread,
May 13, 2013, 11:05:20 AM5/13/13
to vcap...@cloudfoundry.org
On 13/05/13 16:00, cedric....@gmail.com wrote:
> P.S : in UaaTokenServices : UaaUser user =
> userDatabase.retrieveUserByName(((Principal)
> authentication.getPrincipal()).getName())

Ah, I see. I wonder if that is necessary. I'll create a story
internally for someone to look at that and see if it is. I would expect
the principle to be available anywhere it is needed via the
AuthenticationManager.

(If you feel like fixing it go ahead.)

--
Dave Syer
ds...@gopivital.com


cedric....@gmail.com

unread,
May 14, 2013, 6:31:09 AM5/14/13
to vcap...@cloudfoundry.org
Ok. What i finally did is creating a custom "UaaUserDatabase" implementation that connects to my ldap and creates a UaaUser out of it. This is mostly stub data in it...
And i inject this implementation into UaaTokenServices and it works like a charm. Now i have to adapt the tests (which seem to loop infinitely) and user roles/grants :)

cedric....@gmail.com

unread,
May 15, 2013, 10:40:35 AM5/15/13
to vcap...@cloudfoundry.org
Dave, one more thing :

UaaTokenServices doesn't seem to encode the token with the authorities associated to a user in my LDAP, but only those from the client.
If i define a user "Paul" with authoritiy "GROUP-test" in Ldap, and that i restrict access to this group in my resource server, it doesn't work :
<s:intercept-url pattern="/*.html*" access="GROUP-test"/>

-> access is denied.

Is there a way i can still use my own user authorities ?

On Monday, 13 May 2013 17:05:20 UTC+2, Dave Syer wrote:

Dave Syer

unread,
May 15, 2013, 10:49:31 AM5/15/13
to vcap...@cloudfoundry.org
On 15/05/13 15:40, cedric....@gmail.com wrote:
> Is there a way i can still use my own user authorities ?

If you aren't using the UAADB at all then you need to grab the
authorities from your backend and stick them in the UaaUser.authorities.
The token, however, will still only include groups that are included
in the client registration scopes (not all clients can act with the full
authorities of a user).

--
Dave Syer
ds...@gopivital.com


cedric....@gmail.com

unread,
May 15, 2013, 11:22:20 AM5/15/13
to vcap...@cloudfoundry.org
>If you aren't using the UAADB at all then you need to grab the 
authorities from your backend and stick them in the UaaUser.authorities. 

Ok, no problem with that (although i don't know where they will be of use)

>The token, however, will still only include groups that are included 
in the client registration scopes (not all clients can act with the full 
authorities of a user). 

Then how can we deal with access rights ? Let's say "app" is a ResourceServer that protects a resource. What if my user does not have sufficient rights ("GROUP-test" and not "GROUP-production") to access the resource ? I would like my "app" to return the resource if the user is authenticated and has the rights to access it...

Dave Syer

unread,
May 15, 2013, 11:38:55 AM5/15/13
to vcap...@cloudfoundry.org
On 15/05/13 16:22, cedric....@gmail.com wrote:
> I would like my "app" to return the resource if the user is
> authenticated and has the rights to access it...

If your resource server is a Spring application you can use the
ScopeVoter (or oauth2 SpEL expression support). There are samples in
the UAA codebase of both. If your app is not a Spring app you need to
decode the token and then look at the scopes to decide what authorities
the user has.

--
Dave Syer
ds...@gopivital.com


cedric....@gmail.com

unread,
May 16, 2013, 5:42:57 AM5/16/13
to vcap...@cloudfoundry.org
Yes my resource server is a spring app.
I've noticed an interesting thing in RemoteTokenServices :

if (map.containsKey("user_authorities")) {
@SuppressWarnings("unchecked")
 ....
} else {
// User authorities had better not be empty or we might mistake user for unauthenticated
userAuthorities.addAll(getAuthorities(scope));
}

It always goes into the else clause because "user_authorities" are never retrieved from the "chek_token" endpoint url (the "claims" map)... Even if UaaUser is set with the right user authorities.
If the user authorities are not encoded in the token at creation time, i'll of course never retrieve them afterwards.

Dave Syer

unread,
May 16, 2013, 8:20:37 AM5/16/13
to vcap...@cloudfoundry.org
On 16/05/13 10:42, cedric....@gmail.com wrote:
> It always goes into the else clause because "user_authorities" are never
> retrieved from the "check_token" endpoint url

That's could be a bug, but I think it's probably OK (the scope of the
token maps directly to the authorities of the user). Not many people
actually use the /check_token endpoint, but we should encourage it, so
I'll take a look. Isn't it behaving the way you want (I'm not really
clear on that)?

--
Dave Syer
ds...@gopivital.com


cedric....@gmail.com

unread,
May 16, 2013, 8:45:59 AM5/16/13
to vcap...@cloudfoundry.org
Actually, the /check_token and RemoteTokenServices features seem absolutely fine.
The only thing that bothers me is UaaTokenServices, for 2 reasons :
- it is coupled to a UaaUser when maybe not necessary (see my first post on this thread), for which you said you'd create a story. It is however not blocking for me.
- it doesn't map my user_authorities when creating the access token, which makes RemoteTokenServices unable to find them in the map i get back from CheckTokenEndpoint ! But the fact that RemoteTokenServices looks for "user_authorities" makes me think it might be a bug, probably not important in your case but blocking for those who need user authorities and not only client authorities. 

Dave Syer

unread,
May 16, 2013, 9:08:33 AM5/16/13
to vcap...@cloudfoundry.org
On 16/05/13 13:45, cedric....@gmail.com wrote:
> it doesn't map my user_authorities when creating the access token

It does I think. You just need to make sure that the client also has
those groups/roles/whatever registered as scopes.

--
Dave Syer
ds...@gopivital.com


cedric....@gmail.com

unread,
May 16, 2013, 9:45:29 AM5/16/13
to vcap...@cloudfoundry.org
To be clearer, in UaaTokenServices, i don't see a authentication.getUserAuthentication().getAuthorities() (the ones from my ldap) be used anywhere in the creation of the JWT token as i would expect it to.

Dave Syer

unread,
May 16, 2013, 9:54:31 AM5/16/13
to vcap...@cloudfoundry.org
On 16/05/13 14:45, cedric....@gmail.com wrote:
> To be clearer, in UaaTokenServices, i don't see a
> authentication.getUserAuthentication().getAuthorities()

Look at UaaAuthorizationRequestManager.checkUserScopes().

--
Dave Syer
ds...@gopivital.com


cedric....@gmail.com

unread,
May 16, 2013, 10:07:44 AM5/16/13
to vcap...@cloudfoundry.org
Oh, the missing part of the puzzle... I understand now what you meant by adding those scopes to the client, and the general oauth/scope/spring mechanism.

Thanks a lot for the support Dave.

James Bayer

unread,
May 16, 2013, 12:26:37 PM5/16/13
to vcap...@cloudfoundry.org
Cedric, I'm glad it appears you've worked it out with Dave's help. Are there things we can document about what you've learned to make it better for someone else wanted to do LDAP integration and passing LDAP groups as OAuth scopes? Is the work you did custom to your specific directory integration or is there reusable code for this part? Do you think a sample would help?

The most popular blog I ever wrote was in 2007 showing how to integrate WebLogic Server with OpenLDAP. It'd be great if we had something like this for UAA.
--
Thank you,

James Bayer

cedric....@gmail.com

unread,
May 17, 2013, 5:11:28 AM5/17/13
to vcap...@cloudfoundry.org

Hello James,

It would have helped me in the beginning if I knew I just had to replace the authz manager by my own ldap manager. It took me some research in the code to find that out. It would be nice to have a quick overview of the main configuration components, and what they do.

Then, another sticking point would be the use of UaaUser in UaaTokenServices. It takes a UaaUser to encrypt the token, and my LdapUser is nowhere close to a UaaUser. Therefore I created another UaaUserDatabase implementation to return a stubbed “UaaUser”… This is the only bit of code I had to write to make the whole thing work (except adapting the config files of course), and it’s more of a “hack” than an actual real business implementation. Oh and that’s right, I also had my LdapUser class implement the Security interface to avoid a ClassCastException. In the UaaUser I return, I also have to add an imaginary “modifiedDate” (which I don’t have in my ldap), otherwise an exception is thrown since I create a new User and uaa thinks the password has changed, but not the access token.

Finally, I struggled to use the ‘user authorities’ from my ldap to filter security access, but I guess that is a gap of spring security/oauth knowledge on my side. However, a reference to “UaaAuthorizationRequestManager” would have saved me some time in terms of comprehension with roles/groups.

 

>Are there things we can document about what you've learned to make it better for someone else wanted to do LDAP integration and passing LDAP groups as OAuth scopes?

If all I said was documented, I’m sure it would help :)

>Is the work you did custom to your specific directory integration or is there reusable code for this part?

It’s mainly configuration so far… I use the cloudfoundry-common jar, and adapt the config files.

But if your goal is for us to use the uaa jar as-is, I think a small rework in UaaTokenServices is necessary to avoid the “hack” I had to do… Hence having a “User” interface instead of a “UaaUser” class, and a documentation that states “you need to replace the UserDatabase with your own in the spring config files”.

>Do you think a sample would help?

It surely wouldn’t hurt, but in the end, the integration of LDAP was not so hard. With a good documentation and some LDAP-spring config knowledge, no problem !

Mike Heath

unread,
May 17, 2013, 10:54:14 AM5/17/13
to vcap...@cloudfoundry.org
You also have to be careful with the value of "modifiedDate" because it's used when tokens get validated using /check_token. If you're doing something like "new Date()" for the modified date, the check token will always fail because it's assuming the user's password changed after the token was issued. In our LDAP integration, we use a really old static date. We'd like to come up with something better but we don't store modification date/times in our directory either.

-Mike

cedric....@gmail.com

unread,
May 17, 2013, 10:59:49 AM5/17/13
to vcap...@cloudfoundry.org
Yes, that is exactly what i did, a static date in the past.

James Bayer

unread,
May 17, 2013, 8:49:39 PM5/17/13
to vcap...@cloudfoundry.org
Thanks for the detailed reply Cedric and your comments Mike. I'll talk to the identity team to see if we can get these things written up.

Wei Tie

unread,
May 27, 2013, 11:54:26 PM5/27/13
to vcap...@cloudfoundry.org
New follower of the threads. After reading the posts above, I'm a little confused about the uaa and login server. seems that there are 2 opinions, one is that  the uaa is a native authorization component and login is for user customize , and login using uaa as default to do  authorize, but it could be others (LDAP) by adjust it in login part. the other is  the login just handle the request of client and send it to uaa to do authorize so that if we want add ldap supported, we should do some hack in the uaa part instead of login part. which one is on the right track?
I prefer the second one because vmc will request uaa.domain.com to do authorization instead of login server (this is got from cc, configured in "cc.yml" property "uaa.url"). And seems that uaa is trying to support more authorization methods. Whether  the login server  necessary when we enabled uaa ? The uaa server can handle /oauth/authorize request (get the info from uaa api doc not code) to do authorize, and response the vmc and web request. If so, and we add ladp support in uaa , what's the login server for ?
I'm trying to add ladp support for uaa/login, some points not quite understand, looking for your help.

Dave Syer

unread,
May 28, 2013, 3:11:29 AM5/28/13
to vcap...@cloudfoundry.org
On 28/05/13 04:54, Wei Tie wrote:
> what's the login server for

It's an abstraction, and a place to do branding and authentication
customizations, if your use case fits that model. I think there are 2
breeds of integration emerging with external systems: one retains the
UAADB and the other doesn't.

If you want to retain the UAADB then the login server is a good option,
e.g. if you want to have Cloud Foundry specific user and group
management, somewhat independent of your external data sources (allowing
users to manage Cloud Foundry access a little bit independently). You
probably don't need to change the UAA at all in that case, and you
should benefit from the resulting stability and supportability.

If you don't want to retain the UAADB (like the original poster in this
thread) then you might still choose to use a login server layer, but
since you are modifying the UAA anyway, arguably you might as well put
all your changes in there.

Personally I think the login server in both cases gives you some
valuable flexibility to change UI and UX features (like autologin)
independently of the token serving and checking features (UAA). It's
your choice.

--
Dave Syer
ds...@gopivital.com


Finch Tie

unread,
May 28, 2013, 5:10:05 AM5/28/13
to vcap...@cloudfoundry.org
Thank you for your quick reply !
As you mentioned the 2 kinds of integration way,  in the "retain UAADB" way do you mean using ladp for authorization and the user will import into UAADB (enable group management etc.) ?  plus, it seems that the latest login-server 1.4.2 has supported ladp, but I'm not quite sure how to configure it ( new bee to spring-security). 
The second way looks like need to add specific user management (group org etc.) processes, and not using UAADB for store user info, am I right ?

---
Finch Tie


Dave Syer

unread,
May 28, 2013, 6:22:03 AM5/28/13
to vcap...@cloudfoundry.org
On 28/05/13 10:10, Finch Tie wrote:
> do you mean using ladp for authorization and the user will import into
> UAADB (enable group management etc.) ?

Yes. The UAA will do that semi-automatically. At the moment it only
supports importing user accounts and not group memberships. Someone is
working on the groups thing.

> it seems that the latest
> login-server 1.4.2 has supported ladp, but I'm not quite sure how to
> configure it ( new bee to spring-security).

In login.yml

spring_profiles: ldap

That switches it on. To change the configuration you might be able to
use the defaults, and only supply a URL for the remote LDAP server (see
the ${...} placeholders in the config file for details. Or you might
need to edit the Spring config file. Spring LDAP is pretty mature and
there are plenty of resources in the interweb for getting help with that.

> The second way looks like need to add specific user management (group
> org etc.) processes, and not using UAADB for store user info, am I right ?

Yes, that's what the OP did (not sure what you mean by "processes" -
assuming translation error and you mean "strategies" or something).
There are a couple of users on this list who have tackled this problem.
One of them (the OP on this thread) implemented UaaUserDatabase (I
think), and the other went ahead and implemented all the Scim*
interfaces as well. The former is a read-only approach, and the latter
is potentially read-write, since the UAA endpoints support those through
the Scim interfaces.

--
Dave Syer
ds...@gopivital.com


Finch Tie

unread,
May 28, 2013, 6:41:27 AM5/28/13
to vcap...@cloudfoundry.org
Sincerely thank you .
Currently my case is helping ldap user have a try of cf, so a quick and
smooth way is what I exactly need, your answer do help a lot !

Finch Tie

unread,
May 30, 2013, 5:46:10 AM5/30/13
to vcap...@cloudfoundry.org
I tested my login-server, it worked well with ldap, but another problem comes out.

We are using cf v1 api and using vmc tools to interact with cf, versions as below
cf-uaa-lib (1.3.10)
cfoundry (0.5.2)
vmc (0.5.0)

which looks like not working well with login-server. the vmc will request login.domain.com/oauth/token to do authorize( due to the cfoundry  version.), which path is in login-server is marked as <sec:http pattern="/oauth/token" security="none" /> ( It will not do authorize I think ), correct url should be /oauth/authorize
After looked into the code, I found the  cfoundry gem is too old still do token_issuer.owner_password_grant(username, password) (https://github.com/cloudfoundry/vmc-lib/blob/master/lib/cfoundry/uaaclient.rb#L23) which will request the outdated url, and yes current vmc still using vmc-lib repo as cfoundry (https://github.com/cloudfoundry/vmc/blob/master/Gemfile#L12).

I'm trying update vmc with cfoundry 1.5.1 and test whether is works, work will be done after supper, If it works, I think someone could update the vmc gem file
Just notify, if someone met the same problem.

---
Finch Tie


Dave Syer

unread,
May 30, 2013, 8:27:54 AM5/30/13
to vcap...@cloudfoundry.org
The cf cli uses /token by default as well so we have a Login Server 1.3
release in the pipeline to support proper external authentication
(everything works with the CF.com because the UAA handles authentication).

On 30/05/13 10:46, Finch Tie wrote:
> I'm trying update vmc with cfoundry 1.5.1 and test whether is works

Maybe. If so good luck. For the v1 LDAP deployments I have worked on I
just made sure that vmc was 0.4.* or 0.3.*. I think using the /token
endpoint was a late addition and it was never really tested with v1
platforms.

--
Dave Syer
ds...@gopivital.com


Finch Tie

unread,
May 31, 2013, 5:40:56 AM5/31/13
to vcap...@cloudfoundry.org
Thank you for your advise, I finished my work just now, with vmc 0.4.7.

Some points to share with someone have the same needs.
1, check the cloudfoundry-identity-uaa-1.4.1.war  and cloudfoundry-login-server-1.2.1.war , early version not checked, I think if login server support ldap is ok
2, in login.yml, set 
spring_profiles: ldap ldap: base: url: 'ldap://your.domain.com:389/dc=domain,dc=com' userDnPattern: 'CN={0},ou=Employees, ou=Users' // if you want edit the dn pattern, edit the spring-serverlet.xml ldapAuthProvider by 
 // <value>${ldap.base.userDnPattern:uid={0},ou=people}</value>

3. if the user is in uaadb, will pass the authorize, or return 401, 
Or If want add ldap users as new user into uaa db, edit the uaa.yml, set 
login
  addnew: true

4.  enjoy.

Thanks Dave Syer 's patient , your answer  truly helped.

---
Finch Tie



On May 30, 2013, at 8:27 PM, Dave Syer <ds...@gopivotal.com> wrote:



Adam Greene

unread,
Jun 12, 2013, 8:11:39 PM6/12/13
to vcap...@cloudfoundry.org
So is there any sort of write up for the LDAP integration?

James Bayer

unread,
Jun 13, 2013, 1:41:22 AM6/13/13
to vcap...@cloudfoundry.org
Not yet, but Joel D'sa told me that the Login Server is already capable of connecting to OpenLDAP for auth, it involves using a profile for LDAP and just needs to be documented. The team that is working on identity is quite stretched thin at the moment, so please bear with us. I know that people want to do this and we will document it soon.

Adam Greene

unread,
Jun 14, 2013, 6:24:36 PM6/14/13
to vcap...@cloudfoundry.org
Is there an software architecture showing how the pieces of UAA, authN, authZ, tokens, etc all work together? What is written into the UAADB, what can be kept in a separate user store, etc? I am having a hard time getting started in integrated CF into an existing identity and auth ecosystem. 

Wei Tie

unread,
Jun 14, 2013, 8:19:35 PM6/14/13
to vcap...@cloudfoundry.org
I write something about this in my blog, but most of which is  in Chinese, some graph may help.
If want to get detail, let me know and I'll translate it into English.

Adam Greene

unread,
Jun 14, 2013, 8:45:34 PM6/14/13
to vcap...@cloudfoundry.org
Thanks! I'll see how well I do with Google Translate and coworkers :)

Wei Tie

unread,
Jun 14, 2013, 9:02:03 PM6/14/13
to vcap...@cloudfoundry.org
OK, any questions please let me know
---
Wei Tie


alexz zzzz

unread,
Aug 21, 2013, 9:23:24 AM8/21/13
to vcap...@cloudfoundry.org
Hi Wei Tie !
sorry,but i have same problem with you on http://grokbase.com/t/cloudfoundry.org/bosh-users/137qyw8mtd/bosh-on-openstack-grizzly and i coldnt find any way to post to you..
so you spooke-because of
guestfs find out fstab is empty, and add an echo after the debootstrap in
stemcell builder base_debootstrap stage will fix the error.
can you little be Moore about it fix?  
I use RDO allinOne system with neutron, and all work except Bosh.
before this try- i try run on Folsom with nova-network-and all work perfect.
i can get you all info,i what you need.
i hope you help me!Thanks)
Reply all
Reply to author
Forward
0 new messages