3

I learning Spring, and I integrated Spring security into my current APIs. To keep things simple, I am starting with Basic Auth.

However, the issue that I am facing is that, if I don't provide the credentials, I get the standard 401 along with a JSON response:

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

But if I do pass correct credentials, I get 401, but without any response body.

Here's my 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();
  }
}

Here's my 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())
    );
  }
}

I should point this out that I am looking up user by email instead of username.

Here's my user entity:

@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
}
relentless-coder
  • 1,478
  • 3
  • 20
  • 39

1 Answers1

0

First: check that user.getRoles() is not throwing a LazyInitializationException

Second: if hash has been generated online, BCryptPasswordEncoder might not work