java - Spring Security 为注册 API 添加自定义过滤器链
问题描述
我正在构建一个 Rest 应用程序,我需要应用一个过滤器(此过滤器将验证凭据,如电子邮件有效、用户名尚未标记、密码强且匹配确认密码)。我想将此链仅用于注册而不是其他过滤器(例如检查您是否已通过身份验证)
I have something like this in spring securityConfiguration
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final BCryptPasswordEncoder passwordEncoder;
private final UserServiceImplementation serviceImplementation;
private final JwtConfiguration jwtConfiguration;
@Autowired
public SecurityConfiguration(UserServiceImplementation serviceImplementation, BCryptPasswordEncoder passwordEncoder, JwtConfiguration jwtConfiguration) {
this.serviceImplementation = serviceImplementation;
this.passwordEncoder = passwordEncoder;
this.jwtConfiguration = jwtConfiguration;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.addFilter(new JwtUsernameAndPasswordAuthenticationFilter(authenticationManager(), jwtConfiguration))
.addFilterAfter(new JwtTokenVerifier(jwtConfiguration), JwtUsernameAndPasswordAuthenticationFilter.class)
.authorizeRequests()
.anyRequest()
.authenticated();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(daoAuthenticationProvider());
}
@Override
public void configure(WebSecurity web) {
web.debug(true);
web.ignoring().antMatchers(HttpMethod.GET, "/register/**");
web.ignoring().antMatchers(HttpMethod.POST, "/register/**");
}
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder(passwordEncoder);
provider.setUserDetailsService(serviceImplementation);
return provider;
}
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH");
}
};
}
}
I will appreciate any input and any suggestions from the community!
解决方案
您可以创建一个 POST 映射控制器方法来处理注册验证。首先,您应该在SpringSecurityConfig中允许注册网址如下。
@Autowired
private UserRepository userRepository;
@Override
public UserDetailsService userDetailsServiceBean() throws Exception {
return new CustomUserDetailsServiceImpl(userRepository);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors().and()
.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/api/v1/user/register").permitAll();
}
在用户控制器中:
@RestController
@RequestMapping("/api/v1/user")
public class UserController {
@Autowired
private CustomUserDetailsServiceImpl userDetailsService;
@Autowired
public UserController(CustomUserDetailsServiceImpl userDetailsService) {
this.userDetailsService = userDetailsService;
}
@PostMapping(value = "/register")
public User register(@RequestBody User user) {
return userDetailsService.save(user);
}
}
用户存储库:
public interface UserRepository extends JpaRepository<User, String> {
User findByUsername(String username);
}
在 CustomUserDetailsServiceImpl 中:您可以在此实现中过滤验证(电子邮件有效,用户名尚未标记,密码强且匹配确认密码)
public User save(User user){
if(StringUtils.isEmpty(user.getUsername())) {
throw ExceptionFactory.getApiError(ExceptionEnum.BAD_REQUEST, "username");
}
if(StringUtils.isEmpty(user.getPassword())) {
throw ExceptionFactory.getApiError(ExceptionEnum.BAD_REQUEST, "password");
}
User registeredUser = new User();
registeredUser.setUsername(user.getUsername());
registeredUser.setPassword(passwordEncoder.encode(user.getPassword()));
registeredUser.setEnabled(true);
registeredUser.setRoles(Arrays.asList(new Role(RoleEnum.USER.getRole())));
return userRepository.save(registeredUser);
}
推荐阅读
- c# - 在 Timer 中编码时,随机图片框不会移动
- java - 在每次调用 isEmailVerified() 时返回错误条件,即使在电子邮件验证之后
- android - Recyclerview 使用中间项目而不是从顶部打开
- office-js - 未捕获(承诺中)类型错误:无法读取 null 的属性“重复”
- kubernetes - 所有 Kubernetes 代理目标都关闭 - Prometheus Operator
- ios - 在 iOS Webview 中播放 Vimeo 视频
- reactjs - 在 React 循环中使用组件函数
- regex - 正则表达式不以零开头并且在指定的范围内
- riscv - 使用 jtagRocketConfig 运行 OpenOCD 失败
- android - 共享首选项在使用一次后删除数据