Skip to content
Newer
Older
100644 269 lines (176 sloc) 8.16 KB
650b10c @dsyer Initial draft - uaa with hard-coded user database
dsyer authored
1 # Proof of Concept for Bento/LDAP Spring Security OAuth
ace5777 @daleolds start of UAA
daleolds authored
2
650b10c @dsyer Initial draft - uaa with hard-coded user database
dsyer authored
3 ## Quick Start
ace5777 @daleolds start of UAA
daleolds authored
4
650b10c @dsyer Initial draft - uaa with hard-coded user database
dsyer authored
5 Quick demo of command line usage:
ace5777 @daleolds start of UAA
daleolds authored
6
650b10c @dsyer Initial draft - uaa with hard-coded user database
dsyer authored
7 $ git clone git://github.com/vmware-ac/poc-identity.git
8 $ cd poc-identity
ace5777 @daleolds start of UAA
daleolds authored
9
650b10c @dsyer Initial draft - uaa with hard-coded user database
dsyer authored
10 $ export API=dsyerapi.cloudfoundry.com
11 $ export AUTH=dsyerauth.cloudfoundry.com
ace5777 @daleolds start of UAA
daleolds authored
12
650b10c @dsyer Initial draft - uaa with hard-coded user database
dsyer authored
13 $ ./login.sh $AUTH -scope read_vcap
ace5777 @daleolds start of UAA
daleolds authored
14
650b10c @dsyer Initial draft - uaa with hard-coded user database
dsyer authored
15 Enter your `api.cloudfoundry.com` credentials, and you should find
16 that you are authenticated. There is an OAUth2 token stored in a
17 local file `.access_token`. So you can read some resources on the
18 server:
19
20 $ ./get.sh $API/services
21
22 You should get back a JSON list of your services (or try `/apps` if
23 you don't actually have any services).
24
25 Note the the local `.access_token` is not the VMC authorization token,
26 it is an OAuth2 token with restricted scope (you should get access
27 denied if you try and POST to an `$API` resource). The VMC token is
28 stored in a shared database on the backend.
29
30 ## A VMC Proxy
31
32 Now do this:
33
34 $ vmc target dsyerapi.cloudfoundry.com
35 $ vmc login dsyer@vmware.com # use your own credentials
36
37 and you are all set to use `vmc` over OAuth2. The login command in
38 this case gave you `scope=read_vcap,write_vcap`.
39
40 ## Inventory
41
42 There are actually several projects here:
43
44 1. `auth` is an OAuth2 authorization service, and also an OpenID
45 provider.
46
47 2. `api` is an OAuth2 resource service
48
49 3. `app` is a user application that uses both of the above
50
51 4. `collaboration` is a draft implementation of the "Collaboration
52 Spaces Model" for CloudFoundry. Used by the `api` service.
53
54 5. `env` is a very basic Ruby webapp used to investigate Ruby idioms
55 for webapp security
56
57 The three Java webapps are deployed on CloudFoundry:
58
59 * `app` = http://dsyerapp.cloudfoundry.com
60 * `api` = http://dsyerapi.cloudfoundry.com
61 * `auth` = http://dsyerauth.cloudfoundry.com
62
63 In CloudFoundry terms
64
65 * `auth` is the Auth Service providing single sign on, plus authorized
66 delegation for back-end services and apps.
67
68 * `api` is `api.cloudfoundry.com` - it's a service that knows about
69 the collaboration spaces. N.B. *only* this component needs to know
70 about the collaboration spaces.
71
72 * `app` is `code.cloudfoundry.com` or `studio.cloudfoundry.com` - a
73 webapp that needs single sign on and access to the `api` service on
74 behalf of users
75
76 ## Preconditions
77
78 * The OAuth provider apps (`api` and `auth`) in this demo use a
79 relational database for sharing OAuth2 tokens. If you open them up as
80 Maven projects in Eclipse (STS) then the `*.launch` files in the `api`
81 module can be used to launch a database (`hsql-server.launch`) and a
82 UI (`hsql-manager.launch`). Right click and `Run As...`. On
83 CloudFoundry they can just share a mysql service.
84 Alternatively, the database can be run using `mvn -e -P rundb exec:java`.
85
86 * While this isn't necessarily relevant to all use cases, clients
87 should follow instructions from the server about cookies (in
88 particular `JSESSIONID`). You can use `curl -b ... -c ...` to do this
89 automatically.
90
91 * Clients should follow redirects where instructed, e.g. using `curl
92 -L` (or a browser).
93
94 ## The Auth Application
95
96 The authentication service is `auth`. It's a plain Spring MVC webapp,
97 deploy as normal in Tomcat or your container of choice.
98
99 ### Use Cases / Resources
100
101 Use `Accept: application/json` to get JSON responses, or `text/html`
102 to get (filename extensions `.json` and `.html` also work partially).
103
104 1. Login:
105
106 GET /login
107 POST /login.do?j_username=marissa@vmware.com&j_password=koala
108
109 2. Logout:
110
111 GET /auth/logout.do
112
113 3. Home page (for authenticated users):
114
115 GET /auth/
116 GET /auth/home
117
118 4. Get an access token directly using username/password.
119
120 GET /auth/oauth/authorize?grant_type=password
121
122 Example command line:
123
124 $ curl localhost:8080/auth/oauth/authorize?grant_type=password\&client_id=app\&username=marissa@vmware.com\&password=koala\&response_type=code\&scope=read_photos
125
126 Example response:
127
128 {
129 "access_token": "4e14e7ba-ae73-4932-89cd-07692d3c7bc0",
130 "expires_in": 43199,
131 "refresh_token": "f0d5ccd5-e636-4be3-a35a-32325982723e"
132 }
133
134 5. OpenID provider for SSO. An OpenID consumer (e.g. `app`) can
135 authenticate via the XRDS at `/auth/openid/users/{user}`.
136
137 ## The API Application
138
139 An example local resource service and also a proxy for the Cloud
140 Controller on `cloudfoundry.com`. It hosts the photo service from
141 Spring Security OAuth (client id `app`) under `/photos` and delegates
142 all other requests to `api.cloudfoundry.com`. You can use it as a raw
143 `vmc` target because although `vmc` doesn't know about OAuth2, the app
144 proxies all requests and translates an incoming OAuth2 header into a
145 native vcap header.
146
147 ### Use Cases
148
149 All resources are protected by default and client should get a 403 or
150 401 if they are not authorized. (N.B. the current implementation
151 redirects to a non-existent login page instead of throwing the
152 exception. Maybe a redirect to the Auth service would be better.)
153 Authorization comes through the access token from the authorization
154 service provided in a header:
155
156 Authorization: Bearer ...
157
158 1. List photos
159
160 GET /api/photos
161 Authorization: Bearer ...
162 Accept: application/json
163
164 Example command line:
165
166 $ curl -v localhost:8080/api/photos -H "Authorization: Bearer ..."
167
168 2. Grab specific JPG image (binary data)
169
170 GET /api/photos/{id}
171 Authorization: Bearer ...
172 Accept: image/jpeg
173
174 3. Get VCAP info (no auth header required)
175
176 GET /info
177 Accept: application/json
178
179 4. Get other VCAP stuff, e.g.
180
181 GET /apps
182 Authorization: Bearer ...
183 Accept: application/json
184
185 lists the apps. This service is just a proxy for `vcap` now.
186
187 4. Post other VCAP stuff, e.g.
188
189 POST /apps
190 Authorization: Bearer ...
191 Accept: application/json
192
193 To GET a CloudFoundry resource you need `scope=read_vcap` in your
194 OAuth2 authorization. To POST, DELETE, PUT you need
195 `scope=write_vcap`. To do both you need `scope=write_vcap,read_vcap`.
196
197 ## The App Application
198
199 This is a user interface (primarily aimed at browser) app that uses
200 OpenID for authentication (i.e. SSO) and OAuth2 for access grants. It
201 authenticates with the Auth service, and then accesses resources in
202 the API service.
203
204 ### Use Cases
205
206 1. See all photos
207
208 GET /app/photos
209
210 browser is redirected through a series of authentication and access
211 grant steps (which could be slimmed down to implicit steps not
212 requiring user at some point), and then the photos are shown.
213
214 2. See an individual photo
215
216 GET /app/photos/{id}
217
218 If the useer is already authenticated goes straight to the image,
219 delegating to the API service to get the actual bytes. The app is
220 acting as a simple proxy for the API service in this case.
221
222 3. See the currently logged in user details, a bag of attributes
223 grabbed from the open id provider
224
225 GET /app
226
227 ### Command line usage:
228
229 Local set up:
230
231 $ export APP=localhost:8080/app
232 $ export AUTH=http://localhost:8080/auth
233
234 Cloudfoundry set up:
235
236 $ export APP=dsyerapp.cloudfoundry.com
237 $ export AUTH=dsyerauth.cloudfoundry.com
238
239 Then
240
241 $ get() { location=$1; shift; curl -b ~/tmp/cookies.txt -c ~/tmp/cookies.txt -v -H "Accept: application/json; */*" $location $*; echo; }
242 $ mkdir ~/tmp
243 $ rm ~/tmp/cookies.txt
244
245 There are 4 requests to authenticate and get back to the original
246 saved request:
247
248 $ get $APP -L
249 $ get $APP/j_spring_openid_security_check -d action=verify -d openid_identifier=$AUTH/openid/xrds -L
250 $ get $AUTH/login.do -d j_username=marissa@vmware.com -d j_password=koala -L
251 $ get $AUTH/openid/authorize -d approve=true -L
252
253 ## The Env Application
254
255 A simple Ruby (Sinatra) application which is a client of the `api`
256 resource service. Prerequisites:
257
258 $ gem install sinatra oauth2
259
260 `oauth2` needs a newish version of gem, so you might have to `rvm use 1.9.2` to get it to install. Runs from the command line:
261
262 $ (cd env; ruby env.rb)
263
264 Make sure the `auth` and `api` applications are running on port 8080 and visit
265 [http://localhost:4567/auth](http://localhost:4567/auth) to see the OAuth dance
266 produce some output (e.g. list of photos from `api`), after authenticating and
267 authorizing at `auth`. Use a browser to make it automatic, or use curl and
268 follow redirects.
Something went wrong with that request. Please try again.