spring security密码验证

2019-04-09  本文已影响0人  莫思闲敏

今天开始做SSM项目,建好表之后,开始做登录功能,项目是从上个项目直接移植过来的

言归正传

<form action="/login" method="post" id="loginForm">

这里是使用的表单提交的方式进行的, 所以我ctrl+h 搜索了一下

就找到了这2个地方,貌似也不对,后来就问了一下,以前是怎么登录登录的,各位不要见笑,本人以前是做android的,被拉来做临时工的

必须要在接口里继承UserDetailsService类,实现UserDetails loadUserByUsername(String username) throws UsernameNotFoundException的方法  如下所示

你没有看错,只有一个用户名,或是只是一个参数,但是丝毫没有体现出密码,所以本着工匠精神直接debug运行下去

只要是用户名或是电话号码正确,都能查询出用户数据,但是出抛出“账户或密码错误,请重试”的错误提示。所示输入一个错误的密码继续debug。

第1步,先搜索“账户或密码错误,请重试”错误提示信息。只搜索到一处

    是继承了DaoAuthenticationProvider的自定义的验证提供类

第2步 点击super.authenticate(authentication),进入源码

    这个类有点长 

    public abstract class AbstractUserDetailsAuthenticationProvider implements AuthenticationProvider, InitializingBean, MessageSourceAware {

              public Authentication authenticate(Authentication authentication)  throws AuthenticationException {

      Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class, authentication, messages.getMessage(

"AbstractUserDetailsAuthenticationProvider.onlySupports",

"Only UsernamePasswordAuthenticationToken is supported"));

// Determine username

String username = (authentication.getPrincipal() == null) ? "NONE_PROVIDED"

: authentication.getName();

boolean cacheWasUsed = true;

UserDetails user = this.userCache.getUserFromCache(username);

if (user == null) {

cacheWasUsed = false;

try {

user = retrieveUser(username,

(UsernamePasswordAuthenticationToken) authentication);

}

catch (UsernameNotFoundException notFound) {

logger.debug("User '" + username + "' not found");

if (hideUserNotFoundExceptions) {

throw new BadCredentialsException(messages.getMessage(

"AbstractUserDetailsAuthenticationProvider.badCredentials",

"Bad credentials"));

}

else {

throw notFound;

}

}

Assert.notNull(user,

"retrieveUser returned null - a violation of the interface contract");

}

try {

preAuthenticationChecks.check(user);

additionalAuthenticationChecks(user,

(UsernamePasswordAuthenticationToken) authentication);

}

catch (AuthenticationException exception) {

if (cacheWasUsed) {

// There was a problem, so try again after checking

// we're using latest data (i.e. not from the cache)

cacheWasUsed = false;

user = retrieveUser(username,

(UsernamePasswordAuthenticationToken) authentication);

preAuthenticationChecks.check(user);

additionalAuthenticationChecks(user,

(UsernamePasswordAuthenticationToken) authentication);

}

else {

throw exception;

}

}

postAuthenticationChecks.check(user);

if (!cacheWasUsed) {

this.userCache.putUserInCache(user);

}

Object principalToReturn = user;

if (forcePrincipalAsString) {

principalToReturn = user.getUsername();

}

return createSuccessAuthentication(principalToReturn, authentication, user);

}

}

太长了,不要看 ,我们看关键的代码

try {

     user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication);

}

user加载出来之后的数据

UserSession@763b173e: Username: 13000000000; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Not granted any authorities

additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken) authentication); 进入实现类源码

public class DaoAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {

@SuppressWarnings("deprecation")

protected void additionalAuthenticationChecks(UserDetails userDetails,

UsernamePasswordAuthenticationToken authentication)

throws AuthenticationException {

Object salt = null;

if (this.saltSource != null) {

salt = this.saltSource.getSalt(userDetails);

}

if (authentication.getCredentials() == null) {

logger.debug("Authentication failed: no credentials provided");

throw new BadCredentialsException(messages.getMessage(

"AbstractUserDetailsAuthenticationProvider.badCredentials",

"Bad credentials"));

}

String presentedPassword = authentication.getCredentials().toString();

if (!passwordEncoder.isPasswordValid(userDetails.getPassword(),

presentedPassword, salt)) {

logger.debug("Authentication failed: password does not match stored value");

throw new BadCredentialsException(messages.getMessage(

"AbstractUserDetailsAuthenticationProvider.badCredentials",

"Bad credentials"));

}

}

在这里验证密码,密码不对就会抛出异常。

开始只是知道登录框架已经帮我们实现了,但是不知道spring security这个框架,第一次使用,也不知道它的原理,更加不知道它是如何运行,不过现在知道的是,先查询出数据,再匹配密码是如正确。

但是又有一个疑问,为什么知道我的密码字段是password,我改成aabbcc试了试也可以

return new UserSession(record.getAccount(),record.getAabbcc(),authorities,record)  猜测是不是这里验证,把record.getAabbcc()改成其它的试试,我改成了record.getMobile() 也可以,真是奇怪

把jsp中的密码框改下

<input type="password2" name="password2" id="password2" class="form-control" placeholder="密码">

效果达到了,无论输入什么值都登录不上

原来是获取这里的值,但是它是怎么知道要与我数据库中的aabbcc对比的呢?有知道的可以告知下,谢谢!

上一篇下一篇

猜你喜欢

热点阅读