我正在尝试在我的项目上制作一个简单的登录系统,也使用 Spring 3.1.1 和 Spring Security 3.1.1。阅读文档,我们不应该再“扩展 WebSecurityAdapter”,而是像这样实现它:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Autowired
RequestFilter requestFilter;
/**
* List with whitelisted endpoints.
*/
private static final String[] AUTH_WHITELIST = {
// -- Swagger UI v2
"/v2/api-docs",
"/swagger-resources",
"/swagger-resources/**",
"/configuration/ui",
"/configuration/security",
"/swagger-ui.html",
"/webjars/**",
// -- Swagger UI v3 (OpenAPI)
"/v3/api-docs/**",
"/swagger-ui/**",
// other public endpoints of your API may be appended to this array
"/users/register",
"/users/login",
"/plans/free-plan"
};
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
return httpSecurity
.csrf(AbstractHttpConfigurer::disable)
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(authorize -> authorize
.requestMatchers(AUTH_WHITELIST).permitAll()
.anyRequest().authenticated()
)
.addFilterBefore(requestFilter, UsernamePasswordAuthenticationFilter.class)
.build();
}
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return web -> web.ignoring().requestMatchers("/v3/api-docs/**");
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
在这个类中,我在 bean 上创建了一个“AuthenticationManager”,但是当我尝试在我的服务上使用它时,它会出现 Stackoverflow 错误。我的服务:
@Service
public class UserService extends GenericService<User> {
/**
* Authentication Manager instance.
*/
private final AuthenticationManager authenticationManager;
/**
* User Repository instance.
*/
private final UserRepository userRepository;
/**
* JWTUtils Instance.
*/
private JWTTokenUtils jwtTokenUtils;
/**
* Plan Service instance.
*/
private PlanService planService;
@Autowired
public UserService(AuthenticationManager authenticationManager, UserRepository userRepository,
JWTTokenUtils jwtTokenUtils, PlanService planService) {
this.authenticationManager = authenticationManager;
this.userRepository = userRepository;
this.jwtTokenUtils = jwtTokenUtils;
this.planService = planService;
}
@Override
protected GenericRepository getGenericRepository() {
return userRepository;
}
@Override
protected SearchPredicate<User> getSearchPredicate(String search) {
return null;
}
/* Methods */
/**
* Method to login on Coupler API.
*
* @param jwtRequestDTO Login request DTO.
* @return {@link JwtResponseDTO}. JWT Token with all the info.
* @throws RestRequestException The API can throw an exception if it cannot find necessary data.
*/
public JwtResponseDTO login(JwtRequestDTO jwtRequestDTO) throws RestRequestException {
var userPassword = new UsernamePasswordAuthenticationToken(jwtRequestDTO.getEmail(), jwtRequestDTO.getPassword());
// The error is here!
var auth = authenticationManager.authenticate(userPassword);
var token = jwtTokenUtils.generateToken(((User) auth.getPrincipal()).getEmail());
User user = userRepository.findByEmail(jwtRequestDTO.getEmail())
.orElseThrow(() -> new RestRequestException(HttpStatus.NOT_FOUND, ErrorIndicator.FIM_ERROR_U01.getMessage()));
return new JwtResponseDTO(token, user.getId());
}
}
我没有在系统中定义任何其他 AuthenticationManager,当我用 AuthenticationManager 注释或删除“@Bean”时,它声称我的 UserService 需要一个未提供的 bean,而该光束就是 AuthenticationManager。 “RequestFilter”是我的“扩展的 OncePerRequestFilter”实现,不认为存在问题,所以为了保持简单,我将忽略它。