Spring Boot中用于应用身份验证和管理身份验证的不同凭据?

时间:2015-05-21 19:32:54

标签: spring authentication spring-security spring-boot

我想使用一组凭据对我的Spring Boot应用程序使用http基本身份验证,同时我想配置执行程序为管理资源(运行状况,环境等)使用不同的凭据集。我已经阅读了Actucator文档,其中说明您应该能够使用security.user.namesecurity.user.password属性设置用户名和密码。但是,当我添加自定义WebSecurityConfigurerAdapter时,它似乎不再适用。我的WebSecurityConfigurerAdapter看起来像这样:

@Configuration
@EnableWebMvcSecurity
@Order(Ordered.LOWEST_PRECEDENCE - 11)
public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {

    private static final String API_USER = "API";
    private static final String ADMIN_USER = "ADMIN";

    @NotNull
    @Value("${security.user.name}")
    private String managementUsername;
    @NotNull
    @Value("${security.user.password}")
    private String managementPassword;
    @NotNull
    @Value("${management.context-path}")
    private String managementContextPath;

    public ApplicationSecurityConfig() {
        super(true);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http
                .addFilter(new WebAsyncManagerIntegrationFilter())
                .exceptionHandling().and()
                .headers().and()
                .sessionManagement()
                    .sessionCreationPolicy(STATELESS)
                .and()
                .securityContext().and()
                .requestCache().and()
                .servletApi().and()
                .authorizeRequests()
                      .antMatchers(managementContextPath+"/**").hasRole(ADMIN_USER)
                      .antMatchers("/**").hasRole(API_USER)
                      .and()
                .httpBasic();
        // @formatter:on
    }


    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("apiUsername").password("apiPassword").roles(API_USER).
                and().withUser(managementUsername).password(managementPassword).roles(ADMIN_USER);
    }
}

我还尝试将management.security.enabled设置为false,但是管理资源似乎对所有人开放,尽管我努力保护它。

有谁知道我做错了什么以及如何去做?

更新

我看到Spring从我的应用程序中发出了三个事件:

2015-06-10 20:04:37.076  INFO 44081 --- [nio-8083-exec-1] o.s.b.a.audit.listener.AuditListener     : AuditEvent [timestamp=Wed Jun 10 20:04:37 CEST 2015, principal=<unknown>, type=AUTHENTICATION_FAILURE, data={type=org.springframework.security.authentication.AuthenticationCredentialsNotFoundException, message=An Authentication object was not found in the SecurityContext}]
2015-06-10 20:04:39.564  INFO 44081 --- [nio-8083-exec-2] o.s.b.a.audit.listener.AuditListener     : AuditEvent [timestamp=Wed Jun 10 20:04:39 CEST 2015, principal=admin, type=AUTHENTICATION_SUCCESS, data={details=org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null}]
2015-06-10 20:04:39.569  INFO 44081 --- [nio-8083-exec-2] o.s.b.a.audit.listener.AuditListener     : AuditEvent [timestamp=Wed Jun 10 20:04:39 CEST 2015, principal=admin, type=AUTHORIZATION_FAILURE, data={type=org.springframework.security.access.AccessDeniedException, message=Access is denied}]

但是hyness示例应用中只有两个:

2015-06-10 19:34:10.851  INFO 42714 --- [nio-8083-exec-1] o.s.b.a.audit.listener.AuditListener     : AuditEvent [timestamp=Wed Jun 10 19:34:10 CEST 2015, principal=anonymousUser, type=AUTHORIZATION_FAILURE, data={type=org.springframework.security.access.AccessDeniedException, message=Access is denied}]
2015-06-10 19:34:17.139  INFO 42714 --- [nio-8083-exec-2] o.s.b.a.audit.listener.AuditListener     : AuditEvent [timestamp=Wed Jun 10 19:34:17 CEST 2015, principal=manage, type=AUTHENTICATION_SUCCESS, data={details=org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null}]

3 个答案:

答案 0 :(得分:1)

我更改了优先级并更改了管理用户名和密码属性名称,这对我有用。管理上下文只能由管理用户访问,其余的安全路径只能由 apiUsername 访问。问题是没有基本的注销功能。您需要关闭浏览器窗口或使用私人选项卡切换用户。

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) 
public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {

    private static final String API_USER = "API";
    private static final String ADMIN_USER = "ADMIN";

    @NotNull
    @Value("${management.user.name}")
    private String managementUsername;

    @NotNull
    @Value("${management.user.password}")
    private String managementPassword;

    @NotNull
    @Value("${management.context-path}")
    private String managementContextPath;

    public ApplicationSecurityConfig() {
        super(true);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http.addFilter(new WebAsyncManagerIntegrationFilter())
                .exceptionHandling().and().headers().and().sessionManagement()
                .sessionCreationPolicy(STATELESS).and().securityContext().and()
                .requestCache().and().servletApi().and().authorizeRequests()
                .antMatchers(managementContextPath + "/**").hasRole(ADMIN_USER)
                .antMatchers("/**").hasRole(API_USER).and().httpBasic();
        // @formatter:on
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth)
            throws Exception {
        auth.inMemoryAuthentication().withUser("apiUsername")
                .password("apiPassword").roles(API_USER).and()
                .withUser(managementUsername).password(managementPassword)
                .roles(ADMIN_USER);
    }
}

答案 1 :(得分:0)

我想你想为不同的网址设置不同的配置? Spring Security参考文档中的Multiple HttpSecurity章节建议您创建一个包含多个WebSecurityConfigurerAdapter bean的安全配置(基于您的问题的简化代码段和参考文档中的示例):

@Configuration
@EnableWebSecurity
public class MultiHttpSecurityConfig {

    // variables omitted...

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) { 
    auth
        .inMemoryAuthentication()
            .withUser("apiUsername").password("apiPassword")
                .roles(API_USER).and()
            .withUser(managementUsername).password(managementPassword)
                .roles(ADMIN_USER);
    }

    @Configuration
    @Order(1)                                                        
    public static class ManagementWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
        protected void configure(HttpSecurity http) throws Exception {
            http
                .antMatcher(managementContextPath+"/**")                               
                .authorizeRequests()
                    .anyRequest().hasRole("ADMIN_USER")
                    .and()
                .httpBasic();
        }
    }

    @Configuration                                                   
    public static class DefaultWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .authorizeRequests()
                    .anyRequest().hasRole("API_USER")
                    .and()
                .httpBasic()
        }
    }
}

请阅读参考文档了解详情。

答案 2 :(得分:0)

如果我改变了,hyness的答案就有用了:

..
.antMatchers(managementContextPath + "/**").hasRole(ADMIN_USER)
.antMatchers("/**").hasRole(API_USER)

..
.requestMatchers(request -> !request.getContextPath().startsWith(managementContextPath)).hasRole(API)
.antMatchers("/**").not().hasRole(API)
.antMatchers(managementContextPath + "/**").hasRole(ADMIN)