samir
samir

Reputation: 339

Implement Authentication for servlet on publish instance CQ5/AEM

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.

What can I do to achieve this?

Upvotes: 0

Views: 2092

Answers (4)

samir
samir

Reputation: 339

Thanks everyone for your replies. In the end I implemented the below code for authentication in cq :

                final String authorization = request.getHeader("Authorization");
                if (authorization != null && authorization.startsWith("Basic")) {
                  StringTokenizer st = new StringTokenizer(authorization);
                  if (st.hasMoreTokens()) {
                    String basic = st.nextToken();
                    if (basic.equalsIgnoreCase("Basic")) {
                      String decodedStr = Base64.decode(st.nextToken());
                      LOGGER.info("Credentials: " + decodedStr);
                      int p = decodedStr.indexOf(":");
                      if (p != -1) {
                        String login = decodedStr.substring(0, p).trim();
                        String password = decodedStr.substring(p + 1).trim();

                        Credentials credentials = new SimpleCredentials(login, password.toCharArray());
                        adminSession = repository.login(credentials);

                        if (null != adminSession) {
                          // means authenticated and do your stuff here                                  
                        }
                      }
                    }
                  }
                }

Also in the webservice code which is calling the servlet of publish, below is the code on how I am supplying the credentials in auth headers :

                String authStr = usrname+":"+password;
				// encode data on your side 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("jsondata={sample:jsoncontent}");  
				writer.close();  

Upvotes: 1

Mohit Bansal
Mohit Bansal

Reputation: 384

I recommend to use a two step process:

  • Step 1: Authentication and generate a token, you can use 3rd party service also to generate token.
  • Step 2: Call your servlet with this token, the servlet will validate token first and then use post data.

Upvotes: 1

Cris Rockwell
Cris Rockwell

Reputation: 904

You might consider using Google Client Library. I used it for authentication of users in an AEM publish instance. After the third party server is authenticated, you could use a separate AEM service account to handle POST processing.

Here' a SO post I made about integrating those libraries into AEM. Google Client API in OSGI

With this you should be able set up authentication of the third party service account... as discussed here https://developers.google.com/identity/protocols/OAuth2ServiceAccount

I haven't actually done server to server auth in AEM, but it should be possible. But in a separate project (non AEM) I've used the Google Client Library for authenticating Service Accounts.

Upvotes: 1

petre
petre

Reputation: 508

The way I would go for it:

Ask those 3rd party applications to send you the username and password so you can validate them on your servlet, then decide if you will allow or reject the request.

from the servlet calling (the 3rd party application)

 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // ... 

        request.setAttribute("username", "a_valid_user");
        request.setAttribute("password", "a_valid_password");
        request.getRequestDispatcher("yourApp/YourServlet").forward(req, resp);
}

On your servlet:

String username = request.getParameter("username");
String password = request.getParameter("password");

if("a_valid_user".equals(username) && "a_valid_password".equals(password) {
     // validate and go further
} else {
     // do not process the request
}

The above example is valid just in case you can validate them on your side.

If this sample doesn't answer to your question, please provide more information about those 3rd party applications and the way you want to validate them.

Upvotes: 1

Related Questions