Определение пользователей, паролей и ролей базовой безопасности в application.yml

#spring #spring-security #spring-boot #spring-boot-actuator

#spring #spring-безопасность #spring-загрузка #spring-boot-actuator

Вопрос:

Я ищу способ защитить методы с @Secured помощью аннотации Spring Boot. Примерно для 10-15 пользователей я бы не хотел подключаться к базе данных и получать оттуда пользователей и их полномочия / роли, а скорее хранить их локально в application.yml файле, специфичном для профиля. Есть ли в Spring Boot концепция, поддерживающая эту идею? Все, что я смог найти до сих пор, работает с базовым приводом безопасности ( 'org.springframework.boot:spring-boot-starter-security' ) и выглядит следующим образом:

 security:
  basic:
    enabled: true
  user:
    name: admin
    password: admin
    role: EXAMPLE
  

Тем не менее, я все еще могу получить доступ к методу с аннотацией @RolesAllowed("READ") , хотя я бы предположил, что администратор пользователя не должен иметь доступа к указанному методу. Моя конфигурация безопасности выглядит следующим образом:

 @Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(jsr250Enabled = true)
@Profile("secure")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest()
                .fullyAuthenticated()
                .and()
                .httpBasic();

        http.sessionManagement()
                .sessionFixation()
                .newSession();

        http.csrf().disable();
        http.headers().frameOptions().disable();

    }
}
  

В конечном итоге это может быть другая проблема, но, возможно, это важно для моего собственного понимания.

Мне интересно, как я мог бы указать несколько пользователей с разными паролями и разными ролями в моих application.yml и аннотированных методах, чтобы гарантировать, что только авторизованные пользователи могут получить доступ к методам.

Комментарии:

1. вы не можете указать несколько пользователей в своей конфигурации. Для этого вам нужно будет создать что-то самостоятельно.

2. @M.Deinum спасибо, я нашел довольно простой способ добиться этого.

Ответ №1:

Это может быть достигнуто с помощью пользовательских ConfigurationProperties :

 @ConfigurationProperties("application")
public class ApplicationClients {

    private final List<ApplicationClient> clients = new ArrayList<>();

    public List<ApplicationClient> getClients() {
        return this.clients;
    }

}

@Getter
@Setter
public class ApplicationClient {
    private String username;
    private String password;
    private String[] roles;
}

@Configuration
@EnableConfigurationProperties(ApplicationClients.class)
public class AuthenticationManagerConfig extends
        GlobalAuthenticationConfigurerAdapter {

    @Autowired
    ApplicationClients application;

    @Override
    public void init(AuthenticationManagerBuilder auth) throws Exception {
        for (ApplicationClient client : application.getClients()) {
            auth.inMemoryAuthentication()
                    .withUser(client.getUsername()).password(client.getPassword()).roles(client.getRoles());
        }
    }

}
  

и затем вы можете указать пользователей в своем application.yml :

 application:
  clients:
    - username: rw
      password: rw
      roles: READ,WRITE
    - username: r
      password: r
      roles: READ
    - username: w
      password: w
      roles: WRITE
  

не забудьте добавить spring-boot-configuration-processor в свой build.gradle :

 compile 'org.springframework.boot:spring-boot-configuration-processor'
  

Обновление апрель 2018

Для Spring Boot 2.0 я использую следующий класс:

 @Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
@EnableWebSecurity
@ConditionalOnWebApplication
@EnableConfigurationProperties(ApplicationClients.class)
@RequiredArgsConstructor
@Slf4j
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final ApplicationClients application;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .requestMatchers(EndpointRequest.to("health")).permitAll()
            .requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole("ACTUATOR")
            .antMatchers("/rest/**").authenticated()
            .antMatchers("/soap/**").authenticated()
            .and()
            .cors()
            .and()
            .httpBasic();
    }

    @Bean
    public InMemoryUserDetailsManager inMemoryUserDetailsManager() {
        final InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        log.info("Importing {} clients:", application.getClients().size());

        application.getClients().forEach(client -> {
            manager.createUser(User.withDefaultPasswordEncoder()
                .username(client.getUsername())
                .password(client.getPassword())
                .roles(client.getRoles())
                .build());
            log.info("Imported client {}", client.toString());
        });

        return manager;
    }
}
  

Пожалуйста, имейте в виду, что User.withDefaultPasswordEncoder() это помечено как устаревшее из соображений безопасности.

Комментарии:

1. Спасибо за ваше решение. У меня возникли проблемы, потому что класс ApplicationClient и все значения имеют значение null. Просто добавлены установщики и получатели в ApplicationClient, как описано здесь docs.spring.io/spring-boot/docs/current/reference/html /… и теперь все работает.