0

我将 RequestFactory 与 GWT 一起使用。一切正常。我有一个指向我的 DAO 方法的 RequestContext 接口。

现在我想在调用 DAO 之前实现某种安全检查。我首先想到的是使用 FrontController 并将安全性集中在其中,但我不知道用 RequestFactory 来实现它。任何想法 ?

4

3 回答 3

3

如果要测试用户是否经过身份验证,可以在服务器端使用 servlet 过滤器,在RequestTransport客户端使用自定义过滤器。有关示例,请参阅https://github.com/tbroyer/gwt-maven-archetypesguice-rf-activity上的原型。

您还可以通过使用自定义ServiceLayerDecorator和实现方法来检查方法级别,在用户未获得授权/身份验证时invoke调用(并在客户端处理)。我实现了这样一个东西,它根据服务方法或类的注释授权用户:https ://gist.github.com/tbroyer/6091533report()onFailure@RolesAllowed

于 2013-03-26T15:56:51.670 回答
1

以下是我实施安全检查的方式:

在服务器端,我检查每个RequestFactory请求是否与先前登录的用户相关联。为此,web.xml文件(在 war/WEB-INF 目录中)必须具有 servlet 类的映射。这是文件中的条目web.xml

<servlet>
  <servlet-name>requestFactoryServlet</servlet-name>
  <servlet-class>org.greatlogic.rfexample2.server.RFERequestFactoryServlet</servlet-class>
  <init-param>
    <param-name>symbolMapsDirectory</param-name>
    <param-value>WEB-INF/classes/symbolMaps/</param-value>
  </init-param>
</servlet>
<servlet-mapping>
  <servlet-name>requestFactoryServlet</servlet-name>
  <url-pattern>/gwtRequest</url-pattern>
</servlet-mapping>

该类RFERequestFactoryServlet包含以下代码:

public class RFERequestFactoryServlet extends RequestFactoryServlet {

@Override
protected void doPost(final HttpServletRequest request, final HttpServletResponse response)
  throws IOException, ServletException {
  if (!userIsLoggedIn(request)) {
    response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
  }
  else {
    super.doPost(request, response);
  }
}

private boolean userIsLoggedIn(final HttpServletRequest request) {
  boolean result = false;
  HttpSession session = request.getSession();
  if (session != null) {
    User user = (User)session.getAttribute("User");
    result = user != null;
  }
  return result;
}

}

在客户端,我需要拦截每个RequestFactory响应以检查SC_UNAUTHORIZED错误。您必须告诉对象在调用RequestFactory中使用特定的,如下所示:RequestTransportRequestFactory#initialize

MyRequestFactory requestFactory = GWT.create(MyRequestFactory.class);
requestFactory.initialize(eventBus, new RFERequestTransport());

我的RFERequestTransport班级扩展了DefaultRequestTransport班级:

public class RFERequestTransport extends DefaultRequestTransport {

private final class RFERequestCallback implements RequestCallback {

private RequestCallback _requestCallback;

private RFERequestCallback(final RequestCallback requestCallback) {
  _requestCallback = requestCallback;
}

@Override
public void onError(final Request request, final Throwable exception) {
  _requestCallback.onError(request, exception);
}

@Override
public void onResponseReceived(final Request request, final Response response) {
  if (response.getStatusCode() == Response.SC_UNAUTHORIZED) {
    // the login processing goes here
  }
  else {
    _requestCallback.onResponseReceived(request, response);
  }
}

} // end of the RFERequestCallback class

@Override
protected RequestCallback createRequestCallback(final TransportReceiver receiver) {
  return new RFERequestCallback(super.createRequestCallback(receiver));
}

}

创建RequestFactory请求回调时,它会调用我的方法,该方法会创建我自己的RequestCallback. 如果用户已登录(由 servlet 确定),则它只执行正常RequestFactory处理;否则,我将与用户一起完成登录过程。登录过程的一部分涉及与服务器的通信以验证登录......如果登录成功,那么我在服务器上创建一个对象并将对它的引用存储在“用户”属性中 - 然后在userIsLoggedIn方法中检查在 servlet 类中。

于 2013-03-26T20:57:35.557 回答
1

在您的 web.xml 中设置一个过滤器,以便过滤每个 RF 请求以验证会话。

<filter>
  <filter-name>AuthFilter</filter-name>
  <filter-class>my.namespace.AuthFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>AuthFilter</filter-name>
  <url-pattern>/gwtRequest</url-pattern>
</filter-mapping>

这里有一个示例类,检查某个参数是否在会话中,该参数可以在您的应用程序的登录过程中设置,这只是一个示例,您可以使用自己的机制。

  public class AuthFilter implements Filter {

    public void doFilter(ServletRequest servletRequest,
        ServletResponse servletResponse, FilterChain filterChain)
        throws IOException, ServletException {

      HttpServletRequest req = (HttpServletRequest) servletRequest;
      HttpServletResponse resp = (HttpServletResponse) servletResponse;

      if (req.getSession().getAttribute("VALID_SESSION") == null) {
        resp.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        return;
      }

      if (null != filterChain) {
        filterChain.doFilter(req, resp);
      }

    }
  }
于 2013-03-26T15:58:58.160 回答