KrakenD Config custom dynamic role based on URL - keycloak

I want to add one URL configuration which would be dynamic. For eg.
URL: /api/v1/{did}
and my jwt token would contain user-id, roles where role = did (same as in URL).
There are various URL like this with different did but same endpoint and krakend should validate that one user has access to that specific URL(did), so I have roles created in keycloak as did (roles = did).
I want to specify roles in krakend json file like roles : [{did}].
Is there any way to achieve this?

That should be possible using a CEL rule (Common Expression Language). With CEL you can set an expression that makes sure that the passed {did} parameter equals to the content of the JWT attribute containing the role.
The following page has several examples that might help you: https://www.krakend.io/docs/endpoints/common-expression-language-cel/
For the testing I would suggest using the devopsfaith/krakend:watch command that hots reload the configuration on every change.

Related

How to search keycloak users by employeeNumber or by custom attributes?

I wanted to search keycloak user using employeeNumber. I tried checking keycloak documentation but didn't find any API which will search based on employeeNumber/custom attributes. I m using below API to search the users with admin access.
http://localhost:8080/auth/admin/realms/Demo-Realm/users/?firstName=akshay
also tried with
http://localhost:8080/auth/admin/realms/Demo-Realm/users/?search=akshay
Although not mentioned on the release notes it is possible after Keycloak version 15.1.0 (as pointed out by #Darko) to search users by custom attributes, introduced with this commit. As one can now see on the GET /{realm}/users endpoint of the Keycloak Admin Rest API:
So in your case you would call that endpoint with the query parameter q=employeeNumber, for instances with curl:
curl 'https://${KEYCLOAL_HOST}/auth/admin/realms/${REALM_NAME}/users?q=employeeNumber:444555'
Bear in mind that the /auth path was removed starting with Keycloak 17 Quarkus distribution. So you might need to remove the /auth, namely:
curl 'https://${KEYCLOAL_HOST}/admin/realms/${REALM_NAME}/users?q=employeeNumber:444555'
Keycloak version before 15.1.0
For those with Keycloak version before 15.1.0, out-of-the-box you can use the Keycloak Admin API endpoint:
GET /{realm}/users
one can read that :
Get users Returns a list of users, filtered according to query
parameters
those (optional) query parameters being:
briefRepresentation (boolean);
email (string);
first (string);
firstName (string);
lastName (string);
max (Maximum results size (defaults to 100)) (integer);
search (A String contained in username, first or last name, or email);
username (string).
As you can see you cannot search for custom attributes. A not so great solution is to get all the users (max=-1), and filter afterwards by the custom attribute.
The other option is to extend Keycloak functionality by adding your own custom Service Provider Interfaces (SPI) and adding your custom endpoint. There you can take advantage of the searchForUserByUserAttribute method from the UserQueryProvider interface.

What URL should be used to create/Modify OIM user via REST API SCIM for UDF?

I am trying to create and modify users using SCIM/REST API's available OOTB in 11gR2PS3.
I am able to create/modify users for all the OOTB attributes specfied in the document
As per the documentation, these API's are supported for custom UDFs as well.
Does anyone know what the schema attributes name and format that needs to be passed in the content body for custom UDF's?
As per the documentation
Note: You can use user defined fields (UDFs) in SCIM requests. After
UDFs are created in Oracle Identity Manager, they automatically appear
in SCIM resources as regular attributes. There is no difference in the
requests and responses with regular attributes.
when we crate the user even after specifying the UDF value its not going in OIM DB and it also doesn't throw any exception.
call /Schemasoperation using get method
using your OIM URL :http://<host>:<port>/idaas/im/scim/v1/Schemas
Use the returned schema while using create, update operation on the UDF.
e.g. schema returned is urn:ietf:params:scim:schemas:extension:oracle:2.0:OIG:User
then qualify UDF with the returned schema while calling Create/Update operation.
"urn:ietf:params:scim:schemas:extension:oracle:2.0:OIG:User":{
UDFNAME : UDFVALUE
}
also incluede the schema in the schemas[] if its not there already.

REST and showing URIs that need user input

I have a REST Service that works with Models. So once a user has navigated to a model I allow two endpoints /ModelRootItems and also /Item.
The /Item endpoint requires an ID of an item within the model eg: /Item/1234.
When a user gets to a model I return the following URIs:
/Model/My_Model/ModelRootItems
/Model/My_Model/Item/{ItemID}
But I feel that I should not expose the /Item URI as it is not complete without an ID. Users are able to see that the /Item endpoint exists via my help page.
So is it right/wrong to show this endpoint in the list of URIs?
I don't think there are right/wrong choices in this case. However, I'd suggest you use
/Model/My_Model/Items
(notice the plural form Items) to return a list containing all the items of that Model and
/Model/My_Model/Items/{ItemID}
to return the single Item referenced by the ID.
Please note that this is just a convention, as I already said, there is no right/wrong choice in this case, especially if you use REST's HATEOAS principle with opaque URIs.

REST API logged in user can access data (parse.com)

I'm using the parse REST API.
I need to setup so that for any requests made:
1) only logged in/authenticated users can Read or Write.
2) users can only access/modify records they own.
My current implementation:
1) using the Application key + REST API key.
2) sending request to user login endpoint, on success returning the user data including the session token
for 2), I'm not doing anything with the session token yet.
I understand that parse has:
1) class based permissions
2) object-level permissions (ACL's)
With Read and Write access on the class level, and by simply using the Application Key + REST API Keys,
anyone with these two keys can access that class (ofcourse, the Master Key has even more "power").
I want to simply say that they can Read and Write on the class level, if they're logged in/authenticated.
And when they Read, Update or Delete, they can only do so if they're owner of the object.
I assume that session token will play a role in the logged in part, and ownership is defined by object-level ACL
Is this correct and how to roughly set this scenario up in parse?
It's not clear to me in the REST API how to handle this (what I think is a common) type of scenario.
Thanks for any feedback
{"ACL":{"$CURRENT_USER":{"read":true,"write":true}}}
above in acl column will mean at the security level, only the creator has RW permissions. No other user can see these records with this ACL attr value regardless of their access on the CLASS level.
OR
you control the accessor predicates in your app. So you can add a column = 'createdBY' of type pointer_to_class_User.
Any queries just contain predicate ..
'where={"createdBy":{"__type":"Pointer","className":"User","objectId":"$CURRENT_USER"}}'
which enforces ( outside row security level ) idea of only getting result sets containing rows for the current-user.
all depends on how you want to use the security layer.
I would do it using the predicates and resort to the ACL only where you may have stuff like SSN's or Salary where as a policy you dont what general read permissions.

What is the best way to design REST URI for nested resources

Say there are users having multiple authorizations having multiple permissions.
Retrieving all authorizations for the specified user (without permissions) could be:
GET users/{id}/authorizations
The "normal" case is to not embed permissions with authorizations for performance reason.
There are cases when authorizations must be returned with their respective permissions for that user.
Suggested solutions are:
GET users/{id}/authorizations/permissions // does not seem clear
GET users/{id}/authorizations?permissions=true // with query string
GET users/{id}/authorizationswithpermissions // new resource
Now what is the best way to design the REST URI in that case?
Your ideas
There are cases when authorizations must be returned with their respective permissions for that user.
GET users/{id}/authorizations/permissions
It is not a good idea to nest collection resource like this. Does it mean "give me all permissions of all authorizations of user id"? This is unclear. Don't do this.
GET users/{id}/authorizations?permissions=true
A query is normally used to query, search, or filter on a collection resource. This URL woud return all authorizations for user id for which permissions is true. But what does that man? This is unclear. Don't do this.
GET users/{id}/authorizationswithpermissions
Authorizations are authorizations. Their representation should not depend on the URI. Don't do this.
Content Negotiation
The solution to your problem is to use content negotiation. You only use one URL:
GET users/{id}/authorizations
This means: Give me a list of all authorizations of user id.
Now if you want to get this list without permissions, you could use the HTTP header
Accepts: application/vnd.mycompany.authorizations+xml
Let's digest this.
application: the first part of the normal MIME type application/xml
vnd: a prefix to define your own type
mycompany.authorizations: your type
xml: the second part of application/xml
Now if you want to get this list with permissions, you could use the HTTP header
Accepts: application/vnd.mycompany.authorizations.permissions+xml
Note that me now use vnd.mycompany.authorizations.permissions. The server should return the authorizatons including the permissions. Only the representations are different, not the resources.
Personnally I can't find any problem with both two last suggestions:
GET users/{id}/authorizations?permissions=true // with query string
GET users/{id}/authorizationswithpermissions // new resource
Except I would change them as follow to be more relevant:
GET users/{id}/authorizations?withPermissions=true // with query string
GET users/{id}/authorizationsANDpermissions // new resource
The first one seems to be quite confusing but your RESTful entities should be documented whatever notation you will opt for.