3

我正在开发一个基于 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() 方法确实被调用(通过打印语句验证)。这是我的 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。

4

1 回答 1

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

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

于 2012-03-05T12:01:27.023 回答