Any endpoint can have limited access by checking SAF resource of the logged user. This feature is implemented in module
apiml-security-common
. Therefore, it can be used in each application with this dependency.
Verification of SAF resource can be provided via three providers:
- the highest priority: REST endpoint call (ZSS or similar)
- native
- the lowest priority: dummy implementation (defined in a file)
note: The first available based on priority will be used.
You can also select one specific provider via the parameter apiml.security.authorization.provider
. Use this value parameter to
strictly define a provider. You use values: endpoint
, native
or dummy
.
When apiml.security.authorization.provider
is not set or set to empty value, provider will be selected automatically.
note: When the endpoint provider is explicitly set attribute apiml.security.authorization.endpoint.enabled
is ignored.
This provider is one way how to enable the feature outside the mainframe (ie. running in Docker).
- Method:
GET
- URL:
{base path}/{userId}/{class}/{entity}/{level}
- Response:
{
"authorized": "{true|false}",
"error": "{true|false}",
"message": "{message}"
}
note: See also ZSS implementation https://github.com/zowe/zss/blob/master/c/authService.c
apiml.security.authorization.endpoint.enabled
true
orfalse
,false
as default- to enable provider via an endpoint
apiml.security.authorization.endpoint.url
- base path of endpoint's URL (
{base path}/{userId}/{class}/{entity}/{level}
) - as default
http://localhost:8542/saf-auth
(default location of ZSS endpoint)
This provider is the easiest way to use the feature on the mainframe.
Enable when classes com.ibm.os390.security.PlatformAccessControl
and com.ibm.os390.security.PlatformReturned
are available on classpath. It uses method
, so
for correct usage, the definition of method
must be also matching.
This provider is for testing purposes off the mainframe.
You can create file saf.yml
and locate it in the folder, where is application running or create file mock-saf.yml
in the
test module (root folder). The highest priority is to read file outside the JAR. A file (inner or outside) has to exist.
Structure of the YML file:
safAccess:
{CLASS}:
{RESOURCE}:
- {UserID}
notes:
- Classes and resources are mapped into a map, user IDs into a list.
- Load method does not support formatting with dots, like {CLASS}.{RESOURCE}, each element has to be separated.
- Field
safAccess
is not required to define empty file (without any definition). - Classes and resources cannot be defined without user ID list.
- When a user has multiple definitions of same the class and resource, just the most privileged access level is loaded.
The REST API endpoints can be protected by the org.springframework.security.access.prepost.PreAuthorize
annotation.
The module apiml-security-common
defines two new security expressions:
boolean hasSafResourceAccess(String resourceClass, String resourceName, String accessLevel)
- returnstrue
when user has access to the resourceboolean hasSafServiceResourceAccess(String resourceNameSuffix, String accessLevel)
- similar as the previous one but the resource class and resource name prefix is taken from the service configuration under keysapiml.security.authorization.resourceClass
andapiml.security.authorization.resourceNamePrefix
.
So you can do following:
@GetMapping("/safProtectedResource")
@PreAuthorize("hasSafResourceAccess('FACILITY', 'BPX.SERVER', 'UPDATE')")
public Map<String, String> safProtectedResource(@ApiIgnore Authentication authentication) { /*...*/ }
@GetMapping("/anotherSafProtectedResource")
@PreAuthorize("hasSafServiceResourceAccess('RESOURCE', 'READ')")
public Map<String, String> anotherSafProtectedResource(@ApiIgnore Authentication authentication) { /*...*/ }
The second @PreAuthorize
expression hasSafServiceResourceAccess('RESOURCE', 'READ')
is effectively translated to hasSafResourceAccess('${apiml.security.authorization.resourceClass}', '${apiml.security.authorization.resourceNamePrefix}RESOURCE', 'READ')
. In case of default values it would be hasSafResourceAccess('ZOWE', 'APIML.RESOURCE', 'READ')
.
Default value of apiml.security.authorization.resourceClass
is ZOWE
.
Default value of apiml.security.authorization.resourceNamePrefix
is APIML.
.