首页 > 解决方案 > Spring Security 基本身份验证总是得到 401

问题描述

我学习 Spring,并将 Spring 安全性集成到我当前的 API 中。为了简单起见,我从基本身份验证开始。

但是,我面临的问题是,如果我不提供凭据,我会得到标准的 401 以及 JSON 响应:

{
    "timestamp": "2018-07-07T18:40:00.752+0000",
    "status": 401,
    "error": "Unauthorized",
    "message": "Unauthorized",
    "path": "/courses"
}

但如果我确实通过了正确的凭据,我会得到 401,但没有任何响应正文。

这是我的WebSecurityConfiguration

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
  @Autowired
  DetailsService detailsService;

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(detailsService)
        .passwordEncoder(User.encoder);
  }

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

这是我的DetailsService

@Component
public class DetailsService implements UserDetailsService {

  @Autowired
  private UserRepository userRepository;

  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    User user = userRepository.findByEmail(username);
    if (user == null) {
      throw new UsernameNotFoundException("User with email " + username + " was not found");
    }
    return new org.springframework.security.core.userdetails.User(
        user.getEmail(),
        user.getPassword(),
        AuthorityUtils.createAuthorityList(user.getRoles())
    );
  }
}

我应该指出这一点,我正在通过电子邮件而不是用户名查找用户。

这是我的用户实体:

@Entity
@Table(name = "users")
public class User extends BaseEntity {
  public static final PasswordEncoder encoder = new BCryptPasswordEncoder();

  @Column(name = "first_name")
  private String firstName;
  @JoinColumn(name = "last_name")
  private String lastName;
  private String email;
  @JsonIgnore
  private String password;
  @JsonIgnore
  private String[] roles;

  public User(String email, String firstName, String lastName, String password,
      String[] roles) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.email = email;
    setPassword(password);
    this.roles = roles;
  }

// getters and setters
}

标签: spring-bootspring-security

解决方案


第一:检查user.getRoles()是不是扔了一个LazyInitializationException

第二:如果已经在线生成hash,BCryptPasswordEncoder 可能不起作用


推荐阅读