spring boot security dao 身份验证 - 权限已删除

Posted

技术标签:

【中文标题】spring boot security dao 身份验证 - 权限已删除【英文标题】:spring boot security dao authentication - authorities removed 【发布时间】:2018-03-31 23:23:00 【问题描述】:

开发一个 Spring Boot 应用程序,实现基于 Spring Boot Security 基本身份验证数据库的安全性。已实现 UserDetailsS​​ervice 并覆盖 loadUserByUsername 方法。单步执行该方法,我发现从我的数据库用户表中成功检索到用户名、密码和角色信息。

我的 UserDetailsS​​ervice loadUserByUsername 代码是

  @Override
public UserDetails loadUserByUsername(String userName)
        throws UsernameNotFoundException 
    UserInfo activeUserInfo = userInfoDAO.getActiveUser(userName);
    SimpleGrantedAuthority authority = new SimpleGrantedAuthority(activeUserInfo.getRole());
    User(activeUserInfo.getUserName(),
            activeUserInfo.getPassword(), Arrays.asList(authority));
    return userDetails;

回到 DaoAUthenticationProvider retrieveUser 包含从用户表查找返回的值,但 AbstractUserDetailsAuthenticationProvider 身份验证方法显示权限是零长度数组,用户名和密码正确返回。没有权限值会导致返回 401 bad credentials 错误。

我正在使用邮递员进行测试。使用 mysql 5.7.11 和使用此定义的用户表:

  CREATE TABLE IF NOT EXISTS `users` (
  `username` varchar(50) NOT NULL,
  `password` varchar(100) NOT NULL,
  `full_name` varchar(100) NOT NULL,
  `role` varchar(50) NOT NULL,
  `country` varchar(100) NOT NULL,
  `enabled` tinyint(1) NOT NULL,
  PRIMARY KEY (`username`)
);

密码使用 BCryptPasswordEncoder 存储,并通过邮递员以纯文本形式发送。

我的 application.properties 定义为:

    spring.datasource.url=jdbc:mysql://localhost:3306/actotracker?useSSL=false
spring.datasource.username=root
spring.datasource.password=Dial0gicRots
spring.datasource.tomcat.max-wait=20000
spring.datasource.tomcat.max-active=50
spring.datasource.tomcat.max-idle=20
spring.datasource.tomcat.min-idle=15
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect
spring.jpa.properties.hibernate.id.new_generator_mappings = false
spring.jpa.properties.hibernate.format_sql = true
security.basic.enabled=true
security.basic.realm=Spring
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

已尝试在不影响结果的情况下手动将权限值设置为“ROLE_ADMIN”。指出我做错了什么?

Java 版本 1.8 Spring Boot 1.5.3.RELEASE

我注册密码编码器的代码:

  private final Logger log = LoggerFactory.getLogger(MyApplication.class);
@Autowired
private AppUserDetailService appUserDetailsService;
@Autowired
private AppAuthenticationEntryPoint appAuthenticationEntryPoint;
@Override
protected void configure(HttpSecurity http) throws Exception 
    log.info("In configure");
    http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/user/**").hasAnyRole("ROLE_ADMIN","ROLE_USER")
            .and().httpBasic().realmName("Spring")
         //   .and().httpBasic()
            .authenticationEntryPoint(appAuthenticationEntryPoint);

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception 
    log.info("configGlobal");
    BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    auth.userDetailsService(appUserDetailsService).passwordEncoder(passwordEncoder);

邮递员价值观: http://localhost:8080/user/distances 用户名字段:tim 密码:纯文本密码值 身份验证设置为基本身份验证

【问题讨论】:

进一步调试了代​​码。 AbstractUserDetailsAuthenticationProvider 的 isPasswordValid 检查中的 additionalAuthenticationChecks 失败。是否评估了提出的密码和 userDetails.getPassword() 并且值匹配。 salt 值为 null。 【参考方案1】:

dur 是正确的,401 是由密码不匹配引起的。我编写了一个小程序来获取纯文本字符串并将其加密。 `

        String creds = "xxxxxxx";       
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String encPassword = bCryptPasswordEncoder.encode(creds);

我在我的用户身份验证表中使用/存储了 encPassword 值。

进入 BCryptPasswordEncoder 类 BCrypt.checkpw,我发现我的原始文本字符串被转换为不同的加密值。使用新的加密值更新了我的数据库用户表条目,我的授权成功。

【讨论】:

以上是关于spring boot security dao 身份验证 - 权限已删除的主要内容,如果未能解决你的问题,请参考以下文章

spring boot mybaits dao层配置

Spring Security:针对多个 LDAP 服务器和基于 DAO 的身份验证进行身份验证

spring boot DAO之jdbcTemplate

spring boot DAO之Hibernate

spring boot DAO之Mybatis

Spring Security with Boot