上一篇文档初步搭建了一个springmvc的web工程,现在要来实现第二步咯。将登录校验整合到项目中,我用的是spring 3.0.2的版本,所以这里的登录用了security来处理。不多说,上代码。
web.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 5 http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> 6 7 <!-- spring核心监听器 配置ContextLoaderListener表示,该工程要以spring的方式启动。启动时会默认在/WEB-INF目录下查找 applicationContext.xml作为spring容器的配置文件 --> 8 <listener> 9 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 10 </listener> 11 12 <!-- 配置DispatcherServlet表示,该工程将采用springmvc的方式。启动时也会默认在/WEB-INF目录下查找XXX-servlet.xml作为配置文件,XXX就是DispatcherServlet的名字 --> 13 <!-- spring-servlet.xml --> 14 <servlet> 15 <servlet-name>spring</servlet-name> 16 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 17 </servlet> 18 <servlet-mapping> 19 <servlet-name>spring</servlet-name> 20 <url-pattern>/</url-pattern> 21 </servlet-mapping> 22 23 <!-- spring security --> 24 <filter> 25 <filter-name>springSecurityFilterChain</filter-name> 26 <filter-class>org.springframework.web.filter.DelegatingFilterProxy 27 </filter-class> 28 </filter> 29 30 <filter-mapping> 31 <filter-name>springSecurityFilterChain</filter-name> 32 <url-pattern>/*</url-pattern> 33 </filter-mapping> 34 35 <context-param> 36 <param-name>contextConfigLocation</param-name> 37 <param-value>classpath*:applicationContext-security.xml</param-value> 38 </context-param> 39 40 <!-- 欢迎页 --> 41 <welcome-file-list> 42 <welcome-file>login.jsp</welcome-file> 43 </welcome-file-list> 44 </web-app>
login.jsp
1 <%@ page language="java" contentType="text/html; charset=utf-8" 2 pageEncoding="utf-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 7 <title>title</title> 8 <script type="text/javascript"> 9 10 function login() { 11 var loginName = "qiuj"; 12 var loginPas = "qiuj"; 13 if (loginName == "") { 14 $.messager.alert('提示','请输入用户名!','warning'); 15 loginForm.username.focus(); 16 return; 17 } else if(loginPas == "") { 18 $.messager.alert('提示','请输入密码!','warning'); 19 loginForm.password.focus(); 20 return; 21 } else { 22 loginForm.action = "j_spring_security_check"; 23 loginForm.submit(); 24 } 25 } 26 27 </script> 28 </head> 29 <body> 30 <div> 31 <form id="loginForm" action="" method="post"> 32 <input type="text" name="username" id="username"/> 33 <input type="password" name="password" id="password"/> 34 <input type="button" value="登录" onclick="login();"/> 35 </form> 36 </div> 37 </body> 38 </html>
有的这次相比上次没改动过的文件就不写啦,参照上文咯,因为这次添加了security,所以pom文件也要加依赖
pom.xml
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 3 <modelVersion>4.0.0</modelVersion> 4 <groupId>com.qiuj</groupId> 5 <artifactId>springmvc-demo</artifactId> 6 <packaging>war</packaging> 7 <version>0.0.1-SNAPSHOT</version> 8 <name>springmvc-demo Maven Webapp</name> 9 <url>http://maven.apache.org</url> 10 <dependencies> 11 <dependency> 12 <groupId>junit</groupId> 13 <artifactId>junit</artifactId> 14 <version>3.8.1</version> 15 <scope>test</scope> 16 </dependency> 17 <dependency> 18 <groupId>org.springframework</groupId> 19 <artifactId>spring-web</artifactId> 20 <version>3.0.5.RELEASE</version> 21 </dependency> 22 23 <dependency> 24 <groupId>org.springframework</groupId> 25 <artifactId>spring-webmvc</artifactId> 26 <version>3.0.5.RELEASE</version> 27 </dependency> 28 29 <dependency> 30 <groupId>org.apache.geronimo.specs</groupId> 31 <artifactId>geronimo-servlet_2.5_spec</artifactId> 32 <version>1.2</version> 33 </dependency> 34 <dependency> 35 <groupId>org.springframework.security</groupId> 36 <artifactId>spring-security-web</artifactId> 37 <version>3.0.5.RELEASE</version> 38 </dependency> 39 40 <dependency> 41 <groupId>org.springframework.security</groupId> 42 <artifactId>spring-security-config</artifactId> 43 <version>3.0.5.RELEASE</version> 44 </dependency> 45 </dependencies> 46 <build> 47 <finalName>springmvc-demo</finalName> 48 </build> 49 </project>
因为我这里security只负责登录处理,所以本着低耦合的设计思想,把这部分配置单拿出来了(这是有问题的,先上这个代码,下边会给正确的,别急)
applicationContext-security.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans:beans xmlns="http://www.springframework.org/schema/security" 3 xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 6 http://www.springframework.org/schema/security 7 http://www.springframework.org/schema/security/spring-security-3.0.xsd"> 8 <!-- http安全配置 --> 9 <http use-expressions='true' 10 entry-point-ref="authenticationProcessingFilterEntryPoint" 11 access-denied-page="/access-denied.jsp"> 12 <!-- 登录页面不过滤 --> 13 <intercept-url pattern="/login.jsp" filters="none" /> 14 <!-- 修改注销页面 --> 15 <logout invalidate-session="true" logout-success-url="/login.jsp" logout-url="/j_spring_security_logout" /> 16 </http> 17 18 <!-- 登录验证器 --> 19 <beans:bean id="loginFilter" 20 class="com.test.service.security.MyUsernamePasswordAuthenticationFilter"> 21 <!-- 处理登录 --> 22 <beans:property name="filterProcessesUrl" value="/j_spring_security_check"></beans:property> 23 <beans:property name="authenticationSuccessHandler" ref="loginLogAuthenticationSuccessHandler"></beans:property> 24 <beans:property name="authenticationFailureHandler" ref="simpleUrlAuthenticationFailureHandler"></beans:property> 25 <beans:property name="authenticationManager" ref="myAuthenticationManager"></beans:property> 26 </beans:bean> 27 <!-- 未登录的切入点 --> 28 <beans:bean id="loginLogAuthenticationSuccessHandler" 29 class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler"> 30 <beans:property name="defaultTargetUrl" value="/index.jsp"></beans:property> 31 </beans:bean> 32 <beans:bean id="simpleUrlAuthenticationFailureHandler" 33 class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"> 34 <beans:property name="defaultFailureUrl" value="/login.jsp"></beans:property> 35 </beans:bean> 36 37 <!-- 用户拥有的权限:登录后取得用户所保有的权限信息 --> 38 <beans:bean id="myUserDetailService" class="com.test.service.security.AdminUserDetailServiceImpl"> 39 </beans:bean> 40 41 <!-- 未登录的切入点 --> 42 <beans:bean id="authenticationProcessingFilterEntryPoint" 43 class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"> 44 <beans:property name="loginFormUrl" value="/login.jsp"></beans:property> 45 </beans:bean> 46 47 <!-- 认证配置,使用userDetailsService提供的用户信息,实现了UserDetailsService的Bean --> 48 <authentication-manager alias="myAuthenticationManager"> 49 <authentication-provider 50 user-service-ref="myUserDetailService"> 51 <!-- 默认提供的PasswordEncoder包含plaintext, sha, sha-256, md5, md4, {sha}, 52 {ssha}。 其中{sha}和{ssha}是专门为ldap准备的,plaintext意味着不对密码进行加密, 如果我们不设置PasswordEncoder,默认就会使用它。 --> 53 <password-encoder hash="plaintext" /> 54 </authentication-provider> 55 </authentication-manager> 56 57 </beans:beans>
上两个java文件
AdminUserDetailServiceImpl.java
1 /** 2 * 3 */ 4 /** 5 * @author Administrator 6 * 7 */ 8 package com.test.service.security; 9 10 import java.util.Set; 11 12 import org.springframework.security.core.GrantedAuthority; 13 import org.springframework.security.core.userdetails.User; 14 import org.springframework.security.core.userdetails.UserDetails; 15 import org.springframework.security.core.userdetails.UserDetailsService; 16 import org.springframework.security.core.userdetails.UsernameNotFoundException; 17 18 public class AdminUserDetailServiceImpl implements UserDetailsService { 19 20 //登录验证 21 public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 22 23 Set<GrantedAuthority> grantedAuths = null; 24 25 //封装成spring security的user 26 User userdetail = new User("", "", 27 true, // 账号状态 0 表示停用 1表示启用 28 true, true, true, grantedAuths // 用户的权限 29 ); 30 return userdetail; 31 } 32 33 }
MyUsernamePasswordAuthenticationFilter.java
1 /** 2 * 3 */ 4 /** 5 * @author Administrator 6 * 7 */ 8 package com.test.service.security; 9 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 13 import org.springframework.security.authentication.AuthenticationServiceException; 14 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 15 import org.springframework.security.core.Authentication; 16 import org.springframework.security.core.AuthenticationException; 17 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 18 19 public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{ 20 21 public static final String USERNAME = "username"; 22 public static final String PASSWORD = "password"; 23 24 @Override 25 public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { 26 27 if (!request.getMethod().equals("POST")) { 28 throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); 29 } 30 31 String username = obtainUsername(request); 32 String password = obtainPassword(request); 33 34 if (username == null) { 35 username = ""; 36 } 37 38 if (password == null) { 39 password = ""; 40 } 41 42 username = username.trim(); 43 44 UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); 45 46 setDetails(request, authRequest); 47 48 49 return this.getAuthenticationManager().authenticate(authRequest); 50 } 51 52 @Override 53 protected String obtainUsername(HttpServletRequest request) { 54 Object obj = request.getParameter(USERNAME); 55 return null == obj ? "" : obj.toString(); 56 } 57 58 @Override 59 protected String obtainPassword(HttpServletRequest request) { 60 Object obj = request.getParameter(PASSWORD); 61 return null == obj ? "" : obj.toString(); 62 } 63 }
项目结构(注意:我这里给的都是按照我的结构配置的,如不一样,要自己客户化啊)
好了,这就是第一次运行了
登录。。。。。。报错。。。。404。。。似曾相识的错误啊
应该applicationContext-security.xml文件配置哪里有问题。。。
瞎调了半天,觉得还是要认真理解配置都代表啥才能更好的对症下药。。。
配置自定义custom-filter---------问题在这里
这是第一次配置的截图,这里的bean并没有对应的自定义过滤器调用啊啊啊啊啊。。。。
修改为:
好 上代码
applicationContext-security.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans:beans xmlns="http://www.springframework.org/schema/security" 3 xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 6 http://www.springframework.org/schema/security 7 http://www.springframework.org/schema/security/spring-security-3.0.xsd"> 8 <!-- http安全配置 --> 9 <http use-expressions="true" 10 entry-point-ref="authenticationProcessingFilterEntryPoint"> 11 <!-- 登录页面不过滤 --> 12 <intercept-url pattern="/login.jsp" filters="none" /> 13 <!-- 只有权限才能访问的请求 --> 14 <intercept-url pattern="/**" access="hasRole('ROLE_USER')"/> 15 <custom-filter ref="loginFilter" position="FORM_LOGIN_FILTER" /> 16 <!-- 修改注销页面 --> 17 <logout invalidate-session="true" logout-success-url="/login.jsp" logout-url="/j_spring_security_logout" /> 18 </http> 19 20 <!-- 登录验证器 --> 21 <beans:bean id="loginFilter" 22 class="com.test.service.security.MyUsernamePasswordAuthenticationFilter"> 23 <!-- 处理登录 --> 24 <beans:property name="filterProcessesUrl" value="/j_spring_security_check"></beans:property> 25 <beans:property name="authenticationSuccessHandler" ref="loginLogAuthenticationSuccessHandler"></beans:property> 26 <beans:property name="authenticationFailureHandler" ref="simpleUrlAuthenticationFailureHandler"></beans:property> 27 <beans:property name="authenticationManager" ref="myAuthenticationManager"></beans:property> 28 </beans:bean> 29 <!-- 未登录的切入点 --> 30 <beans:bean id="loginLogAuthenticationSuccessHandler" 31 class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler"> 32 <beans:property name="defaultTargetUrl" value="/login"></beans:property> 33 </beans:bean> 34 <beans:bean id="simpleUrlAuthenticationFailureHandler" 35 class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"> 36 <beans:property name="defaultFailureUrl" value="/login.jsp"></beans:property> 37 </beans:bean> 38 39 <!-- 用户拥有的权限:登录后取得用户所保有的权限信息 --> 40 <beans:bean id="myUserDetailService" class="com.test.service.security.AdminUserDetailServiceImpl"> 41 </beans:bean> 42 43 <!-- 未登录的切入点 --> 44 <beans:bean id="authenticationProcessingFilterEntryPoint" 45 class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"> 46 <beans:property name="loginFormUrl" value="/login.jsp"></beans:property> 47 </beans:bean> 48 49 <!-- 认证配置,使用userDetailsService提供的用户信息,实现了UserDetailsService的Bean --> 50 <authentication-manager alias="myAuthenticationManager"> 51 <authentication-provider 52 user-service-ref="myUserDetailService"> 53 <!-- 默认提供的PasswordEncoder包含plaintext, sha, sha-256, md5, md4, {sha}, 54 {ssha}。 其中{sha}和{ssha}是专门为ldap准备的,plaintext意味着不对密码进行加密, 如果我们不设置PasswordEncoder,默认就会使用它。 --> 55 <password-encoder hash="plaintext" /> 56 </authentication-provider> 57 </authentication-manager> 58 59 </beans:beans>
顺便为了规范化,也将欢迎页和登录跳转的成功页修改了
MyUsernamePasswordAuthenticationFilter.java
1 /** 2 * 3 */ 4 /** 5 * @author Administrator 6 * 7 */ 8 package com.test.service.security; 9 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 13 import org.springframework.security.authentication.AuthenticationServiceException; 14 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 15 import org.springframework.security.core.Authentication; 16 import org.springframework.security.core.AuthenticationException; 17 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 18 19 public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{ 20 21 public static final String USERNAME = "username"; 22 public static final String PASSWORD = "password"; 23 24 @Override 25 public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { 26 27 if (!request.getMethod().equals("POST")) { 28 throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); 29 } 30 31 String username = obtainUsername(request); 32 String password = obtainPassword(request); 33 34 if (username == null) { 35 username = ""; 36 } 37 38 if (password == null) { 39 password = ""; 40 } 41 42 username = username.trim(); 43 44 UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); 45 46 setDetails(request, authRequest); 47 48 49 return this.getAuthenticationManager().authenticate(authRequest); 50 } 51 52 @Override 53 protected String obtainUsername(HttpServletRequest request) { 54 Object obj = request.getParameter(USERNAME); 55 return null == obj ? "" : obj.toString(); 56 } 57 58 @Override 59 protected String obtainPassword(HttpServletRequest request) { 60 Object obj = request.getParameter(PASSWORD); 61 return null == obj ? "" : obj.toString(); 62 } 63 }
AdminUserDetailServiceImpl.java
1 /** 2 * 3 */ 4 /** 5 * @author Administrator 6 * 7 */ 8 package com.test.service.security; 9 10 import java.util.ArrayList; 11 import java.util.Collection; 12 13 import org.springframework.security.core.GrantedAuthority; 14 import org.springframework.security.core.authority.GrantedAuthorityImpl; 15 import org.springframework.security.core.userdetails.User; 16 import org.springframework.security.core.userdetails.UserDetails; 17 import org.springframework.security.core.userdetails.UserDetailsService; 18 import org.springframework.security.core.userdetails.UsernameNotFoundException; 19 20 public class AdminUserDetailServiceImpl implements UserDetailsService { 21 22 //登录验证 23 public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 24 25 Collection<GrantedAuthority> auths = new ArrayList<GrantedAuthority>(); 26 auths.add(new GrantedAuthorityImpl("ROLE_USER")); 27 String password = "1234"; 28 //String password = loginUser.getLoginPW(); 29 //封装成spring security的user 30 User userdetail = new User(username, password, 31 true, // 账号状态 0 表示停用 1表示启用 32 true, true, true, auths // 用户的权限 33 ); 34 return userdetail; 35 } 36 37 }
跑起来
目前这个版本还没有用到数据库判断权限啊 用户啊之类的,都是写死的配置,先初步出来一版吧,感觉对整体有个概念,然后想要理解。。。spring源码,I'm coming。。。
源码还是依旧百度云盘吧。。。干巴呆