Spring默认身份验证内部工作

时间:2016-12-21 17:33:31

标签: java spring spring-mvc spring-security

我刚开始学习Spring和Spring Security,我通过阅读Spring Security文档创建了一个简单的项目。我完成了以下基于java的配置。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
            .withUser("admin")
            .password("nimda")
            .roles("ADMIN");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests()
            .antMatchers("/").permitAll() 
            .antMatchers("/admin**").access("hasRole('ADMIN')")
            .and().formLogin();

        http.csrf().disable();
    }
}

当我选择" / admin"它将我重定向到我知道使用此默认配置生成的登录页面,登录后它将显示登录页面。现在我的问题是:登录表单发布到" / login"我没有定义任何" AuthenticationManager"和" UserDetailService"我在自定义配置的文档中读到了如何弹出表单并执行登录过程?基本上我想知道这个默认登录过程内部工作的一些细节。

2 个答案:

答案 0 :(得分:0)

当您使用* ConfigurerAdapter类时,在上下文加载期间会发生很多事情。 Spring将检查您是否定义了AuthenticationManager,如果没有,它将创建一个默认的。

如果您真的对魔术配置步骤中发生的事情感兴趣,您可能需要查看源代码。例如,如果您查看WebSecurityConfigurerAdapter.getHttp(),您可以看到它调用authenticationManager()以构造此bean。

protected AuthenticationManager authenticationManager() throws Exception {
    if (!authenticationManagerInitialized) {
        configure(localConfigureAuthenticationBldr);
        if (disableLocalConfigureAuthenticationBldr) {
            authenticationManager = authenticationConfiguration
                    .getAuthenticationManager();
        }
        else {
            authenticationManager = localConfigureAuthenticationBldr.build();
        }
        authenticationManagerInitialized = true;
    }
    return authenticationManager;
}

在过去,你必须自己创造所有豆子并将它们连接在一起,这样我们就能更清楚地了解事物是如何组合在一起的。现在你要么必须阅读来源,要么从指南中复制,并希望你不要犯任何错误。

调试提示:这些天我查看加载上下文后存在的bean,然后我返回并在AuthenticationManager实现的构造函数中设置断点,然后我可以看到call-stack以及初始化的工作原理。

答案 1 :(得分:0)

以下是您要查找的代码,而不是使用构建器来构建内存中的用户详细信息源,您可以实现自己的自定义AuthenticationProvider。

public void configure(AuthenticationManagerBuilder auth) throws Exception {

    auth.authenticationProvider(new AuthenticationProvider() {
        @Override
        public Authentication authenticate(Authentication authentication) throws AuthenticationException {
            String password = (String) authentication.getPrincipal();
            String userName = (String) authentication.getCredentials();

            if ("user".equals(userName) && "password".equals(password)) {
                authentication = new UsernamePasswordAuthenticationToken(userName, password, Lists.newArrayList(new SimpleListProperty<GrantedAuthority>(null, "USER")));
                return authentication;
            }
            throw new BadCredentialsException("Incorrect username or password.");
        }

        @Override
        public boolean supports(Class<?> authentication) {
            return true;
        }
    });
}

请注意,您可以创建自己的身份验证实施,以备需要添加其他信息时使用,或者您可以使用每个身份验证可以拥有的详细信息属性。