This is used to set the default permissions for all incoming requests regardless of any user information.
Currently it is only possible to allow by O-MI request type with this setting.
This setting is intended for testing the node or, for example, allowing "read" and "cancel" requests when all data in the db is open data.
- Set
allowRequestTypesForAll
in configuration
This is useful for allowing localhost connections to write. It allows fast and easy setup of simple O-MI wrapper scripts on the same server machine.
- Set
input-whitelist-ips
in configuration
This is aimed for quick low security solution or allowing a subnet of trusted computers to write.
- Set
input-whitelist-subnets
in configuration
This can be used to setup external authentication and authorization services (word external means a separate process that can run on the same or other computer). O-MI Node first contacts authentication service and then authorization service, after that it filters the request.
The Authentication and Authorization APIs are quite flexible and are controlled by configuration options in object omi-service.authAPI.v2
. Only fixed format is the last step, which is the response of Authorization service: It must have json object in the body that has two lists of paths, "allow"
and "deny"
. These lists are used to filter the incoming O-DF with following set operations: <O-DF> intersect <allow> difference <deny>
. The filtered O-DF is used in the request instead of the original and the request processing will continue.
The input for authentication service can be passed by several configurable ways (option omi-service.authAPI.v2.parameters.fromRequest
):
- omiEnvelope attribute, for example
<omiEnvelope xmlns="http://www.opengroup.org/xsd/omi/1.0/" version="1.0" ttl="0" token="eyJ0eXAiOiJKV1Q...">
, This is the recommended way to ensure functionality even when using other transport protocols. - The
Authorization
HTTP header - HTTP Cookie
- Other HTTP headers
- Uri query parameters
Continue reading below to know about already existing implementations of these APIs.
These are examples on how to use Auth API v2 of O-MI Node. They might be secure enough for production use, but use with care. Either of them can be replaced by other software by adjusting the configuration approprietly or implementing a wrapper to fix any larger protocol differences.
Start with this to test how the modules work.
Versions used:
- O-MI Node: 1.0.2
- O-MI Authentication: 1.0.0
- O-MI Authorization: 1.0.0
Instructions:
- Install Authentication module
- ldap and nginx installations are optional
- Install Authorization module
- Configure O-MI Node: application.conf
- Configure according to the readmes of the modules
- If testing with localhost: add option
omi-service.input-whitelist-ips=[]
to disable localhost authorization - Optional: In O-MI Node
logback.xml
configuration file, add<logger name="authorization" level="DEBUG"/>
inside configuration element for debugging
- Start O-MI Node, Authentication module and Authorization module
- open authentication module in browser http://localhost:8000/ and press signup
- Create a new user and remember the email that was used
- Log in with your account
- Open About page and copy your token string (carefully, don't copy white space)
- Open O-MI Node webclient http://localhost:8080/html/webclient/index.html
- Create a write request
- Send and check that the result is
Unauthorized
- Leave page open
- Open shell (or http client tool)
- Install httpie (or the http client of your choice)
sudo apt-get install httpie
- Add your email address as username
http POST :8001/v1/add-user username=your@test.email
- Add allow write rule to your user (automatically created group)
http POST :8001/v1/set-permissions group=your@user.email_USERGROUP permissions:='[{"path":"Objects","request":"wcd","allow":true}]'
- Install httpie (or the http client of your choice)
- Go back to O-MI Node webclient and send again. You should see returnCode=200.
By default, O-MI Node allows anyone to make any read requests. If some parts of O-DF should be hidden, follow these instructions.
- Make sure that you have basic installation done as described above.
- In application.conf of O-MI Node:
- Set
omi-service.allowRequestTypesForAll = []
- For anonymous users to get the default permissions from O-MI-Authorization:
# to skip authentication when token is not found omi-service.authAPI.v2.parameters.skipAuthenticationOnEmpty = ["token"] # to set username to empty string when that happens omi-service.authAPI.v2.parameters.initial.username = ""
- Set
- Set some default permissions (change this to fit your needs):
http POST :8001/v1/set-permissions group=DEFAULT permissions:='[{"path":"Objects","request":"rc","allow":true},{"path":"Objects/private","request":"rc","allow":false]'
Versions used:
- O-MI Node: 1.0.2
- O-MI Authentication: 1.0.0
- O-MI Authorization: 1.0.0
- nginx: 1.14.0 (Prior to version 1.11.6, $ssl_client_s_dn_legacy was $ssl_client_s_dn.)
Instructions:
- Install Authorization module
- Install nginx
- Configure O-MI Node: application.conf
omi-service.authAPI.v2 { enable = true authentication.url = "" authorization.url = "http://localhost:8001/v1/get-permissions" parameters.initial { username = "" # to send empty username if username is not given by nginx } parameters.fromRequest { headers { "X-CLIENT-SSL-USER" = "username" } } parameters.toAuthorization { jsonbody { username = "username" request = "requestTypeChar" } } }
- Create a CA certificate and a client key and sign it using your preferred tools. (openssl)
- Configure nginx
- put this outside server block to extract CN for the username (remove "_legacy" if using older than v1.11.6) and support websockets
map $ssl_client_s_dn_legacy $ssl_client_s_dn_cn { default ""; ~/CN=(?<CN>[^/]+) $CN; } # and websocket support map $http_upgrade $connection_upgrade { default upgrade; '' close; }
- setup SSL and the route to O-MI Node
server { listen 443 ssl; server_name localhost; # Server SSL ssl_certificate server.crt; ssl_certificate_key server.key; # Client SSL ssl_client_certificate ca.crt; ssl_verify_client optional; # or `on` if you require client key location / { # client certificate verification: SUCCESS, FAILED[:reason] or NONE if ($ssl_client_verify ~ "FAILED.*") { return 403; # Reject the whole request } # username derived from CN and serial proxy_set_header X-CLIENT-SSL-USER "${ssl_client_s_dn_cn}#${ssl_client_serial}"; # The usual proxy settings proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://localhost:8080; # websocket proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; } }
- put this outside server block to extract CN for the username (remove "_legacy" if using older than v1.11.6) and support websockets
- (re)Start o-mi-node, o-mi-authorization and nginx
If you are using the authentication plugins of Kong you can use the upstream headers set by the plugin(s). For example, there is "X-Consumer-ID" or "X-Credential-Username". Now in O-MI Node you only need a quite usual authz configuration like this:
omi-service.authAPI.v2 {
enable = true
authentication.url = "" # skip; already done at this point
authorization.url = "http://localhost:8001/v1/get-permissions" # fill this as usual
parameters {
fromRequest.headers {
X-Consumer-ID = "username" # select header to use for "username" in Authorization module
}
toAuthorization.jsonbody { # as usual
username = "username"
request = "requestTypeChar"
}
}
}