繁体   English   中英

Spring OAuth2 授权服务器,带有使用基本身份验证保护的 Actuator 端点

[英]Spring OAuth2 Authorization Server with Actuator endpoints secured with basic auth

我有 Spring Spring OAuth2 授权服务器。 它是我的微服务之一(称为用户管理)。 它在数据库中保存用户和密码,但也保存一些其他“安全相关”实体。 这意味着我有 UserDetailsS​​ervice 的自定义实现,它包装了 Spring Security 操作的用户加载。 这个微服务是授权服务器,但它也是资源服务器,因为有一些与用户、组织、组织成员等相关的持久性和域逻辑......我的大多数 REST 端点都使用标头中的 OAuth2 令牌访问,一切正常。

但我也在使用通常由 Spring Boot 管理服务器访问的 Spring Actuator。 对于这些端点,我使用 Http 基本身份验证,因此我为 /actuator/** 端点使用了一些自定义 WebSecurityConfigurerAdapter。 在所有微服务中,我都有用户访问 application.yaml 配置中定义的这些执行器端点,并且它工作正常。 但是...在这种具有自定义 UserDetailsS​​ervice 实现的用户管理的情况下,它不起作用。

问题是,当对执行器端点调用执行基本身份验证时,DaoAuthenticationProvider 对我的自定义 UserDetailsS​​ervice 有引用,该服务试图在我的数据库中查找用户,但它不存在。 当这种情况发生在所有其他微服务中时,UserDetailsS​​ervice 的 InMemoryUserDetailsManager 实现(由 DaoAuthenticationProvider 使用)包含来自 application.yaml 的用户。

知道如何解决或解决问题吗?

  • 创建执行器端点访问数据库的用户? 我不喜欢它,因为它与我的其他微服务不同
  • 创建一个委托 UserDetailsS​​ervice 来检查两个用户存储? 我不确定如何配置它,因为 InMemoryUserDetailsManager 看起来不像托管 bean,所以有一些手动编程。
  • 或者有什么不同的正确方法? 如何配置它?

非常感谢,卢卡斯

经过一些调查,我发现解决方案看起来很不错。 我为执行器端点创建了专用配置,我可以在其中设置 UserDetailsS​​ervice 的专用实现。 我选择了 InMemoryUserDetailsManager,当您不使用自定义实现时,它会用作默认值。

这意味着 WebSecurityConfigurerAdapter 的其他实例和 AuthorizationServerConfigurerAdapter 的实现不会干扰这些执行器端点的安全性

@Configuration
@Order(1)
public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

    @Autowired
    private InMemoryUserDetailsManager inMemoryUserDetailsManager;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.userDetailsService(inMemoryUserDetailsManager)
                .antMatcher("/actuator/**").httpBasic().and()
                .csrf().disable()
                .headers().disable();
    }
}

我必须手动创建 InMemoryUserDetailsManager 的实例并从配置中注入值。

    @Value("${spring.security.user.name}")
    private String systemUserName;

    @Value("${spring.security.user.password}")
    private String systemUserPassword;

    @Bean
    public InMemoryUserDetailsManager inMemoryUserDetailsManager()
    {
        List<UserDetails> userDetailsList = new ArrayList<>();
        userDetailsList.add(User.withUsername(systemUserName).password(systemUserPassword).authorities("USER").build());

        return new InMemoryUserDetailsManager(userDetailsList);
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM