2013-06-03 149 views
2

我已经搜索了关于这个主题的教程,但他们都过时了。任何人都可以向我提供任何链接,或有关将Spring安全整合到GWT中的示例?GWT与Spring安全框架集成

+0

以下是GWT的单个登录页面的一些讨论 - 请参阅我的意见以接受答案。我在这里没有代码片段,但今天晚上我会尽力为您提供。 http://stackoverflow.com/questions/6508238/gwt-authentication-for-some-part-of-application-using-gwt-login-page –

+0

考虑[this](http://stackoverflow.com/questions/13914547/gwt-spring-security-integration-pure-gwt-no-jsp/13934318#13934318)回答如果你有兴趣将安全性应用到服务器端方法 –

+0

@PiotrekDe我将等待你的代码片断,谢谢 – Olzhas

回答

3

首先,您必须记住,GWT应用程序已转变为在客户端运行的JavaScript,因此您无法真正保护某些资源。所有敏感信息都应该存储在服务器端(与其他情况一样,不仅仅是GWT),所以正确的方法是从应用程序服务层的角度思考Spring Security集成,并将该安全与通信协议使用 - 在GWT的情况下,它在大多数情况下是请求工厂。

该解决方案不是非常简单,但我无法以任何更好的方式做到...任何细化建议都是值得欢迎的。

您需要从创建GWT ServiceLayerDecorator开始,将请求工厂的世界与Spring的世界连接起来。覆盖createServiceInstance方法以春季服务类的名称从服务名称标注值调用和返回该服务的实例(你需要从春天ApplicationContext获得它):

final Class<?> serviceClass = requestContext.getAnnotation(ServiceName.class).value(); 
return appContext.getBean(serviceClass); 

此外,你需要重写超invoke(Method, Object...)方法为了捕获所有抛出的运行时异常。 如果是Spring Security AccessDeniedException的实例,应该分析捕获到的异常原因。如果是这样,应该重新抛出异常原因。在这种情况下,GWT不会将异常序列化为字符串,而是再次重新抛出异常,因此,调度程序servlet可以通过设置适当的HTTP响应状态码来处理异常。所有其他类型的异常将被GWT序列化为字符串。

其实,你可以只捕获GWT ReportableException,但不幸的是它有包访问修饰符(heh ... GWT不是那么容易扩展)。捕获所有运行时异常要安全得多(尽管不是很优雅,我们别无选择) - 如果GWT实现发生更改,此代码仍可正常工作。

现在你需要插入你的装饰器。 - 你需要做一个肮脏的黑客和覆盖要求在工厂的servlet doPost方法改变了方式,如何处理例外

public MyRequestFactoryServlet() { 
    this(new DefaultExceptionHandler(), new SpringServiceLayerDecorator()); 
} 

的最后一件事:您可以通过扩展要求在工厂的servlet和定义您的Servlet构造如下容易做到这一点 - 默认情况下,异常被序列化为字符串,服务器发送500个状态码。并非所有异常都应该导致500 s.c - 例如安全性异常应该导致未经授权的状态码。所以,你需要做的是改写的异常处理机制以下列方式:

catch (RuntimeException e) { 
    if (e instanceof AccessDeniedException) { 
    response.sendError(HttpServletResponse.SC_UNAUTHORIZED); 
    } else { 
    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 
    LOG.log(Level.SEVERE, "Unexpected error", e); 
    } 
} 

而是扩展类的,你可以尝试使用一些“周围”方面 - 这是在这种情况下,清晰的解决方案。

就是这样!现在,您可以像往常一样使用Spring Security注释(@Secured等等)来注释您的应用程序服务层。

我知道 - 这一切都很复杂,但Google的请求工厂几乎不可扩展。伙计们在通信协议方面做了很多工作,但是这个库的设计很糟糕。当然,客户端代码有一些限制(它被编译为java脚本),但服务器端代码可以设计得更好......

+0

今天想法出现在我的脑海中,您如何看待,如果我检查授权详细信息,在GWT servlet实施方法之前,请检查用户是否为anonymouse,如果匿名方法将返回null,则在客户端,我们可以获得例如,在GWT的servlet中,每个方法都会检查Authentication auth = SecurityContextHolder.getContext()。getAuthentication();如果它没有通过身份验证,则返回null或任何信息到客户端并通过其处理。这个想法是否可行? – Olzhas