美文网首页
spring security密码验证

spring security密码验证

作者: 莫思闲敏 | 来源:发表于2019-04-09 18:36 被阅读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对比的呢?有知道的可以告知下,谢谢!

    相关文章

      网友评论

          本文标题:spring security密码验证

          本文链接:https://www.haomeiwen.com/subject/rsjiiqtx.html