spring security 一个验证码登录例子
2016-07-11 17:03
453 查看
看完shiro,在看spring security感觉快了很多,最开始看spring security的时候,非常晕,看完我觉得spring security做了太多事,以至于程序员都不知道,是怎么实现的,这样的
后果就是 当出现错误,或者需要修改的时候感觉无从下手。
个人理解,若有错误,请指正。
spring security跟shiro类似,都是使用过滤器来认证和授权,不同的是spring seciruty是实现了一个过滤器链,每个请求都要经过,我们可以使用自动配置,这样spring security自动帮我们配置了这一系列过滤器,也可以自定义过滤器放在它的过滤器链中。
验证码或密码登录,需要重新修改认证过滤器
package com.test.hello.security;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
public class KdUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{
private boolean postOnly = true;
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
if (this.postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
}
String username = obtainUsername(request);
String password = obtainPassword(request);
String type = request.getParameter("j_type");
if (username == null) {
username = "";
}
if (password == null) {
password = "";
}
if (type == null) {
type = "1";
}
username = username.trim();
Authentication authRequest;
if(type.equals("1")){
authRequest = new UsernamePasswordAuthenticationToken(username, password);
}else{
authRequest = new KdUsernamePasswordAuthenticationToken(username, password,type);
}
// Allow subclasses to set the "details" property
setDetails(request, (AbstractAuthenticationToken)authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
/**
* Provided so that subclasses may configure what is put into the authentication request's details
* property.
*
* @param request that an authentication request is being created for
* @param authRequest the authentication request object that should have its details set
*/
protected void setDetails(HttpServletRequest request, AbstractAuthenticationToken authRequest) {
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
}
}
type为2时候,使用验证码登录,token- >provider ->
token
package com.test.hello.security;
import java.util.Collection;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
public class KdUsernamePasswordAuthenticationToken extends AbstractAuthenticationToken{
//~ Instance fields ================================================================================================
/**
*
*/
private static final long serialVersionUID = 1L;
private final Object principal;
private Object credentials;
private String type;
//~ Constructors ===================================================================================================
/**
* This constructor can be safely used by any code that wishes to create a
* <code>UsernamePasswordAuthenticationToken</code>, as the {@link
* #isAuthenticated()} will return <code>false</code>.
*
*/
public KdUsernamePasswordAuthenticationToken(Object principal, Object credentials,String type) {
super(null);
this.principal = principal;
this.credentials = credentials;
this.type = type;
setAuthenticated(false);
}
/**
* This constructor should only be used by <code>AuthenticationManager</code> or <code>AuthenticationProvider</code>
* implementations that are satisfied with producing a trusted (i.e. {@link #isAuthenticated()} = <code>true</code>)
* authentication token.
*
* @param principal
* @param credentials
* @param authorities
*/
public KdUsernamePasswordAuthenticationToken(Object principal, Object credentials,String type, Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
this.credentials = credentials;
this.type = type;
super.setAuthenticated(true); // must use super, as we override
}
//~ Methods ========================================================================================================
public Object getCredentials() {
return this.credentials;
}
public Object getPrincipal() {
return this.principal;
}
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
if (isAuthenticated) {
throw new IllegalArgumentException(
"Once created you cannot set this token to authenticated. Create a new instance using the constructor which takes a GrantedAuthority list will mark this as authenticated.");
}
super.setAuthenticated(false);
}
@Override
public void eraseCredentials() {
super.eraseCredentials();
credentials = null;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
provider 重写了 密码校验方法,并且默认使用了KdJdbcDaoImpl去查询用户信息
KdAbstractUserDetailsAuthenticationProvider跟AbstractUserDetailsAuthenticationProvider一样仅仅改了authenticate方法里面的
Assert.isInstanceOf(KdUsernamePasswordAuthenticationToken.class,
package com.test.hello.security;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
public class KdDaoAuthenticationProvider extends KdAbstractUserDetailsAuthenticationProvider{
private UserDetailsService userDetailsService = new KdJdbcDaoImpl();
public UserDetailsService getUserDetailsService() {
return userDetailsService;
}
public void setUserDetailsService(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Override
public boolean supports(Class<?> authentication) {
return (KdUsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
}
@SuppressWarnings("deprecation")
@Override
protected void additionalAuthenticationChecks(UserDetails userDetails,
KdUsernamePasswordAuthenticationToken authentication)
throws AuthenticationException {
if (authentication.getCredentials() == null) {
logger.debug("Authentication failed: no credentials provided");
throw new BadCredentialsException(messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"), userDetails);
}
String presentedPassword
4000
= authentication.getCredentials().toString();
if (!userDetails.getPassword().equals(presentedPassword)) {
logger.debug("Authentication failed: password does not match stored value");
throw new BadCredentialsException(messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"), userDetails);
}else{
KdJdbcDaoImpl.userpass.remove(userDetails.getUsername());
}
}
@Override
protected UserDetails retrieveUser(String username,
KdUsernamePasswordAuthenticationToken authentication)
throws AuthenticationException {
UserDetails loadedUser;
try {
loadedUser = this.getUserDetailsService().loadUserByUsername(username);
} catch (UsernameNotFoundException notFound) {
throw notFound;
} catch (Exception repositoryProblem) {
throw new InternalAuthenticationServiceException(repositoryProblem.getMessage(), repositoryProblem);
}
if (loadedUser == null) {
throw new InternalAuthenticationServiceException(
"UserDetailsService returned null, which is an interface contract violation");
}
return loadedUser;
}
}
KdJdbcDaoImpl
package com.test.hello.security;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl;
public class KdJdbcDaoImpl extends JdbcDaoImpl{
public static ConcurrentHashMap<String,String> userpass = new ConcurrentHashMap<String, String>();
@Override
protected List<UserDetails> loadUsersByUsername(String username) {
List<UserDetails> list = new ArrayList<UserDetails>();
String password = userpass.get(username);
if(password != null){
list.add(new User(username, password, true, true, true, true, AuthorityUtils.NO_AUTHORITIES));
}
return list;
}
}
最后的配置
<security:http pattern="/resource/**" security="none"></security:http>
<security:http pattern="/index.jsp" security="none"></security:http>
<security:http pattern="/" security="none"></security:http>
<security:http pattern="/checkcode" security="none"></security:http>
<security:http entry-point-ref="loginUrlAuthenticationEntryPoint" >
<security:intercept-url pattern="/role/user**" access="ROLE_USER"/>
<security:intercept-url pattern="/role/admin**" access="ROLE_ADMIN"/>
<security:intercept-url pattern="/role/manager**" access="ROLE_MANAGER"/>
<security:custom-filter ref="kdUsernamePasswordAuthenticationFilter" position="FORM_LOGIN_FILTER"/>
<security:custom-filter ref="logoutFilter" position="LOGOUT_FILTER"/>
<security:access-denied-handler ref="accessDeniedHandlerImpl"/>
</security:http>
<bean id="accessDeniedHandlerImpl" class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<property name="errorPage" value="/errorPage.jsp"></property>
</bean>
<bean id="loginUrlAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<property name="loginFormUrl" value="/index.jsp"></property>
</bean>
<bean id="kdUsernamePasswordAuthenticationFilter" class="com.test.hello.security.KdUsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="org.springframework.security.authenticationManager"></property>
<property name="authenticationSuccessHandler" ref="savedRequestAwareAuthenticationSuccessHandler"></property>
<property name="authenticationFailureHandler" ref="simpleUrlAuthenticationFailureHandler"></property>
</bean>
<bean id="savedRequestAwareAuthenticationSuccessHandler" class="com.test.hello.security.KdSavedRequestAwareAuthenticationSuccessHandler">
<property name="defaultTargetUrl" value="/loginSuccess"></property>
</bean>
<bean id="simpleUrlAuthenticationFailureHandler" class="com.test.hello.security.KdSimpleUrlAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/index.jsp"></property>
</bean>
<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<property name="filterProcessesUrl" value="/logout"></property>
<constructor-arg index="0" >
<bean class="org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler">
<property name="defaultTargetUrl" value="/index.jsp"></property>
</bean>
</constructor-arg>
<constructor-arg index="1">
<array>
<bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"></bean>
</array>
</constructor-arg>
</bean>
<bean id="org.springframework.security.authenticationManager" name="authenticationManager" class="org.springframework.security.authentication.ProviderManager" >
<property name="authenticationEventPublisher" ref="defaultAuthenticationEventPublisher"></property>
<property name="providers">
<list>
<ref bean="daoAuthenticationProvider"/>
<ref bean="anonymousAuthenticationProvider"/>
<ref bean="kdDaoAuthenticationProvider"/>
</list>
</property>
</bean>
<bean id="defaultAuthenticationEventPublisher" class="org.springframework.security.authentication.DefaultAuthenticationEventPublisher"></bean>
<bean id="anonymousAuthenticationProvider" class="org.springframework.security.authentication.AnonymousAuthenticationProvider">
<property name="key" value="work"></property>
</bean>
<bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userService"></property>
<!-- <property name="passwordEncoder" ref="bcrypt"></property> -->
</bean>
<bean id="userService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="kdDaoAuthenticationProvider" class="com.test.hello.security.KdDaoAuthenticationProvider">
<property name="userDetailsService" ref="kdJdbcDaoImpl"></property>
</bean>
<bean id="kdJdbcDaoImpl" class="com.test.hello.security.KdJdbcDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
后果就是 当出现错误,或者需要修改的时候感觉无从下手。
个人理解,若有错误,请指正。
spring security跟shiro类似,都是使用过滤器来认证和授权,不同的是spring seciruty是实现了一个过滤器链,每个请求都要经过,我们可以使用自动配置,这样spring security自动帮我们配置了这一系列过滤器,也可以自定义过滤器放在它的过滤器链中。
验证码或密码登录,需要重新修改认证过滤器
package com.test.hello.security;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
public class KdUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{
private boolean postOnly = true;
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
if (this.postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
}
String username = obtainUsername(request);
String password = obtainPassword(request);
String type = request.getParameter("j_type");
if (username == null) {
username = "";
}
if (password == null) {
password = "";
}
if (type == null) {
type = "1";
}
username = username.trim();
Authentication authRequest;
if(type.equals("1")){
authRequest = new UsernamePasswordAuthenticationToken(username, password);
}else{
authRequest = new KdUsernamePasswordAuthenticationToken(username, password,type);
}
// Allow subclasses to set the "details" property
setDetails(request, (AbstractAuthenticationToken)authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
/**
* Provided so that subclasses may configure what is put into the authentication request's details
* property.
*
* @param request that an authentication request is being created for
* @param authRequest the authentication request object that should have its details set
*/
protected void setDetails(HttpServletRequest request, AbstractAuthenticationToken authRequest) {
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
}
}
type为2时候,使用验证码登录,token- >provider ->
token
package com.test.hello.security;
import java.util.Collection;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
public class KdUsernamePasswordAuthenticationToken extends AbstractAuthenticationToken{
//~ Instance fields ================================================================================================
/**
*
*/
private static final long serialVersionUID = 1L;
private final Object principal;
private Object credentials;
private String type;
//~ Constructors ===================================================================================================
/**
* This constructor can be safely used by any code that wishes to create a
* <code>UsernamePasswordAuthenticationToken</code>, as the {@link
* #isAuthenticated()} will return <code>false</code>.
*
*/
public KdUsernamePasswordAuthenticationToken(Object principal, Object credentials,String type) {
super(null);
this.principal = principal;
this.credentials = credentials;
this.type = type;
setAuthenticated(false);
}
/**
* This constructor should only be used by <code>AuthenticationManager</code> or <code>AuthenticationProvider</code>
* implementations that are satisfied with producing a trusted (i.e. {@link #isAuthenticated()} = <code>true</code>)
* authentication token.
*
* @param principal
* @param credentials
* @param authorities
*/
public KdUsernamePasswordAuthenticationToken(Object principal, Object credentials,String type, Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
this.credentials = credentials;
this.type = type;
super.setAuthenticated(true); // must use super, as we override
}
//~ Methods ========================================================================================================
public Object getCredentials() {
return this.credentials;
}
public Object getPrincipal() {
return this.principal;
}
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
if (isAuthenticated) {
throw new IllegalArgumentException(
"Once created you cannot set this token to authenticated. Create a new instance using the constructor which takes a GrantedAuthority list will mark this as authenticated.");
}
super.setAuthenticated(false);
}
@Override
public void eraseCredentials() {
super.eraseCredentials();
credentials = null;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
provider 重写了 密码校验方法,并且默认使用了KdJdbcDaoImpl去查询用户信息
KdAbstractUserDetailsAuthenticationProvider跟AbstractUserDetailsAuthenticationProvider一样仅仅改了authenticate方法里面的
Assert.isInstanceOf(KdUsernamePasswordAuthenticationToken.class,
package com.test.hello.security;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
public class KdDaoAuthenticationProvider extends KdAbstractUserDetailsAuthenticationProvider{
private UserDetailsService userDetailsService = new KdJdbcDaoImpl();
public UserDetailsService getUserDetailsService() {
return userDetailsService;
}
public void setUserDetailsService(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Override
public boolean supports(Class<?> authentication) {
return (KdUsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
}
@SuppressWarnings("deprecation")
@Override
protected void additionalAuthenticationChecks(UserDetails userDetails,
KdUsernamePasswordAuthenticationToken authentication)
throws AuthenticationException {
if (authentication.getCredentials() == null) {
logger.debug("Authentication failed: no credentials provided");
throw new BadCredentialsException(messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"), userDetails);
}
String presentedPassword
4000
= authentication.getCredentials().toString();
if (!userDetails.getPassword().equals(presentedPassword)) {
logger.debug("Authentication failed: password does not match stored value");
throw new BadCredentialsException(messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"), userDetails);
}else{
KdJdbcDaoImpl.userpass.remove(userDetails.getUsername());
}
}
@Override
protected UserDetails retrieveUser(String username,
KdUsernamePasswordAuthenticationToken authentication)
throws AuthenticationException {
UserDetails loadedUser;
try {
loadedUser = this.getUserDetailsService().loadUserByUsername(username);
} catch (UsernameNotFoundException notFound) {
throw notFound;
} catch (Exception repositoryProblem) {
throw new InternalAuthenticationServiceException(repositoryProblem.getMessage(), repositoryProblem);
}
if (loadedUser == null) {
throw new InternalAuthenticationServiceException(
"UserDetailsService returned null, which is an interface contract violation");
}
return loadedUser;
}
}
KdJdbcDaoImpl
package com.test.hello.security;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl;
public class KdJdbcDaoImpl extends JdbcDaoImpl{
public static ConcurrentHashMap<String,String> userpass = new ConcurrentHashMap<String, String>();
@Override
protected List<UserDetails> loadUsersByUsername(String username) {
List<UserDetails> list = new ArrayList<UserDetails>();
String password = userpass.get(username);
if(password != null){
list.add(new User(username, password, true, true, true, true, AuthorityUtils.NO_AUTHORITIES));
}
return list;
}
}
最后的配置
<security:http pattern="/resource/**" security="none"></security:http>
<security:http pattern="/index.jsp" security="none"></security:http>
<security:http pattern="/" security="none"></security:http>
<security:http pattern="/checkcode" security="none"></security:http>
<security:http entry-point-ref="loginUrlAuthenticationEntryPoint" >
<security:intercept-url pattern="/role/user**" access="ROLE_USER"/>
<security:intercept-url pattern="/role/admin**" access="ROLE_ADMIN"/>
<security:intercept-url pattern="/role/manager**" access="ROLE_MANAGER"/>
<security:custom-filter ref="kdUsernamePasswordAuthenticationFilter" position="FORM_LOGIN_FILTER"/>
<security:custom-filter ref="logoutFilter" position="LOGOUT_FILTER"/>
<security:access-denied-handler ref="accessDeniedHandlerImpl"/>
</security:http>
<bean id="accessDeniedHandlerImpl" class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<property name="errorPage" value="/errorPage.jsp"></property>
</bean>
<bean id="loginUrlAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<property name="loginFormUrl" value="/index.jsp"></property>
</bean>
<bean id="kdUsernamePasswordAuthenticationFilter" class="com.test.hello.security.KdUsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="org.springframework.security.authenticationManager"></property>
<property name="authenticationSuccessHandler" ref="savedRequestAwareAuthenticationSuccessHandler"></property>
<property name="authenticationFailureHandler" ref="simpleUrlAuthenticationFailureHandler"></property>
</bean>
<bean id="savedRequestAwareAuthenticationSuccessHandler" class="com.test.hello.security.KdSavedRequestAwareAuthenticationSuccessHandler">
<property name="defaultTargetUrl" value="/loginSuccess"></property>
</bean>
<bean id="simpleUrlAuthenticationFailureHandler" class="com.test.hello.security.KdSimpleUrlAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/index.jsp"></property>
</bean>
<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<property name="filterProcessesUrl" value="/logout"></property>
<constructor-arg index="0" >
<bean class="org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler">
<property name="defaultTargetUrl" value="/index.jsp"></property>
</bean>
</constructor-arg>
<constructor-arg index="1">
<array>
<bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"></bean>
</array>
</constructor-arg>
</bean>
<bean id="org.springframework.security.authenticationManager" name="authenticationManager" class="org.springframework.security.authentication.ProviderManager" >
<property name="authenticationEventPublisher" ref="defaultAuthenticationEventPublisher"></property>
<property name="providers">
<list>
<ref bean="daoAuthenticationProvider"/>
<ref bean="anonymousAuthenticationProvider"/>
<ref bean="kdDaoAuthenticationProvider"/>
</list>
</property>
</bean>
<bean id="defaultAuthenticationEventPublisher" class="org.springframework.security.authentication.DefaultAuthenticationEventPublisher"></bean>
<bean id="anonymousAuthenticationProvider" class="org.springframework.security.authentication.AnonymousAuthenticationProvider">
<property name="key" value="work"></property>
</bean>
<bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userService"></property>
<!-- <property name="passwordEncoder" ref="bcrypt"></property> -->
</bean>
<bean id="userService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="kdDaoAuthenticationProvider" class="com.test.hello.security.KdDaoAuthenticationProvider">
<property name="userDetailsService" ref="kdJdbcDaoImpl"></property>
</bean>
<bean id="kdJdbcDaoImpl" class="com.test.hello.security.KdJdbcDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <script type="text/javascript" src="resource/js/jquery.min.js"></script> <script type="text/javascript"> $(function(){ $("#jtypese").change(function(){ var v = $("#jtypese").val(); if(v=='2'){ var uname = $("#usernameinput").val(); var url = "<%=basePath%>checkcode?username="+uname; $.get(url,function(data,status){ alert("验证码: " + data + "\n发送状态: " + status); }); } }); }); </script> </head> <body> This is my login page. <br> <form action="j_spring_security_check" method="post"> <table> <tr><td>用户名:</td><td><input name="j_username" value="u1" id="usernameinput"></td></tr> <tr><td>密码/验证码:</td><td><input name="j_password" value="p1"></td></tr> <tr><td>登录方式: </td><td><select name="j_type" id="jtypese"><option value="1">密码</option><option value="2">验证码</option></select></td></tr> <tr><td colspan="2"> <input type="submit" value="submit"></td></tr> </table> </form> 异常: ${SPRING_SECURITY_LAST_EXCEPTION }<br> 失败次数: ${SPRING_SESSION_FAIL_TIMES } </body> </html>
相关文章推荐
- Java Set 排序
- java的文件操作(2)
- 【Java线程】Java线程池ExecutorService
- 质因数分解的简单例子
- javamail 发送邮件demo
- java的文件操作(1)
- 记录一下几个Eclipse插件安装地址
- Java查看动态代理生成的代码 in Action
- Java并发编程:Callable、Future和FutureTask
- Jmeter测试Java请求示例
- spring中@param和mybatis中@param使用区别
- Ubuntu 14.04 Trusty安装java环境
- Spring管理 hibernate 事务配置的五种方式
- Java Override和@Override
- springmvc+oscache 简单实例
- spring源码分析之spring-core-io
- java运行原理
- 初级Java开发电脑环境配置
- RxJava 详解
- Java标识符