网站代码优化视频教程,贾汪网站建设,西安做网站的云阔,网站建设什么公司专业gwt格式在本教程中#xff0c;我们将看到如何将GWT与Spring的安全模块#xff08;即Spring Security#xff09;集成。 我们将看到如何保护GWT入口点#xff0c;如何检索用户的凭据以及如何记录各种身份验证事件。 此外#xff0c;我们将实现自定义身份验证提供程序#… gwt格式 在本教程中我们将看到如何将GWT与Spring的安全模块即Spring Security集成。 我们将看到如何保护GWT入口点如何检索用户的凭据以及如何记录各种身份验证事件。 此外我们将实现自定义身份验证提供程序以便可以重用现有的身份验证方案。 如果您是JavaCodeGeeks的普通读者那么现在您可能应该知道我们真的很喜欢GWT 。 过去贾斯汀Justin在GWT上写了一些杀手G的文章 如何将GWT与Spring和HibernateJPA集成以及如何在混合中添加Eclipse和Maven 。 此外我已经写了关于如何在GWT应用程序中添加JSON功能 如何为GWT添加CAPTCHA以及如何开始使用SmartGWT的文章 。 最后Pat写了有关构建自己的GWT Spring Maven原型并集成GWTEJB3Maven和JBoss的文章 。 因此我们现在开始使用Spring的Security模块就不足为奇了。 如官方站点所述 Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架。 它是用于保护基于Spring的应用程序的实际标准 。 Spring Security是Acegi框架的演变该框架在后台使用Spring以便主要为Web应用程序提供安全性。 但是Spring Security现在是一个完善的安全框架它不仅包含针对Web的功能还包含针对LDAP集成和ACL创建的功能。 在开始本教程之前最好先阅读一下Spring Security参考文档并准备好Spring Security API Javadocs 。 在本教程中我将使用GWT 2.1.0和Spring Security 3.0.5。 您可以在此处下载最新的生产版本。 您可能已经猜到了还需要Spring核心框架中的一些库。 您可以在此处下载框架。 让我们开始在Eclipse中创建一个新的Web应用程序项目我想您已经安装了Eclipse的Google插件并且已经部署了GWT。 我为该项目的名称选择了深奥的名称“ GwtSpringSecurityProject”。 Eclipse屏幕如下所示 将Spring安全性添加到我们的项目的第一步是在“ web.xml”文件中声明一个过滤器。 这个过滤器是FilterChainProxy类的实例它将拦截所有传入的请求并将请求的控制委托给适当的Spring处理程序。 相关的Web声明文件片段如下 …
filterfilter-namespringSecurityFilterChain/filter-namefilter-classorg.springframework.web.filter.DelegatingFilterProxy/filter-class
/filterfilter-mappingfilter-namespringSecurityFilterChain/filter-nameurl-pattern/*/url-pattern
/filter-mapping
... 我们还必须在“ web.xml”中定义ContextLoaderListener以便引导Spring上下文。 这是通过以下代码段完成的 …listenerlistener-classorg.springframework.web.context.ContextLoaderListener/listener-class/listener
... 接下来我们在“ war / WEB-INF”文件夹中创建一个名为“ applicationContext.xml”的文件。 在那里我们声明了Spring Security的相关信息。 最重要的元素是“ http ”它可用于定义应在哪些URL上应用安全性以及用户应具有哪些角色才能访问特定资源。 在我们的示例中代码段如下 …
http auto-configtrueintercept-url pattern/gwtspringsecurityproject/** accessROLE_USER/intercept-url pattern/gwt/** accessROLE_USER/intercept-url pattern/**/*.html accessROLE_USER/intercept-url pattern/** accessIS_AUTHENTICATED_ANONYMOUSLY /
/http
... 简而言之上述内容要求角色“ ROLE_USER”才能访问“ gwt”和“ gwtspringsecurityproject”文件夹与GWT相关的资源所在下的文件。 同样所有HTML文件如GWT的入口点都需要相同的角色。 “ IS_AUTHENTICATED_ANONYMOUSLY”意味着所有用户都可以访问特定资源而不必成为特定角色的一部分。 通过简单地使用“ http ”元素Spring将使用默认的登录页面和注销URL。 所有身份验证请求均由AuthenticationManager处理因此必须在文件中声明其实例。 更具体地说通常将请求委托给AuthenticationProvider 。 可以使用一些已经创建的实现例如DaoAuthenticationProvider 与DB中定义的角色和用户一起使用时或LdapAuthenticationProvider 根据LDAP服务器对用户进行身份验证。 但是出于本教程的目的我们将创建一个自定义身份验证提供程序并将其与spring的安全性基础架构集成。 在深入研究应用程序的代码之前我们必须首先处理依赖项。 这是必须添加到项目的类路径中的JAR org.springframework.context-3.0.5.RELEASE.jar Spring安全核心-3.0.5.RELEASE.jar spring-security-web-3.0.5.RELEASE.jar 好现在我们准备好了。 我们的提供程序非常简单仅使用静态Map来存储用户及其相应的密码。 这是代码 package com.javacodegeeks.gwt.security.server.auth;import java.util.HashMap;
import java.util.Map;import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;public class CustomAuthenticationProvider implements AuthenticationProvider {private static MapString, String users new HashMapString, String();static {users.put(fabrizio, javacodegeeks);users.put(justin, javacodegeeks);}Overridepublic Authentication authenticate(Authentication authentication) throws AuthenticationException {String username (String) authentication.getPrincipal();String password (String)authentication.getCredentials();if (users.get(username)null)throw new UsernameNotFoundException(User not found);String storedPass users.get(username);if (!storedPass.equals(password))throw new BadCredentialsException(Invalid password);Authentication customAuthentication new CustomUserAuthentication(ROLE_USER, authentication);customAuthentication.setAuthenticated(true);return customAuthentication;}Overridepublic boolean supports(Class? extends Object authentication) {return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);}} 让我们从头开始对该代码进行详细说明。 supports方法定义了此提供程序提供的身份验证的类型。 在我们的例子中 UsernamePasswordAuthenticationToken是我们希望处理的那个。 该实现旨在简化用户名和密码的显示。 实现了authenticate方法并在其中检索登录表单中提供的用户名通过getPrincipal方法以及随附的密码通过getCredentials方法。 首先我们检查特定的用户名是否存在如果不存在则抛出UsernameNotFoundException 。 同样如果用户名存在但密码不正确 则会引发BadCredentialsException 。 请注意这两个异常都扩展了父AuthenticationException类。 如果用户名和密码均正确我们将对用户进行身份验证。 为此我们必须返回Authentication接口的具体实例。 在这种情况下我们必须封装已知的用户信息凭证等以及用户所具有的角色权限。 请注意分配的角色ROLE_USER与“ applicationContext.xml”文件中声明的角色匹配。 另外必须调用setAuthenticated方法以true作为参数以向其余身份验证链指示特定用户已成功通过我们的模块进行身份验证。 让我们看看在这种情况下如何定义自定义身份验证对象 package com.javacodegeeks.gwt.security.server.auth;import java.util.ArrayList;
import java.util.Collection;import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;public class CustomUserAuthentication implements Authentication {private static final long serialVersionUID -3091441742758356129L;private boolean authenticated;private GrantedAuthority grantedAuthority;private Authentication authentication;public CustomUserAuthentication(String role, Authentication authentication) {this.grantedAuthority new GrantedAuthorityImpl(role);this.authentication authentication;}Overridepublic CollectionGrantedAuthority getAuthorities() {CollectionGrantedAuthority authorities new ArrayListGrantedAuthority();authorities.add(grantedAuthority);return authorities;}Overridepublic Object getCredentials() {return authentication.getCredentials();}Overridepublic Object getDetails() {return authentication.getDetails();}Overridepublic Object getPrincipal() {return authentication.getPrincipal();}Overridepublic boolean isAuthenticated() {return authenticated;}Overridepublic void setAuthenticated(boolean authenticated) throws IllegalArgumentException {this.authenticated authenticated;}Overridepublic String getName() {return this.getClass().getSimpleName();}} 在构造函数中我们传递用户的角色和原始的Authentication对象。 在实现的方法中最重要的一种是getAuthorities 它返回已授予主体的权限。 该信息在GrantedAuthority对象的集合内提供。 现在让我们看看“ applicationContext.xml”的样子 ?xml version1.0 encodingUTF-8?beans:beans xmlnshttp://www.springframework.org/schema/securityxmlns:beanshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsdbeans:bean idcustomAuthListener classcom.javacodegeeks.gwt.security.server.auth.CustomAuthListener/http auto-configtrueintercept-url pattern/gwtspringsecurityproject/** accessROLE_USER/intercept-url pattern/gwt/** accessROLE_USER/intercept-url pattern/**/*.html accessROLE_USER/intercept-url pattern/** accessIS_AUTHENTICATED_ANONYMOUSLY //httpbeans:bean idcustomAuthenticationProvider classcom.javacodegeeks.gwt.security.server.auth.CustomAuthenticationProvider / authentication-manager aliasauthenticationManagerauthentication-provider refcustomAuthenticationProvider//authentication-manager/beans:beans 除“ CustomAuthListener”外声明文件的每个元素均已定义。 作为Spring框架的一部分Spring Security允许应用程序开发人员提供回调这些回调将在应用程序生命周期的特定部分被调用。 因此当发生特定的身份验证事件时我们可以注册要调用的方法。 在我们的例子中我们将创建一个侦听器该侦听器接收AbstractAuthorizationEvent 即所有与安全拦截有关的事件。 让我们看看这是如何实现的 package com.javacodegeeks.gwt.security.server.auth;import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.security.authentication.event.AbstractAuthenticationEvent;
import org.springframework.security.authentication.event.AbstractAuthenticationFailureEvent;public class CustomAuthListener implements ApplicationListenerAbstractAuthenticationEvent {private static final Log logger LogFactory.getLog(CustomAuthListener.class);Overridepublic void onApplicationEvent(AbstractAuthenticationEvent event) {final StringBuilder builder new StringBuilder();builder.append(Authentication event );builder.append(event.getClass().getSimpleName());builder.append(: );builder.append(event.getAuthentication().getName());builder.append(; details: );builder.append(event.getAuthentication().getDetails());if (event instanceof AbstractAuthenticationFailureEvent) {builder.append(; exception: );builder.append(((AbstractAuthenticationFailureEvent) event).getException().getMessage());}logger.warn(builder.toString());}} 在我们的实现中我们仅记录所有成功和不成功的身份验证事件基于LoggerListener类但是在此处提供您自己的业务逻辑显然非常简单。 最后我们将创建一个GWT异步服务器端服务该服务将向客户端提供有关用户及其登录用户名的信息。 如果您最熟悉GWT那么理解代码就不会有任何问题。 这是服务的两个接口和具体实现 验证服务 package com.javacodegeeks.gwt.security.client;import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;/*** The client side stub for the RPC service.*/
RemoteServiceRelativePath(auth)
public interface AuthService extends RemoteService {String retrieveUsername();
} AuthServiceAsync package com.javacodegeeks.gwt.security.client;import com.google.gwt.user.client.rpc.AsyncCallback;/*** The async counterpart of codeAuthService/code.*/
public interface AuthServiceAsync {void retrieveUsername(AsyncCallbackString callback);
} AuthServiceImpl package com.javacodegeeks.gwt.security.server;import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.javacodegeeks.gwt.security.client.AuthService;SuppressWarnings(serial)
public class AuthServiceImpl extends RemoteServiceServlet implements AuthService {Overridepublic String retrieveUsername() {Authentication authentication SecurityContextHolder.getContext().getAuthentication();if (authenticationnull){System.out.println(Not logged in);return null;}else {return (String) authentication.getPrincipal();}}} 代码很简单。 我们使用SecurityContextHolder类来检索当前的SecurityContext 然后使用getAuthentication方法来获取对基础Authentication对象的引用。 然后我们通过getPrincipal方法检索用户名如果有。 当然我们必须在应用程序“ web.xml”文件中声明特定的servlet。 这里是 ...
servletservlet-nameauthServlet/servlet-nameservlet-classcom.javacodegeeks.gwt.security.server.AuthServiceImpl/servlet-class
/servletservlet-mappingservlet-nameauthServlet/servlet-nameurl-pattern/gwtspringsecurityproject/auth/url-pattern
/servlet-mapping
... 这是整个网络声明文件 ?xml version1.0 encodingUTF-8?
!DOCTYPE web-appPUBLIC -//Sun Microsystems, Inc.//DTD Web Application 2.3//ENhttp://java.sun.com/dtd/web-app_2_3.dtdweb-appfilterfilter-namespringSecurityFilterChain/filter-namefilter-classorg.springframework.web.filter.DelegatingFilterProxy/filter-class/filterfilter-mappingfilter-namespringSecurityFilterChain/filter-nameurl-pattern/*/url-pattern/filter-mappinglistenerlistener-classorg.springframework.web.context.ContextLoaderListener/listener-class/listener!-- Servlets --servletservlet-namegreetServlet/servlet-nameservlet-classcom.javacodegeeks.gwt.security.server.GreetingServiceImpl/servlet-class/servletservlet-mappingservlet-namegreetServlet/servlet-nameurl-pattern/gwtspringsecurityproject/greet/url-pattern/servlet-mappingservletservlet-nameauthServlet/servlet-nameservlet-classcom.javacodegeeks.gwt.security.server.AuthServiceImpl/servlet-class/servletservlet-mappingservlet-nameauthServlet/servlet-nameurl-pattern/gwtspringsecurityproject/auth/url-pattern/servlet-mapping!-- Default page to serve --welcome-file-listwelcome-fileGwtSpringSecurityProject.html/welcome-file/welcome-file-list/web-app 让我们看看如何在应用程序的入口点中使用此服务。 我们在onModuleLoad方法结束之前添加以下代码片段 authService.retrieveUsername(new AsyncCallbackString() {public void onFailure(Throwable caught) {dialogBox.setText(Remote Procedure Call - Failure);}public void onSuccess(String result) {nameField.setText(result);}}
); 启动我们的应用程序之前的最后一步是处理运行时依赖项。 Spring需要大量的库来执行其DI魔术因此这是必须存在于“ war / WEB-INF / lib”文件夹中的JAR列表 org.springframework.aop-3.0.5.RELEASE.jar org.springframework.asm-3.0.5.RELEASE.jar org.springframework.beans-3.0.5.RELEASE.jar org.springframework.context-3.0.5.RELEASE.jar org.springframework.core-3.0.5.RELEASE.jar org.springframework.expression-3.0.5.RELEASE.jar org.springframework.web-3.0.5.RELEASE.jar 弹簧安全配置-3.0.5.RELEASE.jar Spring安全核心-3.0.5.RELEASE.jar spring-security-web-3.0.5.RELEASE.jar 复制所有上述内容后启动Eclipse项目配置并尝试访问默认URL http://127.0.0.1:8888/GwtSpringSecurityProject.html?gwt.codesvr127.0.0.1:9997 Spring Security将拦截该请求并为您提供默认的登录页面。 提供如下有效凭证 提交表单数据您将被重定向到原始URL。 请注意该文本字段将填充用于登录的用户名。 返回到Eclipse控制台视图并查看在那里打印的各种日志。 您应该看到类似以下的内容 2010年12月12日晚上8:45:49 com.javacodegeeks.gwt.security.server.auth.CustomAuthListener onApplicationEvent 警告身份验证事件AuthenticationSuccessEventCustomUserAuthentication; 详细信息org.springframework.security.web.authentication.WebAuthenticationDetailsfffdaa08RemoteIpAddress127.0.0.1; SessionIdim1fdjvdu7yw 2010年12月12日晚上8:45:49 com.javacodegeeks.gwt.security.server.auth.CustomAuthListener onApplicationEvent 警告身份验证事件InteractiveAuthenticationSuccessEventCustomUserAuthentication; 详细信息org.springframework.security.web.authentication.WebAuthenticationDetailsfffdaa08RemoteIpAddress127.0.0.1; SessionIdim1fdjvdu7yw 那是所有人。 您可以在这里找到创建的Eclipse项目。 玩得开心 相关文章 GWT 2 Spring 3 JPA 2 Hibernate 3.5教程 SmartGWT入门提供出色的GWT界面 建立自己的GWT Spring Maven原型 GWT 2 Spring 3 JPA 2 Hibernate 3.5教程– Eclipse和Maven 2展示 使用Spring使用Java发送电子邮件– GMail SMTP服务器示例 翻译自: https://www.javacodegeeks.com/2010/12/securing-gwt-apps-with-spring-security.htmlgwt格式