Tuesday, October 23, 2018

[Java] Central Authentication Service (CAS) Authentication

To secure the application, only authenticated user should be able to access it. Authorize user can be located in database or LDAP repository. Most of the time the users already have user repository like Active Directory. Providing a solution that can be configured to use different repository would be a good idea. It will decouple the authentication provider with the user repository. Below diagram shows an option for CAS to connect to database.

The diagram below shows an application deployed in application server, e.g. Websphere or JBoss authenticate logon user against LDAP or database.







Below is a sample code to call CAS server to authenticate user.


import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.security.sasl.AuthenticationException;



public class CasAuthenticationAdapter{

  private static final String CAS_URL = "http://{hostname}:{port}/cas-server-webapp-3.5.2/v1/tickets";

public boolean authenticate(
  String username, 
  String password){

  String tgt = null;

try{
tgt = getTicketGrantingTicket(username, password);
}catch (IOException e){
e.printStackTrace();
}

if (tgt == null){
return false;
}else{
return true;
}
}


private  String getTicketGrantingTicket(
  String username, 
  String password)throws IOException{

Map<String,Object> params = new LinkedHashMap<>();
params.put("username", username);
params.put("password", password);
HttpURLConnection conn = post(CAS_URL, params);

  if(conn.getResponseCode() == 400){
    throw new AuthenticationException("bad username or password");
  }
        
  String location = conn.getHeaderField("Location");
  System.out.println("TGT LOCATION -> " + location);
  return location;
}


private HttpURLConnection post(
  String url, 
  Map<String, Object> params)throws IOException{
System.out.println("Posting to url '" + url +"' w/ params '" +   params.toString() + "'");

URL connectionUrl = createUrl(url);
byte[] postDataBytes = convertParamMapToBytes(params);
HttpURLConnection conn = (HttpURLConnection)connectionUrl.openConnection();
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
        conn.setDoOutput(true);
        conn.getOutputStream().write(postDataBytes);
        return conn;
}


private URL createUrl(String url) throws MalformedURLException{
return new URL(url);
}


private byte[] convertParamMapToBytes(
  Map<String, 
  Object> params)throws UnsupportedEncodingException{
StringBuilder postData = new StringBuilder();
    for (Map.Entry<String,Object> param : params.entrySet()){
      if (postData.length() != 0) postData.append('&');
      postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
      postData.append('=');         postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
        }
      return postData.toString().getBytes("UTF-8");
}

}

No comments:

Post a Comment