Your achievements

Level 1

0% to

Level 2

Tip /
Sign in

Sign in to Community

to gain points, level up, and earn exciting badges like the new
BedrockMission!

Learn more

View all

Sign in to view all badges

SOLVED

Implementing Authentication for servlet on publish instance

__96
Level 4
Level 4

Hi,

I have a scenario and any suggestions in implementing that will be of great help. I have a servlet created on publish that will have POST requests coming from a lot of other third party applications. This servlet just stores the incoming posted data in JCR. I have successfully created this servlet but now the requirement is to make this servlet secured so that only applications hitting this servlet with particular username and password should be entertained.

Has anyone knowledge on what I can do to achieve this.

Thanks,

Samir

1 Accepted Solution
Jitendra_S_Toma
Correct answer by
Level 9
Level 9

Hi Samir,

Use UserManager API in your servlets which handles are the request from third party applications. Through UserManager API, you could extract individual user profiles to do validation against given parameters.

Here is the doc which could help you.

http://wemcode.wemblog.com/user-group-management

https://docs.adobe.com/docs/en/aem/6-0/develop/ref/javadoc/org/apache/jackrabbit/api/security/user/U...

Jitendra

$@^^!R wrote...

Hi,

I have a scenario and any suggestions in implementing that will be of great help. I have a servlet created on publish that will have POST requests coming from a lot of other third party applications. This servlet just stores the incoming posted data in JCR. I have successfully created this servlet but now the requirement is to make this servlet secured so that only applications hitting this servlet with particular username and password should be entertained.

Has anyone knowledge on what I can do to achieve this.

Thanks,

Samir

 

View solution in original post

11 Replies
Jitendra_S_Toma
Correct answer by
Level 9
Level 9

Hi Samir,

Use UserManager API in your servlets which handles are the request from third party applications. Through UserManager API, you could extract individual user profiles to do validation against given parameters.

Here is the doc which could help you.

http://wemcode.wemblog.com/user-group-management

https://docs.adobe.com/docs/en/aem/6-0/develop/ref/javadoc/org/apache/jackrabbit/api/security/user/U...

Jitendra

$@^^!R wrote...

Hi,

I have a scenario and any suggestions in implementing that will be of great help. I have a servlet created on publish that will have POST requests coming from a lot of other third party applications. This servlet just stores the incoming posted data in JCR. I have successfully created this servlet but now the requirement is to make this servlet secured so that only applications hitting this servlet with particular username and password should be entertained.

Has anyone knowledge on what I can do to achieve this.

Thanks,

Samir

 

View solution in original post

kunal23
Level 10
Level 10

I would recommend you to bind this servlet to a page path using the resource type and then use closed user group feature in AEM to secure this path on the publish instance. You need to expose only the page path to your external applications. If they request the page with authentication then they will be granted access otherwise it redirects to the login page. 

See the following pages for more details- 

[1] https://cqdump.wordpress.com/2015/03/23/aem-coding-best-practice-servlets/

[2] https://helpx.adobe.com/experience-manager/kb/HowToSetupCUG.html

[3] https://docs.adobe.com/docs/en/aem/6-1/administer/security/cug.html

Jitendra_S_Toma
Level 9
Level 9

In my view, using CUG would be difficult to do with a given case. Third party applications are posting some data & that data has to store in JCR. What would happen if third party API which hits our servlet gets login page in response?.

Jitendra

__96
Level 4
Level 4

Yes jeetendra completely agree with you. That wont suffice my requirement. To really tell you about the scenario its like an SAP system which has some form which has to submit that data to CQ thrrough SOAP webservice. For the same I have created a SOAP webservice and deployed in an Tomcat app server. That webservice gets the data from SAP and the posts the same to CQ5. Now I dont want any random application to submit to my servlet, so for that I thought of bringing in some authentication mechanism which makes CQ5 identify that its authorized application requesting submit on my servlet.

For now I have manually added the authorization in webservice connection which calls the servlet with encoded username password as admin:admin and in CQ5 servlet I am decoding the same using Base64 decoder and checking if its admin admin, only then I am writing the data into JCR. Now I know this is just an workaround approach and hence looking for a more recommended way to achieve the same. Also I know still anyone can sniff the authorization from packets and decode and see the username but I have been told that if CQ5 will be on SSL, noone will be able to see the username password. But still I feel thats not the correct way. Any help with this ? 

Jitendra_S_Toma
Level 9
Level 9

Samir,

if it is just about making username/password secure, you could use java.security & javax.crypto.* API for encryption & decryption. AEM does have crypto support API.

https://docs.adobe.com/docs/en/aem/6-1/ref/javadoc/

Jitendra

Jörg_Hoh
Employee
Employee

Hi,

first question: why don't you deploy your webserver in AEM? You can bring a bundle which contains all the logic and libraries to do the webservice call, and then directly persist the data.

Regarding the authentication: Please use the approach described by kunal and bind your servlet to a resourcetype; then create a page using this resourcetype and protected this page via ACLs; you can configure AEM/Sling to accept basic authentication. And then everything should work. Do not implement authentication on your own!

kind regards,
Jörg

__96
Level 4
Level 4

Jörg Hoh wrote...

Hi,

first question: why don't you deploy your webserver in AEM? You can bring a bundle which contains all the logic and libraries to do the webservice call, and then directly persist the data.

Regarding the authentication: Please use the approach described by kunal and bind your servlet to a resourcetype; then create a page using this resourcetype and protected this page via ACLs; you can configure AEM/Sling to accept basic authentication. And then everything should work. Do not implement authentication on your own!

kind regards,
Jörg

 

Hi Jorg,

I am not consuming the SOAP webservice, but hosting it, thats the reason I created/deployed that webservice on a seperate Tomcat server as .war file. Do you mean we can create the webservice in CQ5 ? or can we deploy that .war in CQ5 ?

Regarding kunal's approach, I have not clearly understood the approach. If you can clarify on my understanding I will be able to implement the same way. Does he mean I have to declare the servlet like below : 

@SlingServlet(resourceTypes = "/apps/myproject/components/mycomponent", methods = {"POST", "GET"}, metatype=true) public class MyServlet extends SlingAllMethodsServlet{

and then the same component, I will use an any Page's sling:resourceType like below :

sling:resourceType = "/apps/myproject/components/mycomponent"

And what about the script of /apps/myproject/components/mycomponent . Should I write any html, jsp there or there is no need for any script ?

Also one more thing will be if the basic authentication fails for such CUG restricted pages, then it will show the login page which is not needed in my case as it will be accessed through Java code, we can't show login page. Also in my webservice do I need to post data to the page instead of servlet like below :

String servleturltopost = "http://localhost:4503/content/site/pagewithcug.html"; String param = "data=somejsondata";     URL url = new URL(servleturltopost); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); String authStr = "testuser"+":"+"testuserforcug"; // encoding data using BASE64 byte[] bytesEncoded = Base64.encodeBase64(authStr.getBytes()); String authEncoded = new String(bytesEncoded); connection.setRequestProperty("Authorization", "Basic "+authEncoded); connection.setDoOutput(true); connection.setRequestMethod("POST"); OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());                     writer.write(param);  writer.close();

Samir

kunal23
Level 10
Level 10

Hi Samir, 

Yes, that is what I meant. You do not need to create the mycomponent in apps as you have already registered this resource type by binding it to the servlet. When you access any page which has this sling:resourceType then Sling will call the servlet automatically. You can restrict access to this page by either using CUG or ACLs. With this approach your servlet do not need to implement any custom authentication logic as it will be handled by AEM itself.  

Thanks,

Kunal

__96
Level 4
Level 4

kunal23 wrote...

Hi Samir, 

Yes, that is what I meant. You do not need to create the mycomponent in apps as you have already registered this resource type by binding it to the servlet. When you access any page which has this sling:resourceType then Sling will call the servlet automatically. You can restrict access to this page by either using CUG or ACLs. With this approach your servlet do not need to implement any custom authentication logic as it will be handled by AEM itself.  

Thanks,

Kunal

 

Hi Kunal,

Thanks a lot for explaining in such detail man. With CUG it will redirect to  login page. But because I will be posting the data from within a webservice I will not need login page in response. 

Thanks,

kunal23
Level 10
Level 10

CUG just does a 302 redirect to any page you specify as path in the properties. It is not necessary that it should always be a login page. For example -You can have a redirect page which have "NOT PERMITTED" as output in the JSON format. 

kunal23
Level 10
Level 10

Also, if you use ACLs/permissions approach instead of CUG then you will get an error page with 403 response code in the header(if the passed user does not have permissions) and if it is successful then you will get 200 as response code in the header. In your service code you can check on the response header value to determine if the post was success or not.