Expand my Community achievements bar.

SOLVED

Role based authorization after SAML Authentication

Avatar

Level 2

Hi,

 

I have a requirement to add role based authorization for some secure pages. I want to set a property for pages called "Security Groups". This property will contain group names which shall have access to that page. I have configured SAML authn handler with Okta IDP . After login when SAML response is submitted to AEM ACS url , viz - /content/****/saml_login ,  I want to read the "Security Groups" from page property and groups of loggedin user from SAML response , and if there is a match between page property value and SAML response groups attribute , then allow user to view the page , if not then redirect user to error page. 

 

User data is maintained in active directory and Okta provides those details, so I don't want to recreate those groups in AEM, just want to do the authorization on the go. I want to set the groups coming from Okta into user session , and on every page request , match Security groups property of page with groups in session.

 

Request you to let me know how to implement this.

 

Thanks!

1 Accepted Solution

Avatar

Correct answer by
Employee Advisor

I want to point out that the code presented here (and marked as correct answer) is not "security". It prevents you just from accessing that page directly (with a direct request), but it does not prevent other pages from including it.

 

For example, if you secured the pages below /content/brand/securepages with the approach described, they can be accessed by using the /content/brand.2.json; content in there can be referenced directly (using reference component), etc. If you really want proper authorization for this content, you need to use ACLs on the content level, as they are always enforced, no matter at what level you want to access that content.

View solution in original post

9 Replies

Avatar

Level 4

You can use a sling servlet filter where each request first comes to this before actually dispatching the AEM page.
https://sling.apache.org/documentation/the-sling-engine/filters.html

 

1. Get current user details using UserManager:

ex: final UserManager userManager = request.getResourceResolver().adaptTo(UserManager.class);


2. Get the current URL from the request & check if the group "Security Groups" present in page properties or not using the page manager API.

 

3. If true => validate the current user is in the list of "Security Groups" and if yes, store it in boolean flag isValidRequest.

 

4. if isValidRequest true => filterChain.doFilter -> return normal AEM page with response 200


5. if false: return 404

 

ex:

if(runModes.contains("author")) {
if (isValidRequest) {
filterChain.doFilter(request, response);
} else {
return404Response();
return;
}
}

Avatar

Level 2

Thanks for your comments. I have written Servlet filter code in which I am able to get page properties , including security groups. But before that I need to check if the page is secured or not. I am not able to get "cq:authenticationRequired" or "jcr:mixinTypes" in filter code. These are set when we check 'Enable Authentication' checkbox in Advanced page properties. In CRX DE , I dont see "cq:authenticationRequired" in jcr:content node properties, I do see "jcr:mixinTypes" as property of page node.

Any hints on why these properties are not available in filter? Or if there is any other way of knowing if page requires Authentication

 

Below is my code .

PageManager pageManager = resourceResolver.adaptTo(PageManager.class);

Page page = pageManager.getContainingPage(resource.getPath());

for(Entry<String, Object> e : page.getProperties().entrySet()) {

String key = e.getKey();

Object value = e.getValue();

log.info("Key : {} . Value : {} ",key, value.toString() );

}

Check property "cq:propertyInheritanceCancelled" to get the value of "cq:authenticationRequired" if you have cancelled inheritance for individual pages. Both "jcr:mixinTypes" & "cq:propertyInheritanceCancelled" are String [] property , you can give to try to read it as a ValueMap pageProperties = currentPage.getProperties(); String[] mixinTypes = pageProperties.get("jcr:mixinTypes", String[].class)

Avatar

Employee Advisor

AEM can do that for you:

 

* Create a group on Okta side, which members should be able to perform this action

* Make sure that this group is synchronized to AEM (login with a user of that group and check that this group is synchronized to AEM).

* Adjust the permissions assigned to this group in the way you require.

 

This is straight forward way and doesn't require any coding.

Avatar

Level 2
Thanks for your response . Actually the groups are not fixed . New groups keep getting created for different campaigns , so I need to build it in a way so that I can assign any group to a page and during login Okta will tell me whether the user is part of that group. Following the filter approach suggested by sanketk90166544

Avatar

Level 4

Recently i did this, you can achieve this using the roles you are getting from okta.

Once a user logged in to AEM will be assigned that role coming from okta and in aem u need to assign specific permission to that group.

Avatar

Correct answer by
Employee Advisor

I want to point out that the code presented here (and marked as correct answer) is not "security". It prevents you just from accessing that page directly (with a direct request), but it does not prevent other pages from including it.

 

For example, if you secured the pages below /content/brand/securepages with the approach described, they can be accessed by using the /content/brand.2.json; content in there can be referenced directly (using reference component), etc. If you really want proper authorization for this content, you need to use ACLs on the content level, as they are always enforced, no matter at what level you want to access that content.

Avatar

Level 2

Hi,

Thanks for pointing this out. As I mentioned earlier I dont have fixed groups which I can preset in AEM. Groups keep getting created & deleted in Active Directory. The filter I have written works fine for ".html" but was allowing access to page json as you mentioned, so I changed the filter to run on ".json" also and that prevents access to page json also. Is this approach fine ? Will the filter cause any performance issue since it will evaluate all html & json requests ?

Thanks!

Avatar

Employee Advisor
You cannot achieve security on a repository level with your approach. For example search results will show results from that area, even it is protected from directly accessing it. Code using "my" session can access it as well. The problem is the application design, which does not take security into account. You need to setup groups and assign proper permissions to them. What you can do is to predefine a set of groups, assign ACLs to them and ask the business (or whoever is responsible for managing users and groups) to only use them as building blocks. But to establish proper security you have to use the ACLs provided by AEM, rolling your own security was never a good idea.