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

时间:2017-07-23 15:36:11

标签: java spring spring-mvc spring-security

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

我希望我的登录表单的行为方式与我的注册表单相同。但是,相反,当使用登录详细信息发送post请求时,UserDetailsS​​ervice类似乎首先执行。有人可以解释UserDetailsS​​ervice如何工作(即当它被调用时)以及如何更改我的安全配置以在我的控制器POST方法中执行什么操作以进行登录(就像注册时一样)。

控制器:

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

1 个答案:

答案 0 :(得分:3)

Spring安全自动检测你的yourOwnuserDetailsS​​ervice,它实现了UserDetailsS​​ervice,当用户在登录界面输入用户名和密码并点击登录按钮时。输入的信息将放入名为身份验证的对象中,该对象将传递给 AuthenticationManager 的身份验证方法。此方法将遍历所有已配置的 AuthenticationProviders 并调用其authenticate方法,并传入Authentication对象。每个 AuthenticationProvider 都会调用其配置的 UserDetailsS​​ervice loadUserByUserName 方法。

你不需要明确地调用它,如果你需要在Spring安全捕获它之前需要捕获Spring Security登录表单,Spring安全会处理它,here是详细信息

  

您可以使用常规Spring Security功能执行此操作。步骤是:

     

实现自定义WebAuthenticationDetailsS​​ource和WebAuthenticationDetails。 WebAuthenticationDetails将捕获   您要验证的额外表单字段。

     

注意:在Spring 3.0中,您需要使用BeanPostProcessor将WebAuthenticationDetailsS​​ource配置为   UsernamePasswordAuthenticationFilter。在Spring 3.1中,您可以执行此操作   直接在命名空间配置中。

     

实现自定义AuthenticationProvider并在authenticate()中检查WebAuthenticationDetails,抛出一个   AuthenticationException如果验证失败。在您的登录页面中检查   对于这个例外。

     

或者,您可以创建一个进行验证的Filter,并在Spring Security过滤器之前添加它。

此外,如果您需要验证参数,则可以使用extends UsernamePasswordAuthenticationFilter

进行检查。
int n;
cin >> n;
vector <int> graph[n], visited(n);
for (int i = 0; i < n - 1; ++i)
{
    int st, en;
    cin >> st >> en;
    st--;
    en--;
    graph[st].push_back(en);
    graph[en].push_back(st);
}
int st, en;
cin >> st >> en;
st--, en--;
queue  <pair <int, int> > q;
q.push({st, 0});
visited[st] = 1;
while (!q.empty())
{
    auto  top = q.front();
    if (top.first == en)
        return top.second;
    q.pop();
    for (auto & x : graph[top.first])
    {
        if(!visited[x])
        {
            q.push({x, top.second + 1});
            visited[x] = 1;
        }
    }
}