spring security 4.1添加验证码和动态权限管理
2016-07-21 16:18
453 查看
本来想一步一步逐步深入的,可惜突然有了其他的事情,只能把一些高级功能一次性演示出来
添加验证码的方式在网上有很多相关的文章,我这里采用的方式是替换标准过滤器链里的UsernamePasswordAuthenticationFilter,验证码的产生方式不是这里要讨论的核心内容,所以直接用代码模拟在session里产生了一个验证码,动态权限来替代xml配置的权限,是在FILTER_SECURITY_INTERCEPTOR前面添加一个自定义的过滤器来实现。
添加需要的jar包,pom文件如下:
项目结构
![](https://img-blog.csdn.net/20160722161357532)
web.xml的配置
spring的默认配置文件 applicationContext.xml,启用注解,暂时还没用到AOP。
spring web mvc的配置文件 spring-servlet.xml
spring security的配置文件,spring-security.xml
上面是具体的配置,下面是配置里bean的具体代码文件,在xml里配置注入的类不要使用注解,否则会报错。
HelloWorldController.java 为了测试spring web mvc的
VirtualUserDao.java 在这个例子里没有集成数据库连接,所以用一个类来生成相关数据,可以修改为到数据库里获取相关信息
MyUsernamePasswordAuthenticationFilter.java 是为了添加验证码进行验证,为了省事,只重写了验证码的部分,如果想要改变系统里默认的错误提示,就把其他部分都重写。
MyFilterSecurityInterceptor.java 实现动态权限管理的过滤器,和默认的过滤器基本一致,由于默认的过滤器不能被修改,只能继承一个,然后来实现手工注入
MyFilterInvocationSecurityMetadataSource.java 通过URL来获取此URL所需要的权限。
MyAccessDecisionManager.java 对比URL所需权限和用户所具有的权限,决定用户是否可以访问 。
MyCustomUserDetailService.java 根据用户名,获取用户所具有的权限
index.jsp 我们自定义的登录页面
其他几个只是为了查看测试结果的jsp页面,可以随便实现。
helloworld.jsp
userIndex.jsp
adminIndex.jsp
loginFailed.jsp
到这里算是把spring web mvc和spring security的部分都测通了,等后续有时间了,再向里面添加数据库连接的部分。
添加验证码的方式在网上有很多相关的文章,我这里采用的方式是替换标准过滤器链里的UsernamePasswordAuthenticationFilter,验证码的产生方式不是这里要讨论的核心内容,所以直接用代码模拟在session里产生了一个验证码,动态权限来替代xml配置的权限,是在FILTER_SECURITY_INTERCEPTOR前面添加一个自定义的过滤器来实现。
添加需要的jar包,pom文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>pers.homer.test</groupId> <artifactId>spring</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>spring Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.1.RELEASE</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>4.1.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>4.1.1.RELEASE</version> </dependency> </dependencies> <build> <finalName>spring</finalName> </build> </project>
项目结构
web.xml的配置
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name>Servlet 3.0 Web Application</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml,/WEB-INF/spring-security.xml</param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 字符集过滤器 --> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter </filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>spring</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
spring的默认配置文件 applicationContext.xml,启用注解,暂时还没用到AOP。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd "> <!-- 扫描注解文件 --> <context:component-scan base-package="pers.homer.test" /> <!-- aop自动注解 <aop:aspectj-autoproxy /> --> </beans>
spring web mvc的配置文件 spring-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 扫描注解文件 --> <context:component-scan base-package="pers.homer.test" /> <!-- 启动注解 --> <mvc:annotation-driven/> <!-- <bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter" /> <bean id="jasonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> </list> </property> </bean> <mvc:annotation-driven> <mvc:message-converters> <ref bean="stringHttpMessageConverter" /> <ref bean="jasonHttpMessageConverter" /> </mvc:message-converters> </mvc:annotation-driven> --> <!-- 静态资源映射 --> <mvc:resources mapping="/javascript/**" location="/static/javascript/"/> <mvc:resources mapping="/styles/**" location="/static/styles/"/> <mvc:resources mapping="/images/**" location="/static/images/"/> <!-- 使用默认servlet处理静态文件 --> <mvc:default-servlet-handler /> <!-- 视图名称到文件的映射 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/view/" /> <property name="suffix" value=".jsp" /> </bean> </beans>
spring security的配置文件,spring-security.xml
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.1.xsd "> <debug/> <http pattern="/resources/**" security="none" /> <http use-expressions="true" auto-config="false" entry-point-ref="authenticationEntryPoint"> <intercept-url pattern="/index.jsp 15873 *" access="permitAll" /> <intercept-url pattern="/LoginFailed" access="permitAll" /> <intercept-url pattern="/**" access="hasRole('ROLE_USER')" /> <!-- 添加自定义filter,替换原有的,或是插入新的 , 替换登录验证,添加资源验证--> <custom-filter ref="loginFilter" position="FORM_LOGIN_FILTER" /> <custom-filter ref="myFilterSecurityInterceptor" before="FILTER_SECURITY_INTERCEPTOR"/> </http> <!-- 自定义用户密码认证filter,需要指定authenticationEntryPoint --> <beans:bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"> <beans:constructor-arg name="loginFormUrl" value="/" /> </beans:bean> <!-- 自定义filter必须手工实现各个属性的注入 --> <beans:bean id="loginFilter" class="pers.homer.test.model.MyUsernamePasswordAuthenticationFilter"> <beans:property name="authenticationManager" ref="authenticationManager"></beans:property> <beans:property name="authenticationSuccessHandler"> <beans:bean class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler"> <beans:property name="defaultTargetUrl" value="/helloworld"> </beans:property> </beans:bean> </beans:property> <beans:property name="authenticationFailureHandler"> <beans:bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"> <beans:property name="defaultFailureUrl" value="/"></beans:property> </beans:bean> </beans:property> </beans:bean> <beans:bean id="myFilterSecurityInterceptor" class="pers.homer.test.model.MyFilterSecurityInterceptor"> <beans:property name="securityMetadataSource"> <beans:bean class="pers.homer.test.model.MyFilterInvocationSecurityMetadataSource"></beans:bean> </beans:property> <beans:property name="accessDecisionManager"> <beans:bean class="pers.homer.test.model.MyAccessDecisionManager"></beans:bean> </beans:property> <beans:property name="authenticationManager" ref="authenticationManager"></beans:property> </beans:bean> <authentication-manager alias="authenticationManager"> <authentication-provider user-service-ref="myCustomUserDetailService"> <!-- 密码编码器,使用md5加密 <password-encoder hash="md5"/> --> <!-- 账号密码采用配置方式,很少会直接这样使用,所以要自己实现UserDetailService <user-service> <user name="test" password="test" authorities="ROLE_USER" /> <user name="admin" password="admin" authorities="ROLE_ADMIN" /> </user-service> --> </authentication-provider> </authentication-manager> </beans:beans>
上面是具体的配置,下面是配置里bean的具体代码文件,在xml里配置注入的类不要使用注解,否则会报错。
HelloWorldController.java 为了测试spring web mvc的
/** * */ package pers.homer.test.controller; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.ModelAndView; /** * @author homer * */ @RestController public class HelloWorldController { /** * */ public HelloWorldController() { // TODO Auto-generated constructor stub } @RequestMapping("/hello") public @ResponseBody String helloworld(){ return "helloworld"; } @RequestMapping("/test") public @ResponseBody Map<String, String> getResponse(){ Map<String, String> map = new HashMap<String, String>(); map.put("name", "test"); return map; } @RequestMapping("/helloworld") public ModelAndView getpage(){ ModelAndView mView = new ModelAndView(); List<String> list = new ArrayList<String>(); list.add("1"); list.add("1"); list.add("1"); list.add("1"); list.add("1"); list.add("1"); list.add("1"); list.add("10"); mView.addObject("name", "xxxxx"); mView.addObject("list", list); mView.setViewName("helloworld"); return mView; } }
VirtualUserDao.java 在这个例子里没有集成数据库连接,所以用一个类来生成相关数据,可以修改为到数据库里获取相关信息
/** * */ package pers.homer.test.dao; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; /** * @author homer * */ public class VirtualUserDao { /** * 模拟数据库查询返回数据,仅为测试使用 */ public VirtualUserDao() { // TODO Auto-generated constructor stub } public static UserDetails getUser(String userName) { User user = new User(userName, getUserPassword(userName), true, true, true, true, getRoleList(userName)); return user; } public static Collection<GrantedAuthority> getRoleList(String userName) { Collection<GrantedAuthority> auths=new ArrayList<GrantedAuthority>(); SimpleGrantedAuthority auth2=new SimpleGrantedAuthority("ROLE_ADMIN"); SimpleGrantedAuthority auth1=new SimpleGrantedAuthority("ROLE_USER"); if(userName.equals("admin")){ auths.add(auth1); auths.add(auth2); } else { auths.add(auth1); } return auths; } public static String getUserPassword(String userName) { return userName; } public static Map<String, Collection<ConfigAttribute>> getResourceMap() { Map<String, Collection<ConfigAttribute>> retMap = new HashMap<String, Collection<ConfigAttribute>>(); Collection<ConfigAttribute> list = new ArrayList<ConfigAttribute>(); list.add(new SecurityConfig("ROLE_USER")); retMap.put("/view/userIndex.jsp*", list); list = new ArrayList<ConfigAttribute>(); list.add(new SecurityConfig("ROLE_ADMIN")); retMap.put("/view/adminIndex.jsp*", list); return retMap; } }
MyUsernamePasswordAuthenticationFilter.java 是为了添加验证码进行验证,为了省事,只重写了验证码的部分,如果想要改变系统里默认的错误提示,就把其他部分都重写。
/** * */ package pers.homer.test.model; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.AccessDecisionManager; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.stereotype.Component; import org.springframework.util.Assert; /** * @author homer * */ public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter { public static final String SPRING_SECURITY_FORM_VALID_CODE = "validCode"; private String validCodeParameter = SPRING_SECURITY_FORM_VALID_CODE; /** * */ public MyUsernamePasswordAuthenticationFilter() { // TODO Auto-generated constructor stub //默认处理登录的页面是/login,方式是POST super(); } /* (non-Javadoc) * @see org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#attemptAuthentication(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { // TODO Auto-generated method stub String validCodeString = (String)request.getSession().getAttribute(validCodeParameter); String inputValidCode = obtainValidCode(request); if(validCodeString == null ||!validCodeString.equals(inputValidCode)) throw new AuthenticationServiceException( "验证码输入错误! "); return super.attemptAuthentication(request, response); } protected String obtainValidCode(HttpServletRequest request) { return request.getParameter(validCodeParameter); } /** * @return the validCodeParameter */ public String getValidCodeParameter() { return validCodeParameter; } /** * @param validCodeParameter the validCodeParameter to set */ public void setValidCodeParameter(String validCodeParameter) { Assert.hasText(validCodeParameter, "Valid code parameter must not be empty or null"); this.validCodeParameter = validCodeParameter; } }
MyFilterSecurityInterceptor.java 实现动态权限管理的过滤器,和默认的过滤器基本一致,由于默认的过滤器不能被修改,只能继承一个,然后来实现手工注入
/** * */ package pers.homer.test.model; import java.io.IOException; import javax.servlet.ServletException; import org.springframework.security.access.AccessDecisionManager; import org.springframework.security.access.intercept.InterceptorStatusToken; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; /** * @author homer * */ public class MyFilterSecurityInterceptor extends FilterSecurityInterceptor { /** * */ public MyFilterSecurityInterceptor() { // TODO Auto-generated constructor stub } /* (non-Javadoc) * @see org.springframework.security.web.access.intercept.FilterSecurityInterceptor#invoke(org.springframework.security.web.FilterInvocation) */ @Override public void invoke(FilterInvocation fi) throws IOException, ServletException { // TODO Auto-generated method stub InterceptorStatusToken token = super.beforeInvocation(fi); try { fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); } finally { super.afterInvocation(token, null); } } }
MyFilterInvocationSecurityMetadataSource.java 通过URL来获取此URL所需要的权限。
/** * */ package pers.homer.test.model; import java.util.Collection; import java.util.Iterator; import java.util.Map; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.util.AntPathMatcher; import pers.homer.test.dao.VirtualUserDao; /** * @author homer * */ public class MyFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource { private static Map<String, Collection<ConfigAttribute>> resourceMap = null; /** * */ public MyFilterInvocationSecurityMetadataSource() { // TODO Auto-generated constructor stub loadResourceDefine(); } public void loadResourceDefine() { //初始化时加载资源权限信息,后续可以调用此方法来刷新权限信息 if(resourceMap != null) resourceMap.clear(); resourceMap = VirtualUserDao.getResourceMap(); } /* (non-Javadoc) * @see org.springframework.security.access.SecurityMetadataSource#getAttributes(java.lang.Object) */ public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException { // TODO Auto-generated method stub // object 是一个URL,被用户请求的url。 FilterInvocation filterInvocation = (FilterInvocation) object; Iterator<String> ite = resourceMap.keySet().iterator(); RequestMatcher urlMatcher; while (ite.hasNext()) { String resURL = ite.next(); urlMatcher = new AntPathRequestMatcher(resURL); if (urlMatcher.matches(filterInvocation.getHttpRequest())) { return resourceMap.get(resURL); } } return null; } /* (non-Javadoc) * @see org.springframework.security.access.SecurityMetadataSource#getAllConfigAttributes() */ public Collection<ConfigAttribute> getAllConfigAttributes() { // TODO Auto-generated method stub return null; } /* (non-Javadoc) * @see org.springframework.security.access.SecurityMetadataSource#supports(java.lang.Class) */ public boolean supports(Class<?> clazz) { // TODO Auto-generated method stub return true; } }
MyAccessDecisionManager.java 对比URL所需权限和用户所具有的权限,决定用户是否可以访问 。
/** * */ package pers.homer.test.model; import java.util.Collection; import java.util.Iterator; import org.springframework.security.access.AccessDecisionManager; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; import org.springframework.security.authentication.InsufficientAuthenticationException; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; /** * @author homer * */ public class MyAccessDecisionManager implements AccessDecisionManager { /** * */ public MyAccessDecisionManager() { // TODO Auto-generated constructor stub } /* (non-Javadoc) * @see org.springframework.security.access.AccessDecisionManager#decide(org.springframework.security.core.Authentication, java.lang.Object, java.util.Collection) */ public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException { // TODO Auto-generated method stub if (configAttributes == null) { return; } Iterator<ConfigAttribute> ite = configAttributes.iterator(); while (ite.hasNext()) { ConfigAttribute ca = ite.next(); String needRole = ((SecurityConfig) ca).getAttribute(); // ga 为用户所被赋予的权限。 needRole 为访问相应的资源应该具有的权限。 for (GrantedAuthority ga : authentication.getAuthorities()) { if (needRole.trim().equals(ga.getAuthority().trim())) { return; } } } throw new AccessDeniedException(""); } /* (non-Javadoc) * @see org.springframework.security.access.AccessDecisionManager#supports(org.springframework.security.access.ConfigAttribute) */ public boolean supports(ConfigAttribute attribute) { // TODO Auto-generated method stub return true; } /* (non-Javadoc) * @see org.springframework.security.access.AccessDecisionManager#supports(java.lang.Class) */ public boolean supports(Class<?> clazz) { // TODO Auto-generated method stub return true; } }
MyCustomUserDetailService.java 根据用户名,获取用户所具有的权限
/** * */ package pers.homer.test.model; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Component; import pers.homer.test.dao.VirtualUserDao; /** * @author homer * */ @Component public class MyCustomUserDetailService implements UserDetailsService { /** * */ public MyCustomUserDetailService() { // TODO Auto-generated constructor stub } /* * 获取用户的相关信息,密码,角色,是否到期,是否停用,是否锁定 * 可以进行扩展,采用数据库存储查询相关的信息 * 此处返回的用户信息,会在 */ public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException { // TODO Auto-generated method stub return VirtualUserDao.getUser(userName); } }
index.jsp 我们自定义的登录页面
<?xml version="1.0" encoding="UTF-8" ?> <%@ page language="java" isELIgnored="false" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>首页</title> <meta http-equiv="ContentType:text/html;charset=utf-8" /> </head> <body> <h2>登录</h2> <% //模拟产生一个验证码,1234 session.setAttribute("validCode", "1234"); %> <form method="POST" action="${pageContext.request.contextPath}/login"> <div>${sessionScope['SPRING_SECURITY_LAST_EXCEPTION'].message} </div> 用户名:<input type="text" name="username"/> <br /> 密码:<input type="password" name="password" /> <br /> 验证码:<input type="text" name="validCode"> <br /> <input name="${_csrf.parameterName}" type="hidden" value="${_csrf.token}" /> <input type="submit" value="提交"/> </form> </body> </html>
其他几个只是为了查看测试结果的jsp页面,可以随便实现。
helloworld.jsp
<?xml version="1.0" encoding="UTF-8" ?> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Insert title here</title> </head> <body> hello , ${name} ! <hr /> <c:forEach var="item" items="${list}"> <div> <c:out value="${item }"></c:out> </div> </c:forEach> </body> </html>
userIndex.jsp
<?xml version="1.0" encoding="UTF-8" ?> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Insert title here</title> </head> <body> <div>welcom user!</div> </body> </html>
adminIndex.jsp
<?xml version="1.0" encoding="UTF-8" ?> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Insert title here</title> </head> <body> <div>welcom admin</div> </body> </html>
loginFailed.jsp
<?xml version="1.0" encoding="UTF-8" ?> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Insert title here</title> </head> <body> <div>login failed</div> </body> </html>
到这里算是把spring web mvc和spring security的部分都测通了,等后续有时间了,再向里面添加数据库连接的部分。
相关文章推荐
- jQuery plugin items filter
- java自动生成验证码插件-kaptcha
- 全国哀悼日网站页面变成灰色的filter方法
- 用css filter做鼠标滑过图片效果
- 如何识别高级的验证码的技术总结第1/4页
- WinForm生成验证码图片的方法
- PHP 验证码不显示只有一个小红叉的解决方法
- 一个简单安全的PHP验证码类 附调用方法
- ASP 使用Filter函数来检索数组的实现代码
- asp汉字中文图片验证码
- asp.net生成字母和数字混合图形验证码
- PHP实现简单汉字验证码
- php生成动态验证码gif图片
- php生成验证码函数
- 基于JavaScript短信验证码如何实现
- php 验证码制作(网树注释思想)
- 基于C#实现12306的动态验证码变成静态验证码的方法
- 理解C#生成验证码的过程
- C#验证码识别基础方法实例分析
- JavaScript 数组some()和filter()的用法及区别