前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >spring secutiry密码验证的另一种解决办法(荐)

spring secutiry密码验证的另一种解决办法(荐)

作者头像
星痕
发布2018-09-12 12:20:47
8580
发布2018-09-12 12:20:47
举报
文章被收录于专栏:JAVA后端开发

最近在集成sping security 到spring boot中,看到大部分登陆验证的代码都这么写

代码语言:javascript
复制
@Service
public class CustomUserService implements UserDetailsService { //自定义UserDetailsService 接口

    @Autowired
    UserDao userDao;
    @Autowired
    PermissionDao permissionDao;

    public UserDetails loadUserByUsername(String username) {
        SysUser user = userDao.findByUserName(username);
        if (user != null) {
            List<Permission> permissions = permissionDao.findByAdminUserId(user.getId());
            List<GrantedAuthority> grantedAuthorities = new ArrayList <>();
            for (Permission permission : permissions) {
                if (permission != null && permission.getName()!=null) {

                GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(permission.getName());
                grantedAuthorities.add(grantedAuthority);
                }
            }
            return new User(user.getUsername(), user.getPassword(), grantedAuthorities);
        } else {
            throw new UsernameNotFoundException("admin: " + username + " do not exist!");
        }
    }

}

然后配置那时的代码为:

代码语言:javascript
复制
 @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(urlUserService).passwordEncoder(new PasswordEncoder() {

            @Override
            public String encode(CharSequence rawPassword) {
                return MD5Util.encode((String) rawPassword);
            }

            @Override
            public boolean matches(CharSequence rawPassword, String encodedPassword) {
                return encodedPassword.equals(MD5Util.encode((String) rawPassword));
            }
        });
    }

看到以上代码,我就有个疑问了。 loadUserByUsername是为什么要把用户的权限也获取了呢,如果密码不正确,那获取的权限也没有用,浪费性能。 个人调试了一下代码,发现登陆验证时,确实会调用到loadUserByUsername。 那怎么办呢?如何解决。 经查,解决办法如下; 1.不使用UserDetailsService,改为使用AbstractUserDetailsAuthenticationProvider 示例代码如下:

代码语言:javascript
复制
public class MucAppAuthenticationProvider extends
        AbstractUserDetailsAuthenticationProvider {
    private static Logger logger = LoggerFactory.getLogger(AbstractUserDetailsAuthenticationProvider.class);

    @Autowired
    SecurityUserService securityUserService;

    @Override
    protected void additionalAuthenticationChecks(UserDetails userDetails,
                                                  UsernamePasswordAuthenticationToken authentication)
            throws AuthenticationException {
        //如果想做点额外的检查,可以在这个方法里处理,校验不通时,直接抛异常即可
    }

    @Override
    protected UserDetails retrieveUser(String username,
                                       UsernamePasswordAuthenticationToken authentication)
            throws AuthenticationException {
        //获取用户权限或密码校验
        return loadUserDetail(username);
    }

    
    
}

2.配置WebSecurityConfigurer改为如下:

代码语言:javascript
复制
@Bean
    AppAuthenticationProvider appAuthenticationProvider() { // 注册UserDetailsService 的bean
        return new AppAuthenticationProvider();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
         auth.authenticationProvider(appAuthenticationProvider());
    }

经测试,登陆验证没有发现任何问题

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018.03.01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档