java - 使用 spring security 登录操作之前的自定义验证?

标签 java spring spring-mvc spring-security

我是 spring 的新手,所以不完全了解 UserDetailsS​​ervice 的工作原理。

我希望我的登录表单能够像我的注册表单一样工作。但是,相反,当使用登录详细信息发送发布请求时,UserDetailsS​​ervice 类似乎首先执行。有人可以解释 UserDetailsS​​ervice 是如何工作的(即何时调用它)以及我如何更改我的安全配置以执行我的 Controller POST 方法中的内容以进行登录(就像它对注册所做的那样)。

Controller :

@Controller
public class controller{

@RequestMapping(value = "/signup", method = RequestMethod.POST)
public String registration(@ModelAttribute("userForm") final User userForm, final BindingResult bindingResult) {
    LOG.debug("Signing up with user: {}", userForm);

    signUpValidationService.validate(userForm, bindingResult);

    if (bindingResult.hasErrors()) {
        return "login/Signup";
    }

    userService.saveUser(userForm);
    userService.autologin(userForm.getEmail(), userForm.getPassword());

    return "about/Home";
}

@RequestMapping(value = "/login", method = RequestMethod.POST)
public String login(@ModelAttribute("userForm") final User userForm, final BindingResult bindingResult) {
    LOG.debug("Logging in with user: {}", userForm);

    loginValidationService.validate(userForm, bindingResult);

    if (bindingResult.hasErrors()) {
        return "login/Login";
    }

    userService.autologin(userForm.getEmail(), userForm.getPassword());

    LOG.debug("Successfully logged in with user: {}", userForm.getFirstName());

    return "about/Home";
}

}

我的安全配置:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig
    extends WebSecurityConfigurerAdapter {

/**
 * {@inheritDoc}
 */
@Override
protected void configure(HttpSecurity http) throws Exception {

    http
            .csrf().disable()
            .authorizeRequests()
            .antMatchers("/resources/**", "/signup", "/", "/home", "/about")
            .permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .loginPage("/login")
            .successHandler(successHandler())
            .permitAll()
            .and()
            .logout().deleteCookies("JSESSIONID")
            .logoutUrl("/logout")
            .logoutSuccessUrl("/home")
            .permitAll()
            .and()
            .rememberMe().key("uniqueAndSecret").tokenValiditySeconds(86400)
            .and()
            .sessionManagement()
            .sessionFixation().migrateSession()
            .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
            .invalidSessionUrl("/invalid_session")
            .maximumSessions(2)
            .expiredUrl("/expired_session");
}

/**
 * User login validation configuration.
 *
 * @param auth
 *         {@link AuthenticationManagerBuilder}
 * @param userDetailsService
 *         {@link UserDetailsService}
 * @throws Exception
 *         {@link Exception}
 */
@Autowired
public void configureGlobal(final AuthenticationManagerBuilder auth, final UserDetailsService userDetailsService)
        throws
        Exception {
    auth
            .userDetailsService(userDetailsService)
            .passwordEncoder(new BCryptPasswordEncoder());
}

/**
 * Handles login success configuration policy.
 *
 * @return {@link AuthenticationSuccessHandler}
 */
private final AuthenticationSuccessHandler successHandler() {
    return new UrlAuthenticationSuccessHandler();
}

/**
 * Sets security evaluation context.
 *
 * @return {@link SecurityEvaluationContextExtension}
 */
@Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
    return new SecurityEvaluationContextExtension();
}
}

最佳答案

Spring security 自动检测你的 yourOwnuserDetailsS​​ervice 实现了 UserDetailsS​​ervice 并且当用户在登录屏幕中输入他们的用户名和密码并单击登录按钮时。输入的信息被放入一个名为 Authentication 的对象中,该对象被传递给 AuthenticationManager 的身份验证方法。此方法将循环遍历所有已配置的 AuthenticationProviders 并调用其身份验证方法,传入 Authentication 对象。每个 AuthenticationProvider 都会调用其配置的 UserDetailsS​​erviceloadUserByUserName 方法。

您不需要显式调用它,如果您需要在 Spring 安全捕获之前捕获 Spring Security 登录表单,Spring Security 会在需要时处理它,here是细节

You can do this using regular Spring Security functionality. The steps are:

Implement a custom WebAuthenticationDetailsSource and WebAuthenticationDetails. The WebAuthenticationDetails will capture the extra form fields that you want to validate.

Note: In Spring 3.0 you'll need to use a BeanPostProcessor to configure the WebAuthenticationDetailsSource into the UsernamePasswordAuthenticationFilter. In Spring 3.1 you can do this directly in the namespace config.

Implement a custom AuthenticationProvider and in authenticate() check the WebAuthenticationDetails, throwing a AuthenticationException if validation fails. In your login page check for this exception.

Alternatively, you can create a Filter that does your validation and add it before the Spring Security filter.

此外,如果您想要验证参数,那么您可以使用 extends UsernamePasswordAuthenticationFilter 检查它

 public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {

       //your logic
        return super.attemptAuthentication(request, response); 
    } 

关于java - 使用 spring security 登录操作之前的自定义验证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45266868/

相关文章:

java - 您如何在蓝/绿部署中管理共享数据库?

java - 通过按钮 Java Swing 打开一个新面板

spring - 如何为 Spring Web 流定义自定义消息源?

java - Spring REST中如何接收多个参数值并返回JSON格式的数据?

java - FileInputStream读取方法的风格

java正则表达式,同时在括号上拆分字符串

java - Spring添加web.xml配置时Session总是过期

java - SpringBoot Catalina生命周期异常

java - Spring 3.x 无法加载 applicationContext

java - Spring MVC HandlerInterceptor : Redirect Failed