Struts 2 + Waffle:用户主体始终为空

时间:2012-02-29 09:28:23

标签: security jsp struts2 waffle

我正在开发基于Java,JSP,Struts 2和Waffle的Web应用程序以确保安全性。我在Tomcat 6中运行它。我的问题是我无法在ActionSupport类中获取主体对象。更具体地说,

principalProxy.getUserPrincipal()

始终返回null。但是当我把它放在.jsp文件中时:

request.getUserPrincipal()

这不会返回null。因此,必须在原始HttpServletRequest对象中提供信息。当然,我尝试在ActionSupport类的HttpServletRequest对象上调用getUserPrincipal(),但这也会返回null。

我的ActionSupport类定义为

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

此外,我的struts.xml使用servlet-config拦截器集定义了一个动作,因此实际调用setPrincipalProxy()方法(由print语句验证)。这是我的struts.xml(缩写):

<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>

web.xml定义了一个安全过滤器和一个应该匹配任何URL的过滤器映射。以下是相关部分:

<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>

请求SomeAction时,系统会根据需要提示我使用HTTP基本身份验证对话框。这表明SecurityFilter实际上确实得到了应用,不是吗?也会调用setPrincipalProxy()方法。我可以在JSP页面中获取Principal对象。那么当我尝试在SomeAction中访问它时,为什么Principal对象总是为null?

还有一件事,我正在使用URL重写,万一可能与它有关。

编辑: 响应batbaatar的请求,在Java中设置请求。可能不会简单得多。

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

实例变量httpRequest的类型为HttpServletRequest。

1 个答案:

答案 0 :(得分:1)

我仍然无法从HTTPServletRequest获取用户主体对象。但是,我能够从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 "";
  }
}

会话密钥定义为:

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

仍然对原始问题的答案感到好奇。