簡體   English   中英

Spring Security 從其他 jar 擴展配置

[英]Spring Security extend configuration from other jar

我有一個具有依賴關系的應用程序,其中定義了安全性。 典型配置:

@Configuration
@EnableWebSecurity
public class AuthConfiguration extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers(DEFAULT_PERMIT_ALL_PATHS).permitAll()
            .and()
            .authorizeRequests().anyRequest().authenticated()
            .and()
            .exceptionHandling()
            .and()
            .csrf().disable().httpBasic();
    }        

    @Override
    protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
        User.UserBuilder users = User.withDefaultPasswordEncoder();
        authManagerBuilder.inMemoryAuthentication().withUser(users.username("FOO").password("BAR").roles("USER").build());
    }
}

以上是第一個項目。 我有第二個項目,我在上面有一個 POM 依賴項。 現在我想添加一個額外的用戶,但我必須在我的第二個項目中執行此操作,其中僅依賴於第一個具有安全性的項目。

我可以復制並粘貼整個 AuthConfiguration,然后我有 2 個安全過濾器鏈,但這不是一個好主意。 應用開始處理請求,查看目標 URI 是什么。 兩個過濾器鏈具有相同的 antMatcher(我只想添加額外的用戶)並且只處理一個過濾器鏈。 因此,它部分工作 - 來自第一個或第二個項目的用戶工作(這取決於 AuthConfiguration 的 @Order)。

也許以某種方式可以在我的第二個項目中注入例如 AuthenticationManagerBuilder 並擴展/添加其他用戶? 我試過了,但它不起作用。 我在第二個項目中添加了這樣的代碼:

@Configuration
public class AdditionalUsersConfiguration() {

    public AdditionalUsersConfiguration(AuthenticationManagerBuilder builder) throws Exception {
        User.UserBuilder users = User.withDefaultPasswordEncoder();

        authManagerBuilder.inMemoryAuthentication()
        .withUser(users.username("FOO").password("BAR").roles("USER")
        .withUser(users.username("FOO2").password("BAR").roles("USER").build());
    }
}

只有第一個用戶 FOO 有效,看起來它來自定義它的第一個項目。

編輯:我也嘗試了這個問題的方法How can I add users to the inMemoryAuthentication builder after it has been built? 我在我的第二個項目中添加了這段代碼:

@Configuration
public class NextApproachConfiguration() {

    public NextApproachConfiguration(InMemoryUserDetailsManager manager) throws Exception {
        manager.createUser(new User("FOO2", "BAR", new ArrayList<GrantedAuthority>()));
        // in debugger here I see two users [FOO, FOO2]
    }
}

這看起來不錯的樣子。 在調試器(代碼注釋)中,我看到來自第一個項目的用戶和新用戶。 但是當我使用 postman 請求端點時,我在調試器內部看到它如何調用 InMemoryUserDetailsManager::loadByUsername() 並且這個管理器的實例與我添加用戶 2 的實例不同。 它只有一個來自第一個項目的用戶。 當我使用 debbuger 啟動應用程序時,我看到首先執行我上面的代碼,在其中添加第二個用戶,然后從第一個項目(AuthConfiguration 類)執行代碼,其中 AuthenticationManagerBuilder::inMemoryAuthentication 轉到 InMemoryUserDetailsManagerConfigurer,其中使用new創建 InMemoryUserDetailsManager 的新實例關鍵詞。

最后,在我的第二個項目中,我只是以這種方式從第一個項目中擴展了 AuthConfiguration 類:

@Configuration
@Order(90)
public class SecondProjectConfiguration extends AuthConfiguration {

    @Override
    protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
        super.configure(authManagerBuilder); // it creates FOO user

        User.UserBuilder users = User.withDefaultPasswordEncoder();
        authManagerBuilder.inMemoryAuthentication()
            .withUser(users.username("FOO2").password("BAR").roles("USER").build());
    }   
}

它工作正常。 Order(90)也是需要的,因為 AuthConfiguration 具有默認的 Order 100,並且它在啟動時停止應用程序並出現錯誤。 非常簡單的方法,但最后嘗試了。

您可以采用的另一種方法是在第一個項目中對您的配置使用自定義 bean(例如 UserFactory),並使用它來檢索所有用戶並添加到內存用戶管理器

    @Autowired(required = false)
    UserFactory userFactory;

    @Override
    protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
        User.UserBuilder users = User.withDefaultPasswordEncoder();
        InMemoryUserDetailsManagerConfigurer configurer = authManagerBuilder.inMemoryAuthentication();
        configurer.withUser(users.username("FOO").password("BAR").roles("USER").build());
        if (userFactory != null) {
            for (UserDetails userDetails: userFactory.getUsers()) {
                configurer.withUser(userDetails);
            }
        }
    }

在您的第二個項目中,您定義 bean 並添加其他用戶:

    @Bean
    public UserFactory userFactory() {
        UserFactory userFactory = new UserFactory();
        User.UserBuilder user = User.withDefaultPasswordEncoder();
        userFactory.addUser(user.username("FOO2").password("BAR").roles("USER").build());
        return userFactory;
    }

如果您有許多默認用戶並希望避免在擴展配置類中重新鍵入它們,這可能更適合。

暫無
暫無

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

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