3

I am working on a Web application based on Java, JSP, Struts 2 and Waffle for security. I run it in Tomcat 6. My problem is that I cannot get a principal object in my ActionSupport class. To be more specific,

principalProxy.getUserPrincipal()

always returns null. When I put this in a .jsp file, however:

request.getUserPrincipal()

this does not return null. So the information must be available in the original HttpServletRequest object. Of course, I have tried calling getUserPrincipal() on the HttpServletRequest object in the ActionSupport class, but this also returns null.

My ActionSupport class is defined as

public class SomeAction extends ActionSupport 
  implements ServletRequestAware, ServletResponseAware, PrincipalAware {
  ...

Furthermore, my struts.xml defines an action with the servlet-config interceptor set, so the setPrincipalProxy() method does actually get called (verified by print statements). This is my struts.xml (shortened):

<package name="default" namespace="/" extends="struts-default">
  <action name="some" class="com.my.package.SomeAction">
    <interceptor-ref name="servlet-config" />
    <interceptor-ref name="params">
      <param name="excludeParams ">(.*)</param>
    </interceptor-ref>
    <interceptor-ref name="i18n"/>
    <result name="success">/someresult.jsp</result>
  </action>
</package>

The web.xml defines a security filter and a filter mapping that should match any URL. Here are the relevant parts:

<filter>
  <filter-name>struts2</filter-name>
  <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>

<filter>
  <filter-name>SecurityFilter</filter-name>
  <filter-class>waffle.servlet.NegotiateSecurityFilter</filter-class>   
  <init-param>
    <param-name>principalFormat</param-name>
    <param-value>fqn</param-value>
  </init-param>
  <init-param>
    <param-name>roleFormat</param-name>
    <param-value>both</param-value>
  </init-param>
  <init-param>
    <param-name>allowGuestLogin</param-name>
    <param-value>true</param-value>
  </init-param>
  <init-param>
    <param-name>securityFilterProviders</param-name>
    <param-value>
      waffle.servlet.spi.BasicSecurityFilterProvider
      waffle.servlet.spi.NegotiateSecurityFilterProvider
    </param-value>
  </init-param>
  <init-param>
    <param-name>waffle.servlet.spi.NegotiateSecurityFilterProvider/protocols</param-name>
    <param-value>
      Negotiate
      NTLM
    </param-value>
  </init-param>
  <init-param>    
    <param-name>waffle.servlet.spi.BasicSecurityFilterProvider/realm</param-name>
    <param-value>WaffleFilterDemo</param-value>
  </init-param>
</filter>

<filter-mapping>
  <filter-name>struts2</filter-name>
  <url-pattern>/*</url-pattern>
  <dispatcher>FORWARD</dispatcher>
  <dispatcher>REQUEST</dispatcher>         
</filter-mapping>

<filter-mapping>
  <filter-name>SecurityFilter</filter-name>
  <url-pattern>/*</url-pattern>
  <dispatcher>FORWARD</dispatcher>
  <dispatcher>REQUEST</dispatcher>      
</filter-mapping>

When requesting SomeAction, I am prompted with a HTTP Basic Authentication dialog as desired. This shows that the SecurityFilter does in fact get applied, doesn't it? The setPrincipalProxy() method gets called as well. I can get a Principal object in the JSP page. So why is the Principal object always null when I try to access it in SomeAction?

One more thing, I am employing URL rewriting, in case that could have anything to do with it.

EDIT: In response to batbaatar's request, the setting of the request in Java. Could not be much simpler.

@Override
public void setServletRequest(HttpServletRequest request) {
  httpRequest = request;
}

The instance variable httpRequest is of type HttpServletRequest.

Tom Bartel
  • 2,283
  • 1
  • 15
  • 18

1 Answers1

1

I still could not get a user principal object from the HTTPServletRequest. However, I am able to get a principal object from the Session:

private String getLoggedInUser() {
  if (httpSession.containsKey(WAFFLE_PRINCIPAL_KEY)) {
    WindowsPrincipal principal = 
      (WindowsPrincipal) httpSession.get(WAFFLE_PRINCIPAL_KEY);
    return principal == null ? "" : principal.getName();
  } else {
    return "";
  }
}

The session key is defined as:

private static final String WAFFLE_PRINCIPAL_KEY = 
    "waffle.servlet.NegotiateSecurityFilter.PRINCIPAL";

Still curious for an answer to the original question, though.

Tom Bartel
  • 2,283
  • 1
  • 15
  • 18
  • have you tried asking the same on struts-user list, might be able to get some insights there – Umesh Awasthi Mar 06 '12 at 07:15
  • Can you get user principal by adding these lines? import org.apache.struts2.ServletActionContext; Principal userPrincipal = ServletActionContext.getRequest().getUserPrincipal(); – batbaatar Mar 07 '12 at 09:07