首页 > 解决方案 > 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! 

标签: javaspring-security

解决方案


您可以创建一个 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);
}

在 CustomUserDetailsS​​erviceImpl 中:您可以在此实现中过滤验证(电子邮件有效,用户名尚未标记,密码强且匹配确认密码)

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);
    }

推荐阅读