I am trying to add a user condition under Security Realms -> myrealm -> Roles and Policies -> Global Roles -> Roles -> Test role -> View role conditions. There I clicked on "Add condition" button, then choose user in Predicate List and enter the user name in User Argument Name and save it.
I did tried cmo.getSecurityConfiguration().getDefaultRealm().lookupRoleMapper("XACMLRoleMapper") from Oracle support, but i am not sure how do i achieve this using wlst.
Could you help me out with this.
As i understand,By using below WLST script it will help you to create users, groups and let you know how to add users to an existing role. 1
connect(‘weblogic’,’weblogic’,’t3://localhost:7001′)
edit()
startEdit(-1,-1,’false’)
serverConfig()
cd(‘/SecurityConfiguration/First_Domain/Realms/myrealm/AuthenticationProviders/DefaultAuthenticator’)
cmo.createUser(‘faisal’,’weblogic’,”)
cmo.groupExists(‘TestGrp’)
cmo.createGroup(‘TestGrp’,”)
cmo.addMemberToGroup(‘testgrp’,’faisal’)
cd(‘/SecurityConfiguration/First_Domain/Realms/myrealm/RoleMappers/XACMLRoleMapper’)
cmo.setRoleExpression(”,’Admin’,’Grp(TestGrp)|Grp(Administrators)’)
edit()
undo(defaultAnswer=’y’, unactivatedChanges=’true’)
stopEdit(‘y’)
Related
Question is more advanced than usual.
Imagine you have three users groups in Keycloak: Group_Basic, Group_Client_A, Group_Client_B.
You add two different LDAP user federation setting for "Client A" and "Client B".
You make Group_Basic as your default group.
How to automatically assign Group_Client_A to LDAP users from "Client A", and Group_Client_B group to LDAP users from "Client B" ?
Any ideas are welcome! Thanks!
Basically #Vadim pointed to right thing:
Under created LDAP -> Mappers -> Create ->
Mapper type: hadrcoded-ldap-group-mapper
Group: /Group_Client_A
Did synced user, got default Group_Basic group + hardcoded Group_Client_A.
I assume pointing to different group under different LDAP synchronisation will got another group assigned.
Thanks!
In my rest service i can obtain the principal information after authentication using
KeycloakPrincipal kcPrincipal = (KeycloakPrincipal) servletRequest.getUserPrincipal();
statement.
Keycloak principal doesn't contain all the information i need about the authenticated user.
Is it possible to customize my own principal type?
On the keycloak-server-end I've developed a user federation provider. I saw that UserModel makes possible to add a set of custom attributes to my user.
Is it possible to insert my custom principal in that code?
Is it possible to retrieve this attributes from keycloak principal?
What is the way?
To add custom attributes you need to do three things:
Add attributes to admin console
Add claim mapping
Access claims
The first one is explained pretty good here: https://www.keycloak.org/docs/latest/server_admin/index.html#user-attributes
Add claim mapping:
Open the admin console of your realm.
Go to Clients and open your client
This only works for Settings > Access Type confidential or public (not bearer-only)
Go to Mappers
Create a mapping from your attribute to json
Check "Add to ID token"
Access claims:
final Principal userPrincipal = httpRequest.getUserPrincipal();
if (userPrincipal instanceof KeycloakPrincipal) {
KeycloakPrincipal<KeycloakSecurityContext> kp = (KeycloakPrincipal<KeycloakSecurityContext>) userPrincipal;
IDToken token = kp.getKeycloakSecurityContext().getIdToken();
Map<String, Object> otherClaims = token.getOtherClaims();
if (otherClaims.containsKey("YOUR_CLAIM_KEY")) {
yourClaim = String.valueOf(otherClaims.get("YOUR_CLAIM_KEY"));
}
} else {
throw new RuntimeException(...);
}
I used this for a custom attribute I added with a custom theme.
Select Users > Lookup > click on ID > go to attributes tab > Add attribute > e.g.: phone > Save
Select Clients > click on Client ID > go to Mappers Tab > create mapper
Get custom attributes
UPDATE
Add 'phone' attribute on Group level, assign user to that group, and you get 'phone' attribute from group level for all users
Go back to mapper and update 'phone' with 'Aggregate attribute values = true' and 'Multivalued=true', and you get 'phone' as list with both attributes from group and user level. If you keep 'Aggregate attribute values = false' or 'Multivalued=false', you get just one value, where 'phone' attribute from user will override 'phone' attribute from group (which make sense)
For Keycloak > 18 the configuration of the mappers has moved in the UI:
Inside Clients > Your selected client under the tab Client Scopes, one has to select account-dedicated:
There custom mappers can be added:
We are having a portlet on a liferay page. We want to put up up a permission on every action method that is performed. For example on page A we have landed an XYZ portlet. Now we want that whenever there is any action performed form this portlet, we want to check that if the user is having a role to perform this action or not.
It wont be a good approach to put up the code in Action method of the portlet cause we are having approximately 20 such pages and portlets.
Can we have some sort of filter or so, so that each action request is checked if the user is having the access to the content or not.
Thank you...
My idea.
Use a filter to intercept all request
You can add a filter to the Liferay Servlet to check every request.
For that you can use a hook-plugin.
Look at this :
http://www.liferay.com/fr/documentation/liferay-portal/6.1/development/-/ai/other-hooks
http://connect-sam.com/2012/06/creating-servlet-filter-hook-in-liferay-6-1-to-restrict-access-based-on-ip-location/
Issue with filter is that you can't access ThemeDisplay or use PortalUtil.getUser(request).
So you must use work around like that :
private User _getUser(HttpServletRequest request) throws Exception {
HttpSession session = request.getSession();
User user = PortalUtil.getUser(request);
if (user != null) {
return user;
}
String userIdString = (String) session.getAttribute("j_username");
String password = (String) session.getAttribute("j_password");
if ((userIdString != null) && (password != null)) {
long userId = GetterUtil.getLong(userIdString);
user = UserLocalServiceUtil.getUser(userId);
}
return user;
}
Filtering the request
To filter the request you must get :
page id (Layout id in Liferay)
portlet id
portlet lifecycle
One more time using a filter is a pain because you can get the ThemeDisplay. These params are easy to get (with real object instancee) with ThemeDisplay.
So you must get this as parameter in the request.
final String portletId = ParamUtil.get((HttpServletRequest) servletRequest, "p_p_id", "");
final String layoutId = ParamUtil.get((HttpServletRequest) servletRequest, "plid", "");
final String portletLifecycle = ParamUtil.get((HttpServletRequest) servletRequest, "p_p_lifecycle", "");
Lifecycle details :
portletLifecycle is a int and the meaning of value is :
0 : RENDER
1 : ACTION (the one that interests you)
2 : RESOURCE
I think that with this data you can be able to define if user can or cannot make the action.
You can get user roles from the user.
You can get the current page and portlet linked to the request.
And you can know if the request is an action request.
Good luck with Liferay.
You can add freely configurable permissions to Liferay, see the Developer Guide for detailed information. My first guess on this would be that these affect "model resources", e.g. the data that your portlet is dealing with, rather than portlet-resources, e.g. permissions on the individual portlet itself. Think of portlet-permissions as permissions that are defined by Liferay, model-resources as permissions where you can come up with your own vocabulary on the actions, e.g. "UPDATE_ADDRESS" etc.
These permissions will typically be tied to roles, which are granted to users/usergroups/etc.
Based on this variability, it depends on the nature of your permissions if you can write a filter to generically check permissions, or if it depends on more than the individual action call.
If you determine that there is a generic solution, look up PortletFilters, they behave just like ServletFilters. These can easily provide a home for permission checks.
It's quite hard to cover this topic in such a short answer, I hope to have given enough resources for you to continue your quest.
You can abuse some existing portlet permission like "Add to Page" and set it to roles that should call the action.
And by the rendering and action phases validate "has the user necessary permission".
Or you can create new permission and configure it by portlet-configuration. This way is cleaner, but difficulty.
According to a requirement, i have to change the owner of an account if the user does not have read access to a third object.
I need a functionality similar to the isAccessible() method of Describe Field Result, but it is only available for the current logged in user.
Is there any other way to check the user's CRUD permissions for an object in Apex code?
I wrote an article about this on my blog. There is a feature that was just released in version 24.0 of the API (Spring Release) that will let you do just this on a record by record basis for the current user.
Here is the link to that blog entry that goes into details: How to tell if a user has access to a record
Don't confuse record level access with CRUD - the latter is the ability for a user to Create, Read, Update or Delete an object in general, regardless of sharing rules etc. that might affect the user's access to a particular record.
To check whether a user can create (e.g. Contacts) in general, just use
Schema.sObjectType.Contact.isCreateable()
(returns true or false)
From the documentation. it sounds like you want to use execute anonymously.
Apex generally runs in system context; that is, the current user's permissions, field-level security, and sharing rules aren’t taken into account during code execution. The only exceptions to this rule are Apex code that is executed with the executeAnonymous call. executeAnonymous always executes using the full permissions of the current user. For more information on executeAnonymous, see Anonymous Blocks.
Although Apex doesn't enforce object-level and field-level permissions by default, you can enforce these permissions in your code by explicitly calling the sObject describe result methods (of Schema.DescribeSObjectResult) and the field describe result methods (of Schema.DescribeFieldResult) that check the current user's access permission levels. In this way, you can verify if the current user has the necessary permissions, and only if he or she has sufficient permissions, you can then perform a specific DML operation or a query.
For example, you can call the isAccessible, isCreateable, or isUpdateable methods of Schema.DescribeSObjectResult to verify whether the current user has read, create, or update access to an sObject, respectively. Similarly, Schema.DescribeFieldResult exposes these access control methods that you can call to check the current user's read, create, or update access for a field. In addition, you can call the isDeletable method provided by Schema.DescribeSObjectResult to check if the current user has permission to delete a specific sObject.
http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content/apex_classes_perms_enforcing.htm#kanchor431
Have you tried the runAs() method?
Something like (not verified):
User u = [SELECT Id FROM User WHERE Name='John Doe'];
System.runAs(u) {
if (Schema.sObjectType.Contact.fields.Email.isAccessible()) {
// do something
}
}
The DescribeSObjectResult class has methods for checking CRUD.
E.g. this allows you to test whether or not the current user can update the account object in general.
Schema.DescribeSObjectResult drSObj = Schema.sObjectType.Account;
Boolean thisUserMayUpdate = drSObj.isUpdateable();
#John De Santiago: your article covers record level access rather than object CRUD (= object level access)
Very old post. Since then SF add option to query object permission:
Select SobjectType ,ParentId, PermissionsEdit, PermissionsRead
From ObjectPermissions
Order by ParentID, SobjectType ASC
Basically you will need to get the profile and permissionset of the user that you want to check and the relevant object. So it will be something like:
Select SobjectType ,ParentId, PermissionsEdit, PermissionsRead
From ObjectPermissions
where parentId IN :UserProfileIdAndPermission
AND sObjectType=:objectType
Order by ParentID, SobjectType ASC
How to model restrictions on data visible on resources? Different people are accessing the same resources but with different roles so they are not allowed to see all the information.
The case I am working on:
Solution without access restriction on information:
User:
name
phoneNumber
If anyone could access it this would be easy to model as:
GET /User -> [{name:"John", phoneNumber: "322-333"}]
GET /User/{id} -> {name:"John", phoneNumber: "322-333"}
However, say I have two roles, admin and user. The phoneNumber must only be visible to users who are also admins. Authorization token is transmitted in a cookie, header or similar. The server will know which roles a requester has. How would one design an API to handle this? I have a couple of ideas:
1) The naive solution would be to just filter it and leave the fields unset if you arent allowed to access it ie.
If user: GET /User -> [{name:"John"}]
If admin: GET /User -> [{name:"John", phoneNumber: "322-333"}]
2) Embed the role in the url:
If user is wanted as a User: GET /User/User -> [{name:"John"}]
If user is wanted as an Admin: GET /Admin/User -> [{name:"John", phoneNumber: "322-333"}]
3) Define a new resource for each possible subset of fields:
If user is wanted as a User: GET /PublicUserInfo -> [{name:"John"}]
If user is wanted as an Admin: GET /FullUserInfo -> [{name:"John", phoneNumber: "322-333"}]
Would a different approach be better ?
Does anyone have experience with a solution that worked out in practice?
Use option 1 based on the authenticated user. If you opt for 2 or 3 clients implementing your API have to worry about twice as any API endpoints and when they should be used.