Implementing the SSLInterceptor
I will not explain the concept of interceptor and will directly explain the internal working of the SSL interceptor. the main purpose of this interceptor is to make the requests to go through https or http mode based on the annotations.
This will work in 2 modes.
1. Annotation based
If its annotation based the interceptor will check for the 'secure' marker in the action class or method level, if secure annotation is present in the class all the methods invoked from this class will be redirected to https mode. if the annotation is present in a method level only the methods which have the 'secure' annotation will be redirected to https mode, others will redirected to http mode.
2. Non-Annotion based
All the action classes which goes through this interceptor will be redirected to https mode.
public String intercept(ActionInvocation invocation) throws Exception {
// initialize request and response
final ActionContext context = invocation.getInvocationContext ();
final HttpServletRequest request =
(HttpServletRequest) context.get(StrutsStatics.HTTP_REQUEST);
final HttpServletResponse response =
(HttpServletResponse) context.get(StrutsStatics.HTTP_RESPONSE);
// check scheme
String scheme = request.getScheme().toLowerCase();
// check method
String method = request.getMethod().toUpperCase();
// if userAnnotations is true check for the annotaion marker in the class level or method level
// else make every request secure.
// If the action class/method uses the Secured marker annotation, then see if we need to
// redirect to the SSL protected version of this page
Object action = invocation.getAction();
Method method2 = getActionMethod(action.getClass(), invocation.getProxy().getMethod());
if ( !isUseAnnotations() || action.getClass().isAnnotationPresent(Secured.class) || method2.isAnnotationPresent(Secured.class) ){
if (HTTP_GET.equals(method) && SCHEME_HTTP.equals(scheme)){
// initialize https port
int httpsPort = getHttpsPort() == null? HTTPS_PORT : Integer.parseInt(getHttpsPort());
URI uri = new URI(SCHEME_HTTPS, null, request.getServerName(),
httpsPort, response.encodeRedirectURL(request.getRequestURI()),
request.getQueryString(), null);
log.info("Going to SSL mode, redirecting to " + uri.toString());
response.sendRedirect(uri.toString());
return null;
}
}
// Otherwise, check to see if we need to redirect to the non-SSL version of this page
else{
if (HTTP_GET.equals(method) && SCHEME_HTTPS.equals(scheme)){
// initialize http port
int httpPort = getHttpPort() == null? HTTP_PORT : Integer.parseInt(getHttpPort());
URI uri = new URI(SCHEME_HTTP, null, request.getServerName(),
httpPort, response.encodeRedirectURL(request.getRequestURI()),
request.getQueryString(), null);
log.info("Going to non-SSL mode, redirecting to " + uri.toString());
response.sendRedirect(uri.toString());
return null;
}
}
return invocation.invoke();
}
Declaring our Interceptor in struts.xml
We need to add the SSLInterceptor to an interceptor stack so it will be used when an action is invoked.
<struts>
<package name="my-default" extends="struts-default">
<interceptors>
...
<interceptor name="secure" class="SSLInterceptor" />
<interceptor-stack name="defaultSSLStack">
<interceptor-ref name="secure"><!-- Our SSLInterceptor -->
<param name="httpPort">8084</param><!-- http port to use, default is 8080 -->
<param name="httpsPort">443</param><!-- https port to use, default is 8443 -->
<param name="useAnnotations">false</param>
</interceptor-ref>
<interceptor-ref name="servlet-config" />
<interceptor-ref name="params" />
<interceptor-ref name="prepare" />
<interceptor-ref name="chain" />
<interceptor-ref name="model-driven" />
<interceptor-ref name="fileUpload" />
<interceptor-ref name="static-params" />
<interceptor-ref name="params" />
<interceptor-ref name="conversionError" />
<interceptor-ref name="validation" />
<interceptor-ref name="workflow" />
</interceptor-stack>
</default-interceptor-ref name="defaultSSLStack" />
...
</package>
</struts>
Saturday, July 28, 2007
Subscribe to:
Comments (Atom)