上一篇文檔初步搭建了一個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。。。
源碼還是依舊百度雲盤吧。。。干巴呆