簡體   English   中英

Spring Security中如何在內存身份驗證和jdbc身份驗證中同時配置

[英]how to configure both in memory authentication and jdbc authentication in spring security

我可以通過以下配置在內存身份驗證中實現

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter
{

    @Autowired
    public void configureInMemoryAuthentication(AuthenticationManagerBuilder auth) throws Exception
    {
        auth.inMemoryAuthentication().withUser("praveen").password("{noop}praveen@123#").roles("ADMIN");
        auth.inMemoryAuthentication().withUser("vedanta").password("{noop}vedanta@123#").roles("USER");
    }

    @Override
    protected void configure(final HttpSecurity http) throws Exception
    {
        http
            .authorizeRequests()
                .antMatchers("/resources/**", "/", "/login", "/api/**").permitAll()
                .antMatchers("/app/admin/*").hasRole("ADMIN").antMatchers("/app/user/*")
                .hasAnyRole("ADMIN", "USER")
            .and().exceptionHandling().accessDeniedPage("/403")
            .and().formLogin()
                .loginPage("/login").usernameParameter("userName")
                .passwordParameter("password")
                .defaultSuccessUrl("/app/user/dashboard")
                .failureUrl("/login?error=true")
            .and().logout()
                .logoutSuccessHandler(new CustomLogoutSuccessHandler())
                .invalidateHttpSession(true)
            .and().csrf().disable();

        http.sessionManagement().maximumSessions(1).expiredUrl("/login?expired=true");
    }
}

和jdbc身份驗證通過以下配置(在不同的項目中)

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter 
{

    @Autowired
    DataSource dataSource;  


    @Autowired
    public void configureJdbcAuthentication(AuthenticationManagerBuilder auth) throws Exception
    {
        auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(passwordEncoder())
                .usersByUsernameQuery("select username, password, enabled from userdetails where userName=?")
                .authoritiesByUsernameQuery(
                        "select ud.username as username, rm.name as role from userdetails ud INNER JOIN rolemaster rm ON rm.id = ud.roleId  where username = ?");
    }

    @Override
    protected void configure(final HttpSecurity http) throws Exception
    {
        http
        .authorizeRequests()
            .antMatchers("/resources/**", "/", "/login")
                .permitAll()
            .antMatchers("/config/*", "/app/admin/*")
                .hasRole("ADMIN")
            .antMatchers("/app/user/*")
                .hasAnyRole("ADMIN", "USER")
            .antMatchers("/api/**")
                .hasRole("APIUSER")
        .and().exceptionHandling()
            .accessDeniedPage("/403")
        .and().formLogin()
            .loginPage("/login")
            .usernameParameter("userName").passwordParameter("password")
            .defaultSuccessUrl("/app/user/dashboard")
            .failureUrl("/login?error=true")
        .and().logout()
            .logoutSuccessHandler(new CustomLogoutSuccessHandler())
            .invalidateHttpSession(true)
        .and().httpBasic()
        .and().csrf()
                .disable();

        http.sessionManagement().maximumSessions(1).expiredUrl("/login?expired=true");
    }

    @Bean
    public PasswordEncoder passwordEncoder() 
    {
        return new BCryptPasswordEncoder();
    }

}

當我試圖在同一個項目中實現兩者時(我在SpringSecurityConfig中僅添加了configureInMemoryAuthentication和configureJdbcAuthentication方法,如下所示)

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter 
{
... 
    @Autowired
    public void configureInMemoryAuthentication(AuthenticationManagerBuilder auth) throws Exception
    {
        auth.inMemoryAuthentication()
        .withUser("restapiuser")
        .password("restapiuser@123#")
        .roles("APIUSER");
    }

    @Autowired
    public void configureJdbcAuthentication(AuthenticationManagerBuilder auth) throws Exception
    {
        auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(passwordEncoder())
                .usersByUsernameQuery("select username, password, enabled from userdetails where userName=?")
                .authoritiesByUsernameQuery(
                        "select ud.username as username, rm.name as role from userdetails ud INNER JOIN rolemaster rm ON rm.id = ud.roleId  where username = ?");
    }

...    
}

但是我無法成功使用inMemoryAuthentication憑據登錄,我已被重定向到“ / login?error = true”頁面。

但是我能夠使用jdbcAuthentication憑據成功登錄。

但兩者都無法實現。
我做錯什么了嗎?
是否可以結合兩個身份驗證?

錯誤的是,身份驗證管理器試圖解碼我的普通密碼並發出此警告。

WARN  - Encoded password does not look like BCrypt

看到日志后,我嘗試了password("{noop}restapiuser@123#")也不起作用,可能是因為jdbcAuthentication已為passwordEncoder注冊,身份驗證管理器每次都會嘗試解密/解碼密碼。 因此,無需跳過密碼解碼即可提供編碼后的密碼。

由於我未保留編碼后的密碼,因此它嘗試對其進行解碼並重定向到failureUrl。

參考解決方案

@Autowired
public void configureInMemoryAuthentication(AuthenticationManagerBuilder auth) throws Exception
{
    auth.inMemoryAuthentication()
    .withUser("restapiuser")
    .password(new BCryptPasswordEncoder().encode("restapiuser@123#"))
    .roles("APIUSER");
}

或者,最佳做法是保留編碼密碼而不是普通密碼

.password("$2a$10$GRoNCbeVoBYMcZH7QLX2O.wWxkMtB4qiBY8y.XzvRN/mvktS9GWc6")

另類。 只有一種configureAuthentication方法,但同時在內存和jdbc身份驗證中進行如下配置

@Autowired
public void configureBothAuthentication(AuthenticationManagerBuilder auth) throws Exception
{
    auth.inMemoryAuthentication()
        .withUser("restapiuser")
        .password(new BCryptPasswordEncoder().encode("restapiuser@123#"))
        .roles("ADMIN");

    auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(passwordEncoder())
            .usersByUsernameQuery("select username, password, enabled from userdetails where userName=?")
            .authoritiesByUsernameQuery(
                    "select ud.username as username, rm.name as role from userdetails ud INNER JOIN rolemaster rm ON rm.id = ud.roleId  where username = ?");
}

所以,
在Spring項目中可以同時實現InMemoryAuthentication和jdbcAuthentication。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM