This is a minimalistic OpenID Connect Provider that mainly supports the Resource Owner Password Credentials Grant to issue JWTs for Service to Service authentication.
More information is available in our Plan B Documentation.
Building the artifact and running all tests:
$ ./mvnw verify
Find the executable jar in the target directory. Building a Docker image with the above artifact:
$ sudo pip3 install scm-source
$ scm-source
$ docker build -t planb-provider .
Java interfaces and classes for some REST APIs are auto-generated on build by swagger-codegen-maven-plugin. Find the generated sources in target/generated-sources/swagger-codegen/.
$ ./setup-dev-cassandra.sh
Afterwards you can access the Cassandra command line client via Docker, e.g.:
$ docker exec -it planb-provider-cassandra cqlsh
cqlsh> DESCRIBE KEYSPACE provider;
$ export OAUTH2_ACCESS_TOKENS=customerLogin=test # fixed OAuth test token (unused)
$ export TOKENINFO_URL=https://example.com/oauth2/tokeninfo # required for /raw-sync REST API (unused here)
$ java -jar target/planb-provider-1.0-SNAPSHOT.jar --cassandra.contactPoints="127.0.0.1"
Requesting a new JWT via Resource Owner Password Grant (using the example credentials inserted into Cassandra above):
$ curl --silent -X POST -u test0:test0 -d "grant_type=password&username=test0&password=test0&scope=uid" \
"http://localhost:8080/oauth2/access_token?realm=/services" | jq .
When requesting a new token via Implicit Flow, client will redirect user agent to the authorize endpoint. To test this, open the following link in your browser:
Introducing credentials test0/test0 will redirect to the consent page. After accepting these, your agent should be redirected with the token as a parameter in the url, which should look like this:
The Authorization Code Grant flow is similar to the implicit flow, but we would be getting an authorization code instead of a token. To test this, open the following link in your browser:
After login and accepting the consents, you will be redirected to the callback with a authorization code as parameter:
Redeeming the code for a token can be done as follows:
$ curl --silent -X POST -d 'redirect_uri=http://localhost:8080/callback&code=<CODE_FROM_PREVIOUS_REQUEST>&grant_type=authorization_code&client_id=test1&client_secret=test1' "http://localhost:8080/oauth2/access_token" | jq .
Get the OpenID Connect configuration discovery document:
$ curl --silent http://localhost:8080/.well-known/openid-configuration | jq .
Retrieving all public keys (set of JWKs) for verification:
$ curl --silent http://localhost:8080/oauth2/connect/keys | jq .
Use OpenSSL to generate JWT signing keys.
$ openssl genrsa -out test-rs256-2048.pem 2048
$ openssl ecparam -genkey -out test-es256-prime256v1.pem -name prime256v1
$ openssl ecparam -genkey -out test-es384-secp384r1.pem -name secp384r1
$ openssl ecparam -genkey -out test-es512-secp521r1.pem -name secp521r1
The resulting PEM file's contents must be stored in the private_key_pem
column of the provider.keypair
Cassandra table.
TOKENINFO_URL
- OAuth2 token info URL (can point to Plan B Token Info), this is used to secure the
/raw-sync/
REST endpoints. CUSTOMER_REALM_SERVICE_URL
- Optional URL to Zalando customer service WSDL.
ACCESS_TOKEN_URI
- OAuth2 access token URL (can point to own endpoint), this is used to get OAuth tokens for upstream services.
CASSANDRA_CONTACT_POINTS
- Comma separated list of Cassandra cluster IPs.
CASSANDRA_CLUSTER_NAME
- Cassandra cluster name.
API_SECURITY_RAW_SYNC_EXPR
- Spring security expression, e.g. "#oauth2.hasScope('application.write_all_sensitive')"