gwt和spring security的集成方法

gwt如何与spring security集成,这是个问题。如果能够合理的集成,可以实现很多需要认证和授权的场合。

比如在访问需要授权的地方,显示登录界面:

image

登录后可以看到授权的界面:

image

如果退出,将返回到登录界面:

image

登录的用户,如果没有授权,比如没有上传权限,当执行文件上传时,提示权限不足。

image

当然,不具备权限的用户,应该看不到上传视频界面才对。这里只是演示针对授权不足的服务器端与客户端交互的实例。在正式的系统中,应该根据用户授权生成用户界面,另外,也还要提供服务器端的检查和客户端的提示机制。

下面说说集成gwt和spring security的基本思路。

spring security提供了对web的认证和授权支持。但是,是基于传统的web mvc模式的,视图由服务器端生成。而gwt,视图都在浏览器端由javascript生成,只需从服务器端获取数据,比如json格式的数据。spring security没有提供对ajax的通用支持。

这里就需要考虑,是否还要使用spring security,自己实现认证和授权不也可以么?经过比较,还是使用spring security工作量小,至少大部分认证授权功能都可以使用,只是需要考虑如何与gwt对接。

如何与gwt集成,spring security提供了三种web认证形式,比较主要的是form和basic,都做了集成的实验。还是form方式比较好集成,因为form方式可以通过服务器端的重定向等动作识别和拦截,而basic,是通过请求头信息,以及返回401/403码和浏览器通信,会造成浏览器的响应早于javascritp。

具体方案,是在web app中,增加一个靠前的Filter,用于检查是否有对*.json和j_spring_security_check。

因为,如果spring security受保护的资源被访问,会重定向到登录界面,要求用户登录。而gwt不需要这个重定向,因为gwt有自己的登录界面,只是需要服务器端触发它。因此监控*.json和j_spring_security_check如果被重定向到spring_security_login,也就是登录界面,则不执行重定向操作,改为返回401(未授权错误),gwt根据401,产生事件,触发登录界面。

有关认证部分的配置和代码。

web.xml的配置:

<filter>
    <filter-name>ajaxAuthFilter</filter-name>
    <filter-class>com.easymorse.videos.server.FormAuthenticationFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>ajaxAuthFilter</filter-name>
    <url-pattern>*.json</url-pattern>
</filter-mapping>

<filter-mapping>
    <filter-name>ajaxAuthFilter</filter-name>
    <url-pattern>/j_spring_security_check</url-pattern>
</filter-mapping>

 

Filter代码:

package com.easymorse.videos.server;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

public class FormAuthenticationFilter implements Filter {

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        HttpServletResponse httpServletResponse = new AuthenticationResponseWrapper(
                (HttpServletResponse) response);
        chain.doFilter(request, httpServletResponse);
    }

    @Override
    public void init(FilterConfig config) throws ServletException {
    }

}

class AuthenticationResponseWrapper extends HttpServletResponseWrapper {

    public AuthenticationResponseWrapper(HttpServletResponse response) {
        super(response);
    }

    @Override
    public void sendRedirect(String location) throws IOException {
        if (location.contains("spring_security_login")) {
            this.sendError(401, "need login");
        } else {
            if (!location.endsWith("json")) {
                super.sendRedirect(location);
            }
        }
    }

}

 

gwt有关代码,使用了gwt的mvp模式,http 401会引发NeedLoginEvent事件,代码就不贴出来了,可以见google code上的源代码。

还有一种情况,是授权不够的问题,即已经登录了,但是这个用户没有足够权限访问某个资源。按理说,应该根据用户的权限动态生成界面,这样用户就不会访问未授权的资源了。但是也可能是这样,比如用户有两个帐号,一个普通用户,一个管理员的。用户的操作可能产生url的变化,在gwt中是token,比如:

http://easymorse.com/aaa/a.html#admin

用户用管理员权限登录访问过上述资源,并保留了书签,下次直接访问书签,却用了普通用户登录。这时就需要上面提到的处理方式。

源代码见:

http://easymorse.googlecode.com/svn/tags/Videos-0.3.2/

PDF格式創作    发送文章为PDF   

这篇文章上的评论的 RSS feed TrackBack URI

Leave a Reply