我正在尝试使用Spring Security添加数据库查找的登录功能,我真的很挣扎。我想通过实现UserDetailsService
接口来查找用户。我已经阅读了大量的文档和谷歌搜索了几个小时,但我仍然卡住了。我能找到的大多数示例都使用XML,因此我的问题可能与将它们转换为Java配置有关。
的UserDetailsService
@Service
public class AccountServiceImpl implements AccountService { // AccountService implements UserDetailsService
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
// The email variable is always ''
List<GrantedAuthority> authList = new ArrayList<>();
authList.add(new Role("ROLE_USER")); // Role implements GrantedAuthority
return new User("test@example.com", "password", true, true, true, true, authList);
}
}
安全配置
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private LogoutSuccessHandler logoutSuccessHandler;
@Autowired
private AccountService accountService;
@Override
@Bean
protected AuthenticationManager authenticationManager() throws Exception {
// This bean is required for using method security annotations
return super.authenticationManager();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login/process")
.failureUrl("/login?error=true")
.defaultSuccessUrl("/", false)
.and()
//.userDetailsService(this.accountService)
.logout()
.logoutUrl("/logout")
.logoutSuccessHandler(this.logoutSuccessHandler)
.invalidateHttpSession(true)
.and()
// Permissions here
.csrf().disable();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("test@example.com").password("password").roles("USER");
}
/*@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
//.userDetailsService(this.accountService);
.inMemoryAuthentication()
.withUser("test@example.com").password("password").roles("USER").and()
.withUser("admin").password("password").roles("USER", "ADMIN");
}*/
/*@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(this.accountService);
return provider;
}*/
}
正如您所看到的,有一堆已经过分析的代码,这些代码只是我尝试使其工作的一些内容。我也尝试过简单的内存中身份验证,但这也不起作用。
的login.jsp
<form action="/login/process" method="POST">
<input name="j_username" id="j_username" type="text" />
<input name="j_password" id="j_password" type="password" />
<input type="submit" value="Login" />
</form>
调试
DEBUG org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter - Request is to process authentication
DEBUG org.springframework.security.authentication.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
DEBUG org.springframework.security.authentication.dao.DaoAuthenticationProvider - User '' not found
DEBUG org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter - Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
DEBUG org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter - Updated SecurityContextHolder to contain null Authentication
以上似乎总是适用于我尝试过的所有配置。我甚至不确定为什么使用DaoAuthenticationProvider
,即使我试图覆盖它;我猜这是默认值。对于上面的一些配置,我的UserDetailsService
实现被调用,但是以空字符串作为参数。此外,即使我返回的硬编码UserDetails
对象的凭据与我在表单中输入的凭据相同,但身份验证仍然失败,我会重定向回/login?error=true
。
我在这里做错了什么?请告诉我有关我的错误或使用Java配置提供一个简单示例。谢谢!
答案 0 :(得分:5)
将Spring Security与基于Java的配置一起使用时,请求参数的名称为username
和password
,而不再是j_username
和j_password
。
您可以修改登录表单
<form action="/login/process" method="POST">
<input name="username" id="j_username" type="text" />
<input name="password" id="j_password" type="password" />
<input type="submit" value="Login" />
</form>
或调整您的配置以使用旧的字段名称。
formLogin().usernameParameter("j_username").passwordParameter("j_password");
无论哪种方式都可以解决您的问题。