Spring Security 登录时总是返回 401

huangapple go评论53阅读模式
英文:

Spring Security always returns 401 when logging in

问题

我是Java和Spring的新手。

每次我向服务器发送包含已存在于我的数据库中的用户详细信息的POST请求时,我总是收到401未经授权的响应,我不确定原因。

安全配置

@Configuration
@EnableWebSecurity
public class SecurityConfiguration {

    @Autowired
    AuthUserService authUserService;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.headers().frameOptions().disable();

        http.httpBasic().authenticationEntryPoint(new BasicAuthenticationEntryPoint());

        http.authorizeHttpRequests()
            .requestMatchers(HttpMethod.POST, "/api/v1/login").authenticated()
            .and()
            .authorizeHttpRequests().anyRequest().permitAll();

        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        return http.build();
    }

    protected void configure (AuthenticationManagerBuilder auth) throws Exception{
        auth.userDetailsService(authUserService).passwordEncoder(passwordEncoder());
    }

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

注意:上面的代码是Java和Spring的一部分,不进行翻译。

英文:

I am new to Java and Spring.

Every-time I send a post request to my server with the details of a user that already exists in my database I always get a 401 unauthorised response and I am not sure why.

Security Configuration

@Configuration
@EnableWebSecurity
public class SecurityConfiguration {

@Autowired
AuthUserService authUserService;


@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http.csrf().disable();
    http.headers().frameOptions().disable();

    http.httpBasic().authenticationEntryPoint(new BasicAuthenticationEntryPoint());

    http.authorizeHttpRequests()
        .requestMatchers(HttpMethod.POST, "/api/v1/login").authenticated()
        .and()
        .authorizeHttpRequests().anyRequest().permitAll();

    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

    return http.build();
}

protected void configure (AuthenticationManagerBuilder auth) throws Exception{
    auth.userDetailsService(authUserService).passwordEncoder(passwordEncoder());
}

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

}

答案1

得分: 0

以下是翻译好的部分:

如果您正在使用来自数据库的用户凭据进行登录,那么您必须使用 DaoAuthenticationProvider,这样 Spring Security 才能知道它必须将您输入的凭据与数据库凭据进行匹配以进行登录。

然后,您需要使用 UserDetailsService 接口从数据库加载用户,然后 Spring Security 将匹配凭据并授予访问权限。

请将以下代码添加到您的 SecurityConfiguration 类中。

@Resource
private UserDetailsService userDetailsService;

@Bean
public DaoAuthenticationProvider authProvider() {
    DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
    authProvider.setUserDetailsService(userDetailsService);
    authProvider.setPasswordEncoder(passwordEncoder());
    return authProvider;
}

然后,您需要创建 UserDetailServiceImpl 类来实现 UserDetailService 接口。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Users user1 = userRepository.findByEmail(username);
        if (user1 is null) {
            throw new UsernameNotFoundException(username);
        }

        UserDetails user = User
            .withUsername(user1.getName())
            .password(user1.getPassword())
            .build();

        return user;
    }
}

如果您的项目中使用了 Spring Data JPA,并且您已经扩展了 JpaRepositoryCrudRepository 以及 UserRepository,并且您在 UserRepository 中有 findByEmail 方法,那么这将起作用。

如果您想了解如何使用 Spring Data JPA 以及如何使用数据库值执行登录的更多信息,请在评论中提出。

英文:

If you are using user credential from database to login then you have to use DaoAuthenticationProvider then only Spring Security get to know it have to match your entered credentials with database credential for login.

Then for that you have to use UserDetailsService interface to load the user from database and then Spring Security will match the credential and give the access.

Mention below code in your SecurityConfiguration class.

<!-- language: java -->

@Resource
private UserDetailsService userDetailsService;

@Bean
public DaoAuthenticationProvider authProvider() {
    DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
    authProvider.setUserDetailsService(userDetailsService);
    authProvider.setPasswordEncoder(passwordEncoder());
    return authProvider;
}

Then you have to create UserDetailServiceImpl class to implements UserDetailService interface.

<!-- language: java -->

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Users user1 = userRepository.findByEmail(username);
        if (user1 == null) {
            throw new UsernameNotFoundException(username);
        }

        UserDetails user = User
            .withUsername(user1.getName())
            .password(user1.getPassword())
            .build();

        return user;
    }
}

This will work if you are using Spring Data JPA in your project and you have extended JpaRepository or CrudRepository with UserRepository and you have findByEmail method in UserRepository.

If you want more information how to use Spring Data JPA and how to perform login using database values comment on this.

huangapple
  • 本文由 发表于 2023年4月4日 03:19:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/75923046.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定