在 Spring Security 6 中未调用 userDetailsService

问题描述 投票:0回答:1

我正在尝试使用 spring security 6 将身份验证应用于 springboot 应用程序,但是当我创建 AuthenticationProvider 的 bean 并将其添加到 filterChain 时,应用程序停止运行。否则,应用程序似乎正在启动。

目前我已允许所有路线用于测试目的。

SecurityConfig.java

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

@Autowired
private UserService userDetailsService;

@Autowired
private BCryptPasswordEncoder encoder;



@Bean
public AuthenticationProvider authenticationProvider() {
    DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
    daoAuthenticationProvider.setUserDetailsService(userDetailsService);
    daoAuthenticationProvider.setPasswordEncoder(encoder);
    return daoAuthenticationProvider;

}

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .cors((cors) -> cors.configurationSource(apiConfigurationSource()))
        .csrf(csrf -> csrf.ignoringRequestMatchers("**"))
        .authorizeHttpRequests(authorize -> authorize
            .requestMatchers("**").permitAll()
            .anyRequest().authenticated()
        )
        .authenticationProvider(authenticationProvider())
        .httpBasic(Customizer.withDefaults());
    return http.build();
}

}

UserService.java

@Service
@RequiredArgsConstructor
public class UserService implements UserDetailsService{

@Autowired
UserRepoImpl userRepoImpl;

final PasswordEncoder passwordEncoder;
final JwtService jwtService;
final AuthenticationManager authenticationManager;
final UserDetailsService userDetailsService;


@Autowired
private PasswordEncoder encoder;

Integer getSessionDuration(RegisterUser user) {
    long sessionDuration = GlobalVariablesBackend.getRoleDuration(user.getRole());
    Integer intVal = Math.toIntExact(sessionDuration);
    return intVal;
}

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException 
{
    System.out.println("in user details service -> "+username);
    RegisterUser user = userRepoImpl.findByUsername(username);
    
    String jwtToken = jwtService.generateToken(user, user.getRole());
    
    AuthenticationResponse authResponse = new AuthenticationResponse();
    authResponse.setEmail(user.getEmail());
    authResponse.setRole(user.getRole());
    authResponse.setSessionDuration(getSessionDuration(user));
    authResponse.setToken(jwtToken);
    authResponse.setUsername(username);
    
    return authResponse;
}

}

注册用户.java

@Entity
@Table(name = "pushcode_users")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class RegisterUser implements UserDetails{


@Id
@NotNull
@Email
@Column(unique=true)
String email;

@NotNull
String password;


@Column(name="created_date")
@CreationTimestamp
LocalDateTime createdDate;

@Column(name="last_login")
@UpdateTimestamp
LocalDateTime lastLogin;

@Enumerated(EnumType.STRING)
Role role;

@NotNull
@Column(name="username")
String username;

@Transient
String confirmPassword;

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
    return List.of(new SimpleGrantedAuthority(role.name()));
}

@Override
public String getUsername() {
    return email;
}

@Override
public boolean isAccountNonExpired() {
    return true;
}

@Override
public boolean isAccountNonLocked() {
    return true;
}

@Override
public boolean isCredentialsNonExpired() {
    return true;
}

@Override
public boolean isEnabled() {
    return true;
}

}

身份验证响应

@Data
@AllArgsConstructor
@NoArgsConstructor
public class AuthenticationResponse extends RegisterUser{

@JsonProperty(access = Access.WRITE_ONLY)
private String token;
private Role role;
private String username;
private String email;
private Integer sessionDuration;

}

根据我的理解,需要验证的路由将被发送到 AuthenticationProvider,后者调用 UserService 中实现的 loadUserByUsername。 RegisterUser 是 UserDetails 的 DAO,AuthenticationResponse 是 DTO。

非常感谢有关此事的任何帮助或建议。

spring spring-boot spring-mvc spring-security
1个回答
0
投票

您的实施存在几个问题,请参考此内容,如果您仍然遇到问题,请告诉我 -

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final UserService userDetailsService;
    private final BCryptPasswordEncoder encoder;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .cors().configurationSource(apiConfigurationSource())
            .and()
            .csrf().ignoringRequestMatchers("**")
            .and()
            .authorizeRequests(authorize -> authorize
                .antMatchers("**").permitAll()
                .anyRequest().authenticated()
            )
            .httpBasic(withDefaults());
    }

    @Bean
    public CorsConfigurationSource apiConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.addAllowedOrigin("*");
        configuration.addAllowedMethod("*");
        configuration.addAllowedHeader("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider());
    }

    @Bean
    public AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setUserDetailsService(userDetailsService);
        daoAuthenticationProvider.setPasswordEncoder(encoder);
        return daoAuthenticationProvider;
    }
}

@Service
@RequiredArgsConstructor
public class UserService implements UserDetailsService {

    private final UserRepoImpl userRepoImpl;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        RegisterUser user = userRepoImpl.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("User not found with username: " + username);
        }
        return new org.springframework.security.core.userdetails.User(
                user.getUsername(),
                user.getPassword(),
                user.getAuthorities()
        );
    }
}

@Data
@Entity
@Table(name = "pushcode_users")
@AllArgsConstructor
@NoArgsConstructor
public class RegisterUser implements UserDetails {

    @Id
    @NotNull
    @Email
    @Column(unique = true)
    private String email;

    @NotNull
    private String password;

    @Column(name = "created_date")
    @CreationTimestamp
    private LocalDateTime createdDate;

    @Column(name = "last_login")
    @UpdateTimestamp
    private LocalDateTime lastLogin;

    @Enumerated(EnumType.STRING)
    private Role role;

    @NotNull
    @Column(name = "username")
    private String username;

    @Transient
    private String confirmPassword;

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return Collections.singleton(new SimpleGrantedAuthority(role.name()));
    }

    @Override
    public String getUsername() {
        return email;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.