使用UserDetailsS​​ervice和Java配置进行Spring Security登录

时间:2015-06-17 12:52:23

标签: java spring spring-mvc spring-security

我正在尝试使用Spring Security添加数据库查找的登录功能,我真的很挣扎。我想通过实现UserDetailsService接口来查找用户。我已经阅读了大量的文档和谷歌搜索了几个小时,但我仍然卡住了。我能找到的大多数示例都使用XML,因此我的问题可能与将它们转换为Java配置有关。

的UserDetailsS​​ervice

@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配置提供一个简单示例。谢谢!

1 个答案:

答案 0 :(得分:5)

将Spring Security与基于Java的配置一起使用时,请求参数的名称为usernamepassword,而不再是j_usernamej_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");

无论哪种方式都可以解决您的问题。