Spring Boot/ Spring Security,登录表单,密码检查

9 浏览
0 Comments

Spring Boot/ Spring Security,登录表单,密码检查

我遇到了一个可能很简单的问题,但我不理解。

我对Spring Boot不是很熟悉,很多东西都是自动完成的。我想要检查在表单中输入用户名和密码的人是否在数据库中存在[并且他的账户已激活]。用户数据存储在在application.properties中配置的MySQL数据库中。我想要检查是否有提供的用户名在"user"表中存在,并且检查提供的密码是否与数据库中的用户密码相等。目前我可以输入数据库中的任何用户名,密码可以是随机的(这对我来说是显而易见的,因为我没有在任何地方进行检查,且很奇怪,因为我感觉周围的一切都表明它正常工作)。这对我来说听起来很简单,但我在StackOverflow或教程中找不到任何合适的解决方案。

我总的问题是-我应该在哪里以及如何检查登录表单中的密码?这是自动完成的(但是它不知何故不起作用),还是我应该编写自定义的controller/service/method来做到这一点?如果需要自定义controller,那么解决我的问题应该是什么方向?

目前我不知道该去哪里。我希望与我的问题相关的所有剩余代码都在这里粘贴。提前感谢您对此的所有提示和评论。

代码:

ApplicationSecurityAdapter 类:

@Configuration

@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)

public class ApplicationSecurityAdapter extends WebSecurityConfigurerAdapter {

@Autowired

private UserService userService;

@Override

protected void configure(HttpSecurity http) throws Exception {

http.authorizeRequests()

.antMatchers("/user/register").permitAll()

.antMatchers("/user/activate").permitAll()

.antMatchers("/user/activation-send").permitAll()

.antMatchers("/user/reset-password").permitAll()

.antMatchers("/user/reset-password-change").permitAll()

.antMatchers("/user/autologin").access("hasRole('ROLE_ADMIN')")

.antMatchers("/user/delete").access("hasRole('ROLE_ADMIN')")

.antMatchers("/img/").permitAll()

.antMatchers("/images/").permitAll()

.antMatchers("/fonts/").permitAll()

.anyRequest().authenticated()

.and()

.formLogin().loginPage("/login").failureUrl("/login?error").permitAll()

.and()

.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login").permitAll() // added permitAll()

.and()

.rememberMe().key(applicationSecret)

.tokenValiditySeconds(31536000);

}

@Override

public void configure(AuthenticationManagerBuilder auth) throws Exception {

auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());

}

UserService 类:

@Service

public class UserService implements UserDetailsService {

@Value("${app.user.verification}") // set to YES

private Boolean requireActivation;

@Value("${app.secret}") // some random stuff

private String applicationSecret;

@Autowired

private UserRepository repo;

@Autowired

private HttpSession httpSession;

public final String CURRENT_USER_KEY = "CURRENT_USER";

@Override

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

User user = repo.findOneByUserName(username);

if(user == null) {

throw new UsernameNotFoundException(username);

}

if(requireActivation && !user.getToken().equals("1")) {

Application.log.error("User [" + username + "] tried to log in, but his account is not activated.");

throw new UsernameNotFoundException(username + " did not activate his account.");

}

httpSession.setAttribute(CURRENT_USER_KEY, user);

List auth = AuthorityUtils.commaSeparatedStringToAuthorityList(user.getRole());

return new org.springframework.security.core.userdetails.User(user.getUserName(), user.getPassword(), auth);

}

}

UserController 类:

@Controller

// @RequestMapping("/user/")

public class UserController {

private Logger log = LoggerFactory.getLogger(UserController.class);

@Value("${app.user.verification}") // YES

private Boolean requireActivation;

@Value("users/")

private String userRoot;

@Autowired

private UserRepository userRepository;

@Autowired

protected AuthenticationManager authenticationManager;

@Autowired

private UserService userService;

@RequestMapping("/login")

public String login(User user) {

return "user/login";

}

}

登录表单:

0
0 Comments

问题出现的原因是在loadUserByUsername方法中将用户存储到了会话中,而实际上不应该这样做,只需要加载用户并返回即可。用户会自动存储在会话中,并且可以通过查找来获取。 密码检查不起作用的原因可能是你将BCryptPasswordEncoder配置为密码编码器,确保你在User中存储的密码是使用该编码器进行编码的,否则密码检查将失败。为了避免自定义激活检查,你可以让User类实现UserDetails接口,并设置其中的4个标志。你的loadUserByUsername方法的实现应该只做加载用户并根据给定的用户名抛出UsernameNotFoundException的操作。如果你不想让'User'实现'UserDetails',可以返回使用Spring的User类的实例,并在其中设置这些标志。最后,密码、权限、激活状态等会由Spring自动检查。

0