springmvc maven搭建二之springmvc的security

上一篇文档初步搭建了一个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>
web.xml

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>
login.jsp

有的这次相比上次没改动过的文件就不写啦,参照上文咯,因为这次添加了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>
pom.xml

因为我这里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>
applicationContext-security.xml

上两个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 }
AdminUserDetailServiceImpl.java

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 } 
MyUsernamePasswordAuthenticationFilter.java

项目结构(注意:我这里给的都是按照我的结构配置的,如不一样,要自己客户化啊)

好了,这就是第一次运行了

登录。。。。。。报错。。。。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>
applicationContext-security.xml

顺便为了规范化,也将欢迎页和登录跳转的成功页修改了

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 } 
MyUsernamePasswordAuthenticationFilter.java

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 }
AdminUserDetailServiceImpl.java

跑起来

目前这个版本还没有用到数据库判断权限啊 用户啊之类的,都是写死的配置,先初步出来一版吧,感觉对整体有个概念,然后想要理解。。。spring源码,I'm coming。。。

源码还是依旧百度云盘吧。。。干巴呆

原文地址:https://www.cnblogs.com/qiujiababy/p/8205207.html