spring mvc实现登录登录验证码怎么实现

您的位置: &
用Spring Security和JCaptcha整合技术实现验证码登录
优质期刊推荐spring(20)
看完shiro,在看spring security感觉快了很多,最开始看spring security的时候,非常晕,看完我觉得spring security做了太多事,以至于程序员都不知道,是怎么实现的,这样的
后果就是 当出现错误,或者需要修改的时候感觉无从下手。
个人理解,若有错误,请指正。
spring security跟shiro类似,都是使用过滤器来认证和授权,不同的是spring seciruty是实现了一个过滤器链,每个请求都要经过,我们可以使用自动配置,这样spring security自动帮我们配置了这一系列过滤器,也可以自定义过滤器放在它的过滤器链中。
验证码或密码登录,需要重新修改认证过滤器
package com.test.hello.
import javax.servlet.http.HttpServletR
import javax.servlet.http.HttpServletR
import org.springframework.security.authentication.AbstractAuthenticationT
import org.springframework.security.authentication.AuthenticationServiceE
import org.springframework.security.authentication.UsernamePasswordAuthenticationT
import org.springframework.security.core.A
import org.springframework.security.core.AuthenticationE
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationF
public class KdUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{
private boolean postOnly =
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 authR
if(type.equals(&1&)){
authRequest = new UsernamePasswordAuthenticationToken(username, password);
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 -&
package com.test.hello.
import java.util.C
import org.springframework.security.authentication.AbstractAuthenticationT
import org.springframework.security.core.GrantedA
public class KdUsernamePasswordAuthenticationToken extends AbstractAuthenticationToken{
//~ Instance fields ================================================================================================
private static final long serialVersionUID = 1L;
private final O
//~ 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 =
this.credentials =
this.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 =
this.credentials =
this.type =
super.setAuthenticated(true); // must use super, as we override
//~ Methods ========================================================================================================
public Object getCredentials() {
return this.
public Object getPrincipal() {
return this.
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);
public void eraseCredentials() {
super.eraseCredentials();
credentials =
public String getType() {
public void setType(String type) {
this.type =
provider 重写了& 密码校验方法,并且默认使用了KdJdbcDaoImpl去查询用户信息
KdAbstractUserDetailsAuthenticationProvider跟AbstractUserDetailsAuthenticationProvider一样仅仅改了authenticate方法里面的
&Assert.isInstanceOf(KdUsernamePasswordAuthenticationToken.class,
package com.test.hello.
import org.springframework.security.authentication.BadCredentialsE
import org.springframework.security.authentication.InternalAuthenticationServiceE
import org.springframework.security.core.AuthenticationE
import org.springframework.security.core.userdetails.UserD
import org.springframework.security.core.userdetails.UserDetailsS
import org.springframework.security.core.userdetails.UsernameNotFoundE
public class KdDaoAuthenticationProvider extends KdAbstractUserDetailsAuthenticationProvider{
private UserDetailsService userDetailsService = new KdJdbcDaoImpl();
public UserDetailsService getUserDetailsService() {
return userDetailsS
public void setUserDetailsService(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsS
public boolean supports(Class&?& authentication) {
return (KdUsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
@SuppressWarnings(&deprecation&)
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 = 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);
KdJdbcDaoImpl.userpass.remove(userDetails.getUsername());
protected UserDetails retrieveUser(String username,
KdUsernamePasswordAuthenticationToken authentication)
throws AuthenticationException {
UserDetails loadedU
loadedUser = this.getUserDetailsService().loadUserByUsername(username);
} catch (UsernameNotFoundException notFound) {
throw notF
} 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 loadedU
KdJdbcDaoImpl
package com.test.hello.
import java.util.ArrayL
import java.util.L
import java.util.concurrent.ConcurrentHashM
import org.springframework.security.core.authority.AuthorityU
import org.springframework.security.core.userdetails.U
import org.springframework.security.core.userdetails.UserD
import org.springframework.security.core.userdetails.jdbc.JdbcDaoI
public class KdJdbcDaoImpl extends JdbcDaoImpl{
public static ConcurrentHashMap&String,String& userpass = new ConcurrentHashMap&String, String&();
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));
最后的配置
&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 id=&loginUrlAuthenticationEntryPoint& class=&org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint&&
&property name=&loginFormUrl& value=&/index.jsp&&&/property&
&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 id=&savedRequestAwareAuthenticationSuccessHandler& class=&com.test.hello.security.KdSavedRequestAwareAuthenticationSuccessHandler&&
&property name=&defaultTargetUrl& value=&/loginSuccess&&&/property&
&bean id=&simpleUrlAuthenticationFailureHandler& class=&com.test.hello.security.KdSimpleUrlAuthenticationFailureHandler&&
&property name=&defaultFailureUrl& value=&/index.jsp&&&/property&
&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&
&/constructor-arg&
&constructor-arg index=&1&&
&bean class=&org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler&&&/bean&
&/constructor-arg&
&bean id=&org.springframework.security.authenticationManager& name=&authenticationManager& class=&org.springframework.security.authentication.ProviderManager& &
&property name=&authenticationEventPublisher& ref=&defaultAuthenticationEventPublisher&&&/property&
&property name=&providers&&
&ref bean=&daoAuthenticationProvider&/&
&ref bean=&anonymousAuthenticationProvider&/&
&ref bean=&kdDaoAuthenticationProvider&/&
&/property&
&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 id=&daoAuthenticationProvider& class=&org.springframework.security.authentication.dao.DaoAuthenticationProvider&&
&property name=&userDetailsService& ref=&userService&&&/property&
&property name=&passwordEncoder& ref=&bcrypt&&&/property& --&
&bean id=&userService& class=&org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl&&
&property name=&dataSource& ref=&dataSource&&&/property&
&bean id=&kdDaoAuthenticationProvider& class=&com.test.hello.security.KdDaoAuthenticationProvider&&
&property name=&userDetailsService& ref=&kdJdbcDaoImpl&&&/property&
&bean id=&kdJdbcDaoImpl& class=&com.test.hello.security.KdJdbcDaoImpl&&
&property name=&dataSource& ref=&dataSource&&&/property&
&%@ page language=&java& import=&java.util.*& pageEncoding=&UTF-8&%&
String path = request.getContextPath();
String basePath = request.getScheme()+&://&+request.getServerName()+&:&+request.getServerPort()+path+&/&;
&%@ taglib uri=&/jsp/jstl/core& prefix=&c&%&
&!DOCTYPE html PUBLIC &-//W3C//DTD HTML 4.01 Transitional//EN& &http://www.w3.org/TR/html4/loose.dtd&&
&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=&+
$.get(url,function(data,status){
alert(&验证码: & + data + &\n发送状态: & + status);
This is my login page. &br&
&form action=&j_spring_security_check& method=&post&&
&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&
异常: ${SPRING_SECURITY_LAST_EXCEPTION }&br&
失败次数:
${SPRING_SESSION_FAIL_TIMES }
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1095次
排名:千里之外
原创:36篇
(2)(14)(18)(6)(1)(1)用spring MVC、spring和 ibatis 如何实现登录验证 - 开源中国社区
当前访客身份:游客 [
当前位置:
jquery easyui和jsp完成登录页面,springMVC 管理页面属性获取及结果导向控制,spring负责各种Bean的创建和依赖注入,ibatis负责处理数据库的访问。登录验证的时候。我将从数据库获取数据 返回结果 转换成int型数据(1、用户名错误,2、密码错误),然后登录页面根据int数据弹框显示。我想用 jquery ui 中的Dialog来实现,但是不知道如何获取?
求大神讲解
共有9个答案
<span class="a_vote_num" id="a_vote_num_
使用shiro吧 &Shiro是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能
--- 共有 2 条评论 ---
搜 跟着开涛学习shiro
(1年前)&nbsp&
还没接触过spring-shiro,百度了解下shiro
(1年前)&nbsp&
<span class="a_vote_num" id="a_vote_num_
shiro是搞权限管理的吧,楼主是不是只是想验证的时候区分 不存在用户名 和 用户名或密码不正确 两种情况?现在一般是采用拿用户名+密码(不可逆加密)查询数据库,查出来允许登陆,否则就不允许登陆。查不出来的时候只提示 用户名或密码不正确,防止猜解帐号及密码。
如果要区分密码,可以返回json的数据,如返回map对象,map.put("code", 0);转成{code:0}传递给前端,前端解析,根据值做对应提示
<span class="a_vote_num" id="a_vote_num_
spring security 这个项目,或者shiro
--- 共有 1 条评论 ---
刚接触spring,我去查查spring security
(1年前)&nbsp&
<span class="a_vote_num" id="a_vote_num_
使用 ajax 吧,前端 js, 后端就是 spring+mvc .....
--- 共有 1 条评论 ---
这个做的不是想要异步刷新的效果。只是想有返回结果的时候弹框
(1年前)&nbsp&
<span class="a_vote_num" id="a_vote_num_
这是毛关系
--- 共有 1 条评论 ---
我是菜鸟,描述的不清楚 勿喷
(1年前)&nbsp&
<span class="a_vote_num" id="a_vote_num_
这是毛关系+1
--- 共有 1 条评论 ---
我是菜鸟,描述的不是挺清楚 勿喷
(1年前)&nbsp&
<span class="a_vote_num" id="a_vote_num_
这是毛关系+2
<span class="a_vote_num" id="a_vote_num_
上Shiro吧,挺简单的。
<span class="a_vote_num" id="a_vote_num_
按照你说的,直接ajax ,判断返回,不就OK了,这和你后台使用的技术spring,ibatis,有毛关系
更多开发者职位上
有什么技术问题吗?
类似的话题二次元同好交流新大陆
扫码下载App
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
阅读(3284)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'在spring security3上实现验证码',
blogAbstract:'验证码与SS3结合的实现方案方案一:自己写个filter严格来讲,这不是与SS3结合,而只是在项目中实现一个filter,然后将其拦截次序放在SS3的filter前面即可。这样做的好处是简单且通 用,以后不玩SS3了,也可以使用。缺点也很明显,那就是在SS3中配置的一应事物都要重新配置,例如拦截的URL、失败的URL、报错的资源文件、异常 后的重定向设置等等。方案二:定制一个新的SS3的filter通过在&http&中声明一个&custom-filter&,设置其\"before\"属性,让它 在\"FORM_LOGIN_FILTER\"前作拦截即可。这样做看上去更集中、直观,对SS3的&http&元素的默认设置改变也很小,但是 和方法一相似,还是要配置很多事物,写很多的基础代码。方案三:扩展UsernamePasswordAuthenticationFilter',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:6,
publishTime:2,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'1',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}}

我要回帖

更多关于 spring 实现验证码 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信