Thursday 19 July 2012

AccessControlServlet and Profile's SecurityStatus


We normally use Profile.transient property to determine if a user is loggedIn. The method is not secure as users that have been logged in automatically have transient property set to false. You should check the profile's security status before displaying secured data such as user's profile or credit card information.


The securityStatus property of the Profile component is used to indicate the type of verification the user has passed through. When a user logs in (or is automatically logged in), the Personalization module sets the value of this property to an integer that indicates the login method used. This can be used to have a tiered login structure where a user can be automatically logged in but they must enter in their login credentials before being able to view certain information such as their address, order history, or credit card information.


The securityStatus property is set according to this table: 
  


Value

Login Method Used

0

Anonymous login

1

Auto-login by URL parameter

2

Auto-login by cookie

3

Login by http-(basic-authentication)

4

Explicit login or registration in the Personalization module via form handler

5

Explicit login or registration in the Personalization module via form handler underhttps protocol.

6

Certificate (not supported by ATG at this time).


AccessControlServlet 

This servlet checks the requestURI to see if it matches any of the requestedURLs identified in it's accessController map. The accessControllermap is made up of URLs matched to an AccessController instance that governs the rules to determine when a URL is requested whether the active Profile is permitted to view the page. When access is denied by an AccessController it calls the AccessControllerServlet which 
redirects the user to the URL in the deniedAccessURL.


Example of instance of AccessController that is invoked when the URL requested is present in the accessController map. allowAccess method uses the Profile's security Status



public boolean allowAccess(Profile pProfile, DynamoHttpServletRequest pRequest){
boolean isLoggedIn = false;
try {
Integer securityStatus = getProfileTools().getSecurityStatus(pProfile);
if(securityStatus >= getProfileTools().getPropertyManager().getSecurityStatusLogin()){
isLoggedIn = true;
}
} catch (PropertyNotFoundException propExc) {
if(isLoggingError()){
logError("PropertyNotFoundException", propExc);
}
}
return isLoggedIn;
}

public String getDeniedAccessURL(Profile pProfile){
DynamoHttpServletRequest dynamoRequest = ServletUtil.getCurrentRequest();
String requestURI = ServletUtil.getCurrentRequestURI(dynamoRequest);
StringBuffer requestURL = new StringBuffer();
if(!StringUtils.isBlank(requestURI)){
requestURL.append(requestURI);
}
String queryString = dynamoRequest.getQueryString();
if(!StringUtils.isBlank(queryString)){
StringBuffer modifiedQueryString = new StringBuffer();
String[] queryStringTokens = StringUtils.splitStringAtString(queryString, "&");
if(queryStringTokens!=null && queryStringTokens.length > 0){
StringTokenizer queryParamAndValue = null;
String paramName = "";
int maxCount = queryStringTokens.length;
for(int i=0;i<maxCount;i++){
queryParamAndValue = new StringTokenizer(queryStringTokens[i],"=");
if(queryParamAndValue.hasMoreTokens()){
paramName = queryParamAndValue.nextToken();
}
if(!"_Dargs".equalsIgnoreCase(paramName)){
if(i<maxCount){
modifiedQueryString.append(queryStringTokens[i]+"&");
}else{
modifiedQueryString.append(queryStringTokens[i]);
}
}
}
}
queryString = modifiedQueryString.toString();
requestURI = requestURL.append("&").append(queryString).toString();
}
return requestURI;
}


2 comments: