在 application.yml 中定义基本安全用户、密码和角色

Posted

技术标签:

【中文标题】在 application.yml 中定义基本安全用户、密码和角色【英文标题】:Define basic-security users, passwords and roles in application.yml 【发布时间】:2017-02-15 04:50:48 【问题描述】:

我正在寻找一种使用 Spring Boot 的 @Secured 注释来保护方法的方法。对于大约 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") 注释的方法,即使我认为用户 admin 不应该有权访问所述方法。我的 SecurityConfiguration 如下所示:

@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 中指定具有不同密码和不同角色的多个用户并注释方法以确保只有授权用户才能访问这些方法。

【问题讨论】:

您不能在配置中指定多个用户。为此,您需要自己构建一些东西。 @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 年 4 月更新

对于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() 已被标记为已弃用。

【讨论】:

感谢您的解决方案。我遇到了问题,因为类 ApplicationClient 和所有值为空的值。刚刚向 ApplicationClient 添加了 setter 和 getter,就像这里描述的 docs.spring.io/spring-boot/docs/current/reference/html/… 一样,现在一切正常

以上是关于在 application.yml 中定义基本安全用户、密码和角色的主要内容,如果未能解决你的问题,请参考以下文章

IDEA开发spring boot应用时 application.yml 或 application.properties 自定义属性提示

无法从 Java Spring Boot 项目中的 application.yml 文件中读取用户定义类的列表

将环境变量传递给 application.yml

Spring Boot - 如何通过实现 BeforeAllCallback 的自定义扩展类设置或覆盖 application.yml 中定义的属性?

Spring Boot-基础配置

Spring Boot系统配置文件application.properties和application.yml