OAuth Provider Implementation
Table of Contents
Motivation
get rid of the insecure basic authentication of opendaylight for Restconf
instead implement JsonWebToken(JWT) authorization
JWT is stateless because its signed
so roles can be put inside of the token and the token only has to be verified (checked signature) to get the roles of the user)
Problems
Opendaylight AAA project for aluminium-SR1 is only supporting authorization header starting with "Basic" and JWT is a Bearer token
So we had to patch the org.opendaylight.aaa:aaa-shiro:0.12.1 bundle with
some backported classes from org.apache.shiro:shiro-core:1.7 package
two modifications on the Authenticator to Accept also Bearer tokens
we realized that an entry in aaa-app-config.xml like
<urls>
<pair-key>/**</pair-key>
<pair-value>authcBasic, roles["admin,provision"]</pair-value>
</urls>
means that the user which wants to access this url pattern needs to have both roles, which does not really make sense. Therefor we also implemented a so called AnyRolesAuthenticationFilter which accepts the connection if one of the given roles matches.
OAuth Provider bundle
API
request | params | response | description |
---|---|---|---|
GET /oauth/providers | OAuthProvider array | list of configured identity providers | |
GET /oauth/redirect | code={}&state={} or session_state={} or token={} | TokenResponse | called by the 301 Response from the identity provider |
POST /oauth/login | username={}&password={} | TokenResponse |
Environment Vars
env | default value | description |
---|---|---|
OAUTH_TOKEN_SECRET | secret | key to sign the token |
OAUTH_TOKEN_ISSUER | ONAP SDNC | |
OAUTH_HOST_URL | null => autodetected | important for reverse proxy use case |
OAUTH_ODLUX_REDIRECT_URI | /odlux/index.html#/oauth?token= | OAuth redirect will be responded |
OAUTH_SUPPORT_ODLUSERS | true | login interface enabled for internal odl configured users |
Dataflow example
for Login with external Identity Provider (KeyCloak)
2:
[{
"id":"keycloak",
"title":"OSNL Keycloak Provider",
"loginUrl":"http://10.20.11.160:8080/auth/realms/onap/protocol/openid-connect/auth?client_id=odlux.app&response_type=code&scope=openid&redirect_uri=http%3A%2F%10.20.11.159%3A8181%2Foauth%2Fredirect%2Fkeycloak"
}]
4:
GET https://oauth-provider/..../...?client_id=abc&response_type=code&redirect_uri=https://sdnc-web
8:
10:
11:
which can be decoded to:
where /real_access/roles are the important ones for us which were configured in the keycloak backend.
Hint: offline_access and uma_authorization are built-in keycloak roles. These ones are filtered by oauth-provider bundle. So delivered role in this case is only provision.
The Opendaylight Roles access problem
As described on top we found out that an entry in aaa-app-config.xml like
results in a restriction for the configured url that the user has to be in both rules. That's why we implement a new Filter AnyRoleHttpAuthenticationFilter
. That means if you enable it for a url you just have to be in at least one of this groups to get access.
So usage changes to:
Configuration
ConfigFile $ODL_HOME/etc/oauth-provider.config.json
key | default | description |
---|---|---|
tokenSecret | randomgeneratedString() | secret to create JWT |
tokenIssuer | "Opendaylight" | issuer for JWT |
publicUrl | autodetect() | url on which odlux webserver is reachable for you. Attention!!!! Be aware behind reverse proxy!! pls set to your reverse proxy url |
redirectUri | "/odlux/index.html#/oauth?token=" | redirect after successful oauth login |
supportOdlUsers | "true" | enable login of internal odl configured users |
Gitlab as a OAuth provider
KeyCloak as a OAuth provider
key | mandatory | description |
---|---|---|
id | yes | identifier for provider-entry ( regex: [ a-zA-Z0-9]+ ) |
type | yes | implementation-type GITLAB | KEYCLOAK | NEXTCLOUD |
url | yes | url of server |
internalUrl | no | url of the oauth provider server to use for internal requests. If not set url is used |
clientId | yes | shared client-id between OAuth provider and Oauth client |
secret | yes | shared secret between OAuth provider and Oauth client |
scope | yes | enabled scopes on oauth-provider side |
title | yes | title shown in odlux GUI |
realmName | if type is KEYCLOAK | realm name set up in keycloak |
trustAll | no | trust all SSL server certificates |
roleMapping | no | HashMap for roles from oauth-provider to odl { "oauth-provider-role":"odl-role" } |