2013-03-26 83 views
0

我在GWT中使用RequestFactory。这一切工作正常。我有一个指向我的DAO方法的RequestContext接口。GWT中带有RequestFactory的FrontController

现在我想在调用DAO之前执行某种安全检查。我想到的第一件事是使用FrontController并集中安全性,但我不知道如何使用RequestFactory实现它。任何想法 ?

+0

你想做什么样的安全检查?测试用户身份验证? – Sam 2013-03-26 15:38:28

+0

基本上我想检查用户是否有活动会话。 – outellou 2013-03-26 15:41:02

回答

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类中。

+0

如何管理第一个登录请求?因为会话尚未创建 – outellou 2013-04-02 16:11:43

+0

@Moh在'RFERequestFactoryServlet#userIsLoggedIn'我正在执行'HttpServletRequest#getSession'。此方法的JavaDoc状态为:返回与此请求关联的当前会话,或者如果请求没有会话,则创建一个会话。 – 2013-04-02 22:16:57

+0

我了解'HttpSession'部分。但是,当用户从会话中获取时,它可能为空,如果没有用户登录,这将是正常的。现在我的问题是,当我调用登录的DAO中的方法时,该呼叫将被处理'RFERequestFactoryServlet#userIsLoggedIn',并且因为会话中没有用户,所以登录请求不会经过并且将显示登录视图。如何让登录请求通过,即使没有用户在会话中? – outellou 2013-04-03 17:42:26

3

如果要测试用户是否已通过身份验证,则可以在服务器端使用servlet筛选器,并在客户端使用自定义RequestTransport。例如,请参阅guice-rf-activity原型https://github.com/tbroyer/gwt-maven-archetypes

您也可以通过使用自定义ServiceLayerDecorator贯彻invoke方法,调用report()当用户未授权/认证(和处理在客户端的onFailure)检查方法级别。我实现了这样的事情,即授权用户基于服务方法或类上的@RolesAllowed注释:https://gist.github.com/tbroyer/6091533

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); 
     } 

    } 
    }