Skip to main content

Configure a Protected Resource

The RSA's purpose is to protect and manage resources (an API/endpoint at the federated OIDC provider). The RSA can automatically protect and share any resources that the user's access token at the Federated OIDC Providers is valid for. The simplest example would be the 'userinfo' endpoint (https://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse). A configuration allowing the 'userinfo' endpoint at the Federated OIDC Providers to be protected and shared through UMA is shown below.

For this we must provide some static and database configuration details.

Zuul Configuration

The Zuul configuration enables requests at the RSA to be re-routed to appropriate endpoints at a given protected Resource Server (The Federated OIDC Provider). Pre-configured routes must be supplied to allow dynamic re-routing. The example below essentially states that all requests arriving at "https://{rsa-url}/api/ must be routed off to https://{example-hosted-api-host-and-path}/ where the wild card "**" is the only part of the initial request that's carried over and appended to the protected Resource Server's "url" (corresponds to "zuul.routes.url" below). For example, if a request "https://{rsa-base-url}/api/userinfo" is made at the AS, it would be re-routed to "https://{example-hosted-api-host-and-path}/userinfo.

zuul:
debug:
request: true
routes:
userinfo:
path: /api/**
url: https://{example-hosted-api-host-and-path}
sensitiveHeaders: Cookie,Set-Cookie
stripPrefix: true
NOTE

Notice in the sample configuration provided here how the federated_issuer (within the OIDC provider config) and the URL supplied within Zuul configuration are not the exact same. The federated_issuer value is the OIDC issuer value of the federated provider whereas the url supplied in the zuul configuration is the part of the path where the access token (generated by the Federated Provider and received by the RSA) is to be used to get the resource for the service provider.

Sensitive Headers

You can share headers between RSA and the Federated Provider. However, you may not want sensitive headers leaking downstream into the Federated Provider. By default, Zuul will send all headers to the proxied path. Depending on your Federated Provider's security policy/deployment configuration (ingress controller settings, etc.), proxy headers (sent as part of a Zuul forwarded request) may lead to unexpected results. 401 errors can occur even if the request made to the Federated Provider is accompanied with an appropriate and valid access token. You can specify a list of ignored headers as part of the route configuration using zuul.routes.{route-name}.sensitiveHeaders.

Consider adding 'x-forwarded-host' to zuul.routes.{route-name}.sensitveHeaders and re-deploy the RSA if such errors occur. The sensitive headers can be configured as a comma-separated list per route, as shown in the above snippet.

For more information and fine-grained control of the Zuul Proxy mechanism in Spring Boot, refer to https://cloud.spring.io/spring-cloud-netflix/multi/multi__router_and_filter_zuul.html and modify the Zuul configuration snippet within the RSA yaml configuration accordingly.

Database Configuration

Next, an entry must be made to the protected_http_path table. This entry will represent the path at which the SP will use to request the resource with the access token granted by the Authorization Server mentioned above.

INSERT INTO protected_http_path (id, version, date_created, last_updated, path, auth_server) 
VALUES (1, 1, now(), now(), "/api/{path-to-be-appended-at-real-api}"}, 2);

Note how the path begins with "/api" which corresponds to the prefix supplied in the Zuul config above (zuul.routes.userinfo.path). The Authorization Server reference must correspond to the id in the oauth_provider table that represents the Authorization Server.

Next, an entry must be made to the resource table which represents a resource registered at a given Authorization Server.

INSERT INTO resource (id, version,date_created, last_updated, name, resource_id, type, auth_server)
VALUES (1, 1, now(), now(), "example-resource", "example-resource-id", "https://openid.net/specs/openid-connect-core-1_0.html", 2);

The 'name' can be a generic user friendly name. However, the 'resource_id' above must be the same as it is in the Authorization Server DB. The type above is listed as an "openid" type. The Authorization Server reference must correspond to the id in the oauth_provider table that represents the Authorization Server.

Next, an entry must be made to the protected_resource_path_mapping table. This entry links a protected_path to a resource registered at a given Authorization Server.

INSERT INTO protected_resource_path_mapping (id,version, date_created, last_updated, method, path_id, resource_id) 
VALUES (1, 1, now(), now(), "GET", 1, 1);

The path_id and resource_id must correspond to the id of the appropriate entry within the protected_http_path and resource tables respectively. The value for method must correspond to the HTTP method expected to be used against the Federated Provider to fetch the resource and must be capitalized as displayed above.

Lastly, an entry must be made to the protected_resource_path_mapping_scopes table. This entry would represent the scopes the Service Provider is required to have been granted access to by the RQP, in order to access a protected path of the RSA.

INSERT INTO protected_resource_path_mapping_scopes (path_mapping, scope) 
VALUES (1, "example-scope");

A path can have have multiple scopes granted to it. The 'path_mapping' above must correspond to the id at the protected_resource_path_mapping table.