= RH SSO Deployment and Command Line Client QuickStart
:toc:
:source-highlighter: coderay
= Shared RH SSO Deployment
This repository contains the RH SSO deployment that is shared by the secured versions of the quick starts.
= Realm Model
The JSON description of the RH SSO master realm that we deploy in this quick start can be found in the
src/resources/master.json file. There are 4 pre-configured application client definitions that model the command line
client and the 3 REST secured endpoints. There are also two pre-configured users in the RH SSO master realm that can be
used to validate various authentication and authorization outcomes; admin and alice.
== The Application Clients
The OAuth2.0 specification that RH SSO supports has the notion of application clients that access secured resources on
behalf of resource owners. The master realm has 4 application clients defined.
=== The demoapp Client
This is a confidential type client with a client secret that is used to obtain an access token that contains grants
for the alice user which enable alice to access the Swarm, Vert.X and SpringBoot based REST deployments.
=== The secured-booster-endpoint Client
The secured-booster-endpoint is a bearer-only type of client that requires a booster-admin role for accessing the
associated resources.
== The Users
=== The admin User
The admin user has a password of admin, and is the realm adminstrator. This user has full access to the RH SSO administration
console, but none of the role mappings that are required to access the secured endpoints. You can use this user to
illustrate the behavior of an authenticated, but unauthorized user.
=== The alice User
The alice user is the canonical application user that will demonstrate successful authenticated and authorized access
to the secured endpoints. A representation of the role mappings is provided in this decoded JWT bearer token:
[source,json]
{
"jti": "5a785440-8cb4-4500-a9fc-0c3aec1e62d5",
"exp": 1489698336,
"nbf": 0,
"iat": 1489698276,
"iss": "https://secure-sso-sso.192.168.99.100.nip.io/auth/realms/master", <1>
"aud": "demoapp",
"sub": "c0175ccb-0892-4b31-829f-dda873815fe8",
"typ": "Bearer",
"azp": "demoapp",
"session_state": "7d296305-0c71-4dda-80d9-5b5ea4a584c1",
"client_session": "31cd83c8-6315-4daf-9aa7-e50e80611c2d",
"allowed-origins": [],
"realm_access": {
"roles": [ <2>
"booster-admin"
]
},
"resource_access": { <3>
"secured-booster-endpoint": {
"roles": [
"booster-admin" <4>
]
},
"account": {
"roles": [
"manage-account",
"view-profile"
]
}
},
"name": "Alice InChains",
"preferred_username": "alice", <5>
"given_name": "Alice",
"family_name": "InChains",
"email": "alice@keycloak.org"
}
<1> The iss(user) field corresponds to the RH SSO realm instance URL that
issues the token. This must be configured in the secured endpoint deployments in order for the token
to be verified.
<2> The roles object provides the roles that have been granted to the user at the global realm level. In this case
alice has been granted the booster-admin role. We will see that the Vert.X secured endpoint will look to the
realm level for authorized roles.
<3> The resource_access object contains resource specific role grants. Under this object you will find an object
for each of the secured endpoints.
<4> The resource_access.secured-booster-endpoint.roles object contains the roles granted to alice for the secured-booster-endpoint
resource.
<7> The preferred_username field provides the username that was used to generate the access token.
= Prerequisites
To get started with these quickstarts you'll need the following prerequisites:
.Required Software
|===
|Name |Description |Version
|http://www.oracle.com/technetwork/java/javase/downloads/[java]
|Java JDK
|8
|https://maven.apache.org/download.cgi?Preferred=ftp://mirror.reverse.net/pub/apache/[maven]
|Apache Maven
|3.2.x
|https://docs.openshift.com/enterprise/3.2/cli_reference/get_started_cli.html[oc]
|OpenShift Client
| v3.3.x
|https://git-scm.com/book/en/v2/Getting-Started-Installing-Git[git]
| Git version management
| 2.x
|===
In order to build and deploy this project, you must have an account on an OpenShift Online (OSO): https://console.dev-preview-int.openshift.com/ instance.
# OpenShift Online
* Using OpenShift Online or Dedicated, log on to the OpenShift console and obtain
your command line login by accessing the Command Line Tools item in the
image:images/Qmark.png[?, title="?"] drop down menu.
image:images/OSOConsole.png[Command Line Tools]
On that page you will see an oc login... section that looks like the following
once you have expanded the "...click to show token..." section:
image:images/OSOLogin.png[Login]
Copy that command and enter it into a shell to login to the OSO server.
* Create a new project on OpenShift if you don't already have one. You can check this via the `oc status` command.
[source,shell]
oc new-project some_project_name
## Deploy the SSO server.
From the root of this project, simply run the following command:
[source,shell]
mvn fabric8:deploy
### Determine the SSO_AUTH_SERVER_URL value
For each of the secured REST quick starts, you will need to configure the RH SSO authorization endpoint. This project
contains a command line program that you can run to determine this information. It was built when you deployed the
RH SSO server, so you can now run the program using:
[source,shell]
[redhat-sso 698]$ java -jar target/sso-client.jar --displaySSOURL
Successful oc get routes: Yes
Using auth server URL: https://secure-sso-sso.e8ca.engint.openshiftapps.com/auth
Available application endpoint names: [secured-vertx-rest, secured-swarm-rest, secured-springboot-rest]
The line starting with *"Using auth server URL:"* is the line that provides the SSO_AUTH_SERVER_URL. In this case it is
'https://secure-sso-sso.e8ca.engint.openshiftapps.com/auth'. Save that someplace and proceed with deploying one of the
secured REST quick starts.
# Deploy the Secured Endpoints
Now you can deploy one or more of the secured versions of the quick starts by cloning them and following the OSO deployment
instructions. Current secured quick starts include:
* https://github.com/wildfly-swarm-openshiftio-boosters/wfswarm-rest-http-secured[secured_rest_swarm]
* https://github.com/snowdrop/spring-boot-http-secured-booster[secured_rest-spring-boot]
* https://github.com/openshiftio-vertx-boosters/vertx-secured-http-booster[secured_rest-vertx]
Checkout one or more of these using the --recursive option to clone, e.g.,
`git clone --recursive https://github.com/wildfly-swarm-openshiftio-boosters/wfswarm-rest-http-secured`
This pulls in this redhat-sso quick start as a submodule of that project so that you can work from within that subproject.
Clone one of these projects now, and then come back here to test access the secured endpoint once you have completed the
deployment steps from the secured REST endpoint quick start.
# Access the Secured Endpoints
Once you have one of the secured endpoints deployed to OSO, you can access them using the Java command line client included
in this project. It is packaged as an executable jar and is located at target/sso-client.jar. To run the client, use
[source,shell]
java -jar target/sso-client.jar -app ...
The full set of command arguments that you can specify can be seen by passing -help:
[source,shell]
[redhat-sso 699]$ java -jar target/sso-client.jar -help
Specifiy the name of the application endpoint with --app
Usage: client.GreetingAuthzClient [options]
Options:
--app
The name of the rest endpoint to access
--debug
The debugging level, > 0 means more verbosity
Default: 0
--displaySSOURL
Obtain and display the RH SSO server auth URL and then exit
Default: false
--from
The name to pass to the greeting endpoint
Default: World
--password
The SSO Realm password to authenticate with
Default: password
--user
The SSO Realm username to authenticate as
Default: alice
The only required argument is the --app argument. This needs to match up to the name of the service endpoint as known by OSO. You
can get a list of the using the `oc get routes` command. The following table shows sample output where the command
was run on a OSO project that had all 3 secured endpoints and the RH SSO server have been deployed:
.Sample oc get routes output
[format="csv", options="header"]
[cols="3,5,1,2,1,2"]
|===
NAME,HOST/PORT,PATH,SERVICES,PORT,TERMINATION
secure-sso,secure-sso-sso.e8ca.engint.openshiftapps.com,,secure-sso,
,passthrough
secured-springboot-rest,secured-springboot-rest-sso.e8ca.engint.openshiftapps.com,,secured-springboot-rest,,
secured-swarm-rest,secured-swarm-rest-sso.e8ca.engint.openshiftapps.com,,secured-swarm-rest,8080,
secured-vertx-rest,secured-vertx-rest-sso.e8ca.engint.openshiftapps.com,,secured-vertx-rest,,
sso,sso-sso.e8ca.engint.openshiftapps.com,,sso,,
|===
The deployed application names is also available via the output of the java command line client used to display the
SSO_AUTH_SERVER_URL. If you look at the following output:
[source,shell]
[redhat-sso 698]$ java -jar target/sso-client.jar --displaySSOURL
Successful oc get routes: Yes
Using auth server URL: https://secure-sso-sso.e8ca.engint.openshiftapps.com/auth
Available application endpoint names: [secured-vertx-rest, secured-swarm-rest, secured-springboot-rest]
The line beginning with *Available application endpoint names:* shows the non-SSO related application names.
You will want to choose a name from among the following, depending on what you have deployed:
* secured-springboot-rest
* secured-swarm-rest
* secured-vertx-rest
## Example Client Output
### secured-swarm-rest with default user
[source,shell]
[redhat-sso 657]$ java -jar target/sso-client.jar --app secured-swarm-rest
Successful oc get routes: Yes
Using auth server URL: https://secure-sso-sso.e8ca.engint.openshiftapps.com
Available application endpoint names: [secured-vertx-rest, secured-swarm-rest, secured-springboot-rest]
{
"id" : 15,
"content" : "Hello, World!",
"node" : "cb5aaf4f-95a7-47d6-a8cb-4f6e0be762b7"
}
### secured-swarm-rest with default user, bad password
[source,shell]
[redhat-sso 658]$ java -jar target/sso-client.jar --app secured-swarm-rest --password bad
Successful oc get routes: Yes
Using auth server URL: https://secure-sso-sso.e8ca.engint.openshiftapps.com
Available application endpoint names: [secured-vertx-rest, secured-swarm-rest, secured-springboot-rest]
Exception in thread "main" java.lang.RuntimeException: Failed to request token
at client.authz.AuthzClient.obtainAccessToken(AuthzClient.java:67)
at client.GreetingAuthzClient.init(GreetingAuthzClient.java:94)
at client.GreetingAuthzClient.main(GreetingAuthzClient.java:61)
Caused by: javax.ws.rs.NotAuthorizedException: HTTP 401 Unauthorized
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.handleErrorStatus(ClientInvocation.java:214)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.extractResult(ClientInvocation.java:189)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.invoke(ClientInvocation.java:492)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocationBuilder.post(ClientInvocationBuilder.java:199)
at client.authz.AuthzClient.obtainAccessToken(AuthzClient.java:63)
... 2 more
### secured-swarm-rest with admin user
[source,shell]
[redhat-sso 660]$ java -jar target/sso-client.jar --app secured-swarm-rest --user admin --password admin
Successful oc get routes: Yes
Using auth server URL: https://secure-sso-sso.e8ca.engint.openshiftapps.com
Available application endpoint names: [secured-vertx-rest, secured-swarm-rest, secured-springboot-rest]
Exception in thread "main" javax.ws.rs.ForbiddenException: HTTP 403 Forbidden
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.handleErrorStatus(ClientInvocation.java:216)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.extractResult(ClientInvocation.java:189)
at org.jboss.resteasy.client.jaxrs.internal.proxy.extractors.BodyEntityExtractor.extractEntity(BodyEntityExtractor.java:60)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invoke(ClientInvoker.java:107)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientProxy.invoke(ClientProxy.java:76)
at com.sun.proxy.$Proxy22.greeting(Unknown Source)
at client.GreetingAuthzClient.getGreeting(GreetingAuthzClient.java:139)
at client.GreetingAuthzClient.main(GreetingAuthzClient.java:62)
### secured-vertx-rest with admin user, debug 2
[source,shell]
[redhat-sso 688]$ java -jar target/sso-client.jar --app secured-vertx-rest --user admin --password admin --debug 2
Successful oc get routes: Yes
Using auth server URL: https://secure-sso-sso.e8ca.engint.openshiftapps.com
Available application endpoint names: [secured-vertx-rest, secured-swarm-rest, secured-springboot-rest]
Sending POST to: https://secure-sso-sso.e8ca.engint.openshiftapps.com/auth/realms/master/protocol/openid-connect/token
Headers:
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Body: grant_type=password&username=admin&password=admin&client_id=demoapp&client_secret=1daa57a2-b60e-468b-a3ac-25bd2dc2eadc
-----------
Token: eyJhbGciOiJSUzI1NiJ9.eyJqdGkiOiJkNWE1ZTg0YS00NGUyLTQzNTYtOTBiOS0zZTAwOWFiNjU2OGMiLCJleHAiOjE0ODk3MzExNjcsIm5iZiI6MCwiaWF0IjoxNDg5NzMxMTA3LCJpc3MiOiJodHRwczovL3NlY3VyZS1zc28tc3NvLmU4Y2EuZW5naW50Lm9wZW5zaGlmdGFwcHMuY29tL2F1dGgvcmVhbG1zL21hc3RlciIsImF1ZCI6ImRlbW9hcHAiLCJzdWIiOiIyNjI2NzdmYS0xMDJiLTRkNjAtOWE2MS1iMWNhMmFmZDY2M2EiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJkZW1vYXBwIiwic2Vzc2lvbl9zdGF0ZSI6ImNmNDIwOTA0LWI0OTYtNDVlZS04OTIxLTExNDM1MTkwNDU2MCIsImNsaWVudF9zZXNzaW9uIjoiYjYwZjM3YzItMjFhMC00MjMyLTk1ZTktMzFmMDE2ZmM3ZmRkIiwiYWxsb3dlZC1vcmlnaW5zIjpbXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbImNyZWF0ZS1yZWFsbSIsImFkbWluIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsibWFzdGVyLXJlYWxtIjp7InJvbGVzIjpbIm1hbmFnZS1ldmVudHMiLCJ2aWV3LWlkZW50aXR5LXByb3ZpZGVycyIsInZpZXctcmVhbG0iLCJtYW5hZ2UtcmVhbG0iLCJtYW5hZ2UtaWRlbnRpdHktcHJvdmlkZXJzIiwiaW1wZXJzb25hdGlvbiIsInZpZXctZXZlbnRzIiwiY3JlYXRlLWNsaWVudCIsIm1hbmFnZS11c2VycyIsInZpZXctdXNlcnMiLCJ2aWV3LWNsaWVudHMiLCJtYW5hZ2UtY2xpZW50cyJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsInZpZXctcHJvZmlsZSJdfX0sIm5hbWUiOiIiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiJ9.kO0dHEY2V5lKVyz3JinqFww7IfL5wYn_6k7F-NfDLJ3O5skrAE64sZiP-7e9eCdQs5-r6SkOJL_3hhYZTu6XRAB23S_Dqo3AtknMw67EB_BAPDYtsKzxGPrJWUVdo7OJFGSHps2jXGPSkW74bt7LfgfurwxbFZx6Ga466NpyOawWEuSUNkQ3r2_KqpRMiasG5pbk3Wd7e5nspy1i8_GTwhSOumfcthyRnjhb_nPoJQFu6hKSXkHIp4QgAb_g2_apGUd3y8HoNTvncx-upTbNDWwvXmogvDn7F38wSsFfvbKfzicd1lXloO9tCAD9jbzDsSItWaMs7jGvS3xen2Uwog
Requesting greeting...
Sending GET to: http://secured-vertx-rest-sso.e8ca.engint.openshiftapps.com/greeting?name=World
Headers:
Accept: application/json
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJqdGkiOiJkNWE1ZTg0YS00NGUyLTQzNTYtOTBiOS0zZTAwOWFiNjU2OGMiLCJleHAiOjE0ODk3MzExNjcsIm5iZiI6MCwiaWF0IjoxNDg5NzMxMTA3LCJpc3MiOiJodHRwczovL3NlY3VyZS1zc28tc3NvLmU4Y2EuZW5naW50Lm9wZW5zaGlmdGFwcHMuY29tL2F1dGgvcmVhbG1zL21hc3RlciIsImF1ZCI6ImRlbW9hcHAiLCJzdWIiOiIyNjI2NzdmYS0xMDJiLTRkNjAtOWE2MS1iMWNhMmFmZDY2M2EiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJkZW1vYXBwIiwic2Vzc2lvbl9zdGF0ZSI6ImNmNDIwOTA0LWI0OTYtNDVlZS04OTIxLTExNDM1MTkwNDU2MCIsImNsaWVudF9zZXNzaW9uIjoiYjYwZjM3YzItMjFhMC00MjMyLTk1ZTktMzFmMDE2ZmM3ZmRkIiwiYWxsb3dlZC1vcmlnaW5zIjpbXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbImNyZWF0ZS1yZWFsbSIsImFkbWluIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsibWFzdGVyLXJlYWxtIjp7InJvbGVzIjpbIm1hbmFnZS1ldmVudHMiLCJ2aWV3LWlkZW50aXR5LXByb3ZpZGVycyIsInZpZXctcmVhbG0iLCJtYW5hZ2UtcmVhbG0iLCJtYW5hZ2UtaWRlbnRpdHktcHJvdmlkZXJzIiwiaW1wZXJzb25hdGlvbiIsInZpZXctZXZlbnRzIiwiY3JlYXRlLWNsaWVudCIsIm1hbmFnZS11c2VycyIsInZpZXctdXNlcnMiLCJ2aWV3LWNsaWVudHMiLCJtYW5hZ2UtY2xpZW50cyJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsInZpZXctcHJvZmlsZSJdfX0sIm5hbWUiOiIiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiJ9.kO0dHEY2V5lKVyz3JinqFww7IfL5wYn_6k7F-NfDLJ3O5skrAE64sZiP-7e9eCdQs5-r6SkOJL_3hhYZTu6XRAB23S_Dqo3AtknMw67EB_BAPDYtsKzxGPrJWUVdo7OJFGSHps2jXGPSkW74bt7LfgfurwxbFZx6Ga466NpyOawWEuSUNkQ3r2_KqpRMiasG5pbk3Wd7e5nspy1i8_GTwhSOumfcthyRnjhb_nPoJQFu6hKSXkHIp4QgAb_g2_apGUd3y8HoNTvncx-upTbNDWwvXmogvDn7F38wSsFfvbKfzicd1lXloO9tCAD9jbzDsSItWaMs7jGvS3xen2Uwog
Exception in thread "main" javax.ws.rs.ForbiddenException: HTTP 403 Forbidden
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.handleErrorStatus(ClientInvocation.java:216)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.extractResult(ClientInvocation.java:189)
at org.jboss.resteasy.client.jaxrs.internal.proxy.extractors.BodyEntityExtractor.extractEntity(BodyEntityExtractor.java:60)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invoke(ClientInvoker.java:107)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientProxy.invoke(ClientProxy.java:76)
at com.sun.proxy.$Proxy21.greeting(Unknown Source)
at client.GreetingAuthzClient.getGreeting(GreetingAuthzClient.java:145)
at client.GreetingAuthzClient.main(GreetingAuthzClient.java:64)
## Decoding JWT
There is a nice online decoder that you can use to decode a JWT to see it's contents at https://jwt.io/#debugger-io[JWT Debugger].
To use it, go to the site, and first use the Algorithm drop down menu to choose RS256. At that point you will a text input
box in the VERIFY SIGNATURE section that has text beginning with "-----BEGIN PUBLIC KEY-----". Copy the entire
"-----BEGIN...-----END PUBLIC KEY-----" block from here:
[source]
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoETnPmN55xBJjRzN/cs30OzJ9olkteLVNRjzdTxFOyRtS2ovDfzdhhO9XzUcTMbIsCOAZtSt8K+6yvBXypOSYvI75EUdypmkcK1KoptqY5KEBQ1KwhWuP7IWQ0fshUwD6jI1QWDfGxfM/h34FvEn/0tJ71xN2P8TI2YanwuDZgosdobx/PAvlGREBGuk4BgmexTOkAdnFxIUQcCkiEZ2C41uCrxiS4CEe5OX91aK9HKZV4ZJX6vnqMHmdDnsMdO+UFtxOBYZio+a1jP4W3d7J5fGeiOaXjQCOpivKnP2yU2DPdWmDMyVb67l8DRA+jh0OJFKZ5H2fNgE3II59vdsRwIDAQAB
-----END PUBLIC KEY-----
and replace all of the text in that input box with this text. This is the master realm public key from this quick start's
RH SSO server deployment.
Now, take the base64 encoding of a token from one of the client runs where you specified a --debug value > 0, and paste it
into the left text input box titled Encoded PASTE a TOKEN HERE. When you do that, it's header, payload sections will populate,
and there should be a Signature Verified box at the bottom.