我是 spring 的新手,所以不完全了解 UserDetailsService 的工作原理。
我希望我的登录表单能够像我的注册表单一样工作。但是,相反,当使用登录详细信息发送发布请求时,UserDetailsService 类似乎首先执行。有人可以解释 UserDetailsService 是如何工作的(即何时调用它)以及我如何更改我的安全配置以执行我的 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 自动检测你的 yourOwnuserDetailsService 实现了 UserDetailsService 并且当用户在登录屏幕中输入他们的用户名和密码并单击登录按钮时。输入的信息被放入一个名为 Authentication 的对象中,该对象被传递给 AuthenticationManager 的身份验证方法。此方法将循环遍历所有已配置的 AuthenticationProviders 并调用其身份验证方法,传入 Authentication 对象。每个 AuthenticationProvider 都会调用其配置的 UserDetailsService 的 loadUserByUserName 方法。
您不需要显式调用它,如果您需要在 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/