OAuth Provider Implementation

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

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

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

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

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"

}