春季安全认证

Posted

技术标签:

【中文标题】春季安全认证【英文标题】:Spring Security Authentication 【发布时间】:2019-02-04 11:05:09 【问题描述】:

我无法在 Spring 中使用 MongoDB 的 Spring Security 进行身份验证。

实体:

@Document(collection = "users")
public class Users 

    @Id
    private String id;
    private String username;
    private String email;
    private String password;
    private List<Notification> preferences;


    public Users(String username, String email, String password, List<Notification> preferences) 
        this.username = username;
        this.email = email;
        this.password = password;
        this.preferences = preferences;
    

    public String getUsername() 
        return username;
    

    public void setUsername(String username) 
        this.username = username;
    

    public String getEmail() 
        return email;
    

    public void setEmail(String email) 
        this.email = email;
    

    public String getPassword() 
        return password;
    

    public void setPassword(String password) 
        this.password = password;
    

    public List<Notification> getPreferences() 
        return preferences;
    

    public void setPreferences(List<Notification> preferences) 
        this.preferences = preferences;
    

服务:

@Component
public class MongoUserDetailsService implements UserDetailsService 

    @Autowired
    private UserRepository repository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException 
        Users user = repository.findByUsername(username);

        if(user == null) 
            throw new UsernameNotFoundException("User not found");
        

        List<SimpleGrantedAuthority> authorities = Arrays.asList(new SimpleGrantedAuthority("user"));

        return new User(user.getUsername(), user.getPassword(), authorities);
    

存储库:

import com.example.Start.entities.Users;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends MongoRepository<Users, String> 
    Users findByUsername(String username);

配置:

    @Configuration
    @EnableConfigurationProperties
    public class SecurityConfiguration extends WebSecurityConfigurerAdapter 

        @Autowired
        MongoUserDetailsService userDetailsService;

        @Override
        protected void configure(HttpSecurity http) throws Exception 
            http
                    .csrf().disable()
                    .authorizeRequests().anyRequest().authenticated()
                    .and().httpBasic()
                    .and().sessionManagement().disable();
        

        @Bean
        public PasswordEncoder passwordEncoder() 
            return new BCryptPasswordEncoder();
        

        @Override
        public void configure(AuthenticationManagerBuilder builder) throws Exception 
            builder.userDetailsService(userDetailsService);
        
    

当我尝试进行身份验证时,它给了我这个: enter image description here

在我的数据库中,我有这个用户:


    "_id" : ObjectId("5b855813d03cce0264de3ab6"),
    "username" : "username",
    "email" : "test@test.com",
    "password" : "123"

知道是什么原因造成的吗?

【问题讨论】:

【参考方案1】:

问题是您已将BCryptPasswordEncoder 注册为passwordEncoder bean,但您已将密码以明文形式存储在数据库中。现在,当身份验证发生时,它正在使用 BCrypt 算法对来自 HTTP 请求的传入密码进行编码,并将其与显然会失败的明文密码进行比较。这就是为什么你得到“编码密码不像 BCrypt”,因为它不是。

简短的解决方法是将您的 mongodb 用户记录编辑为具有用户名“用户名”的用户的密码字段具有以下值,如下所示:


    "_id" : ObjectId("5b855813d03cce0264de3ab6"),
    "username" : "username",
    "email" : "test@test.com",
    "password" : "$2a$10$pIUUIHClmGYBnsJzlOHQkeecSwRGAgYlxzRfBFjEqhk6rkQdilTYC"

当您使用 BCrypt 算法对字符串“123”进行编码时,您将得到“$2a$10$pIUUIHClmGYBnsJzlOHQkeecSwRGAgYlxzRfBFjEqhk6rkQdilTYC”。

但正确的解决方法是在将密码保存到应用程序中的 Mongo 数据库之前添加代码以对密码进行编码,如下所示:

@Autowired
private PasswordEncoder passwordEncoder;

public void saveUser(Users user) 
    user.setPassword(passwordEncoder.encoder(user.getPassword()));
    // Save in mongodb

【讨论】:

以上是关于春季安全认证的主要内容,如果未能解决你的问题,请参考以下文章

春季安全动态角色

春季安全 mysuccessHandler

春季安全会话超时

春季安全会话到期

在春季安全中注销特定会话ID

春季安全会话超时