我正在尝试使用 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。
非常感谢有关此事的任何帮助或建议。
您的实施存在几个问题,请参考此内容,如果您仍然遇到问题,请告诉我 -
@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;
}
}