Spring Security中使用UserDetails登录的java实现不起作用
我有一个简单的弹簧靴2。xx应用程序使用Spring Data JPA MySQL,我必须使用Spring Security(特别是Java config)来保护这个web应用程序。在这方面,我在网上找到了大量资源来完成这项工作,但徒劳了,有些示例太复杂了,无法理解,而其他示例对我来说从未奏效。我想出了这个secure-spring-demo,它也不起作用。一些代码剪报是
WebSecurity配置类是
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public DaoAuthenticationProvider authProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authProvider());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http
.authorizeRequests()
.antMatchers("/login*", "/register", "/").anonymous()
.antMatchers("/secure/*").hasAnyAuthority("ADMIN").anyRequest().authenticated()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.and()
.logout().logoutSuccessUrl("/login");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
而UserDetailsServiceImpl类是
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
private final UserService userService;
@Autowired
public UserDetailsServiceImpl(UserService userService) {
this.userService = userService;
}
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
User user = userService.findByUserEmail(s);
if (user == null){
throw new UsernameNotFoundException("User with " + s + " not found!");
}
return new org.springframework.security.core.userdetails.User(
user.getUserEmail(), user.getUserPassword(), user.getRoles());
}
}
控制器是
@Controller
public class UserController {
@Autowired
private UserService userService;
@Autowired
private RoleService roleService;
@Autowired
private SecurityService securityService;
//Omitting other mappings
@GetMapping(value = "/login")
public String getLogin(Model model,
@RequestParam(value = "error", required = false) String error){
if (null != error && error.equalsIgnoreCase("true")){
model.addAttribute("loginError", "Unable to Login");
}
return "login";
}
@PostMapping(value = "/login")
public String postLogin(@RequestParam(value = "userEmail") String userEmail,
@RequestParam(value = "userPassword") String userPassword){
logger.debug(userEmail + " and " + userPassword );
boolean loginResult = securityService.login(userEmail, userPassword);
return (loginResult ? "redirect:/secure/home" : "redirect:/login?error=true");
}
}
这样,所有用户都无法使用正确的凭据登录
# 1 楼答案
我在你的代码中发现的主要问题是没有从thymeleaf模板中传递“username”和“password”属性,因为它应该与准确的凭据属性相匹配,以便对对象进行身份验证。。因此,您的登录表单如下所示:
由于参数已更改,因此您还需要更改控制器属性:
# 2 楼答案
主要原因,因为您希望自定义方法处理spring security的登录,但您再次设置了自定义方法的名称,该名称与spring security的方法登录默认值相同。所以Web会调用spring的登录方法,但不会调用自定义方法
在这种情况下,如果要自定义spring security的方法登录,必须将其转换为与spring login default的方法名不同的名称。这是你的建议,我可以听从
我在登录文件中将“login”编辑为loginCustom。html
在用户控制器中。java,我编辑为“/loginCustom”