如何获取 Spring Boot 和 OAuth2 示例以使用默认密码授予凭据以外的其他凭据

Posted

技术标签:

【中文标题】如何获取 Spring Boot 和 OAuth2 示例以使用默认密码授予凭据以外的其他凭据【英文标题】:How to get Spring Boot and OAuth2 example to use password grant credentials other than the default 【发布时间】:2014-12-24 15:30:42 【问题描述】:

我正在关注 Dave Syer 的基本 Spring Boot OAuth2 示例:https://github.com/dsyer/sparklr-boot/blob/master/src/main/java/demo/Application.java

@Configuration
@ComponentScan
@EnableAutoConfiguration
@RestController
public class Application 

    public static void main(String[] args) 
        SpringApplication.run(Application.class, args);
    

    @RequestMapping("/")
    public String home() 
        return "Hello World";
    

    @Configuration
    @EnableResourceServer
    protected static class ResourceServer extends ResourceServerConfigurerAdapter 

        @Override
        public void configure(HttpSecurity http) throws Exception 
            // @formatter:off
            http
                // Just for laughs, apply OAuth protection to only 2 resources
                .requestMatchers().antMatchers("/","/admin/beans").and()
                .authorizeRequests()
                .anyRequest().access("#oauth2.hasScope('read')");
            // @formatter:on
        

        @Override
        public void configure(ResourceServerSecurityConfigurer resources) throws Exception 
            resources.resourceId("sparklr");
        

    

    @Configuration
    @EnableAuthorizationServer
    protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter 

        @Autowired
        private AuthenticationManager authenticationManager;

        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception 
            endpoints.authenticationManager(authenticationManager);
        

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception 
            // @formatter:off
            clients.inMemory()
                .withClient("my-trusted-client")
                    .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
                    .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
                    .scopes("read", "write", "trust")
                    .resourceIds("sparklr")
                    .accessTokenValiditySeconds(60)
            .and()
                .withClient("my-client-with-registered-redirect")
                    .authorizedGrantTypes("authorization_code")
                    .authorities("ROLE_CLIENT")
                    .scopes("read", "trust")
                    .resourceIds("sparklr")
                    .redirectUris("http://anywhere?key=value")
            .and()
                .withClient("my-client-with-secret")
                    .authorizedGrantTypes("client_credentials", "password")
                    .authorities("ROLE_CLIENT")
                    .scopes("read")
                    .resourceIds("sparklr")
                    .secret("secret");
        // @formatter:on
        

    

该示例适用于两种类型的授权,但密码授权使用 Spring Boot 默认安全用户(在启动期间回显“使用默认安全密码:927ca0a0-634a-4671-bd1c-1323a866618a”的用户) .

我的问题是如何覆盖默认用户帐户并实际依赖 WebSecurityConfig?我添加了这样的部分:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
protected static class WebSecurityConfig extends WebSecurityConfigurerAdapter 
    @Override
    protected void configure(AuthenticationManagerBuilder authManagerBuilder)
            throws Exception 
        authManagerBuilder.inMemoryAuthentication().withUser("user")
                .password("password").roles("USER");
    

但它似乎并没有覆盖默认的 Spring 用户/密码,即使文档建议它应该这样做。

让这个工作我缺少什么?

【问题讨论】:

不应该,除非您将@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) 添加到其中。您可以通过设置属性security.user.namesecurity.user.password 在application.properties 文件中设置默认用户名/密码。有关更多属性,请参阅reference guide。 这里有一个更好的示例(更新更多):github.com/spring-projects/spring-security-oauth/blob/master/…。 authenticationManager 方法是 2.0.4 快照中的一个新覆盖(如果要与 2.0.3 一起使用,请查看实现)。 @DaveSyer 示例没有为我运行,“创建名为 'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration' 的 bean 时出错” 对我有用,所有测试都是绿色的(并且您的错误片段太小而无法诊断问题)。您如何构建和运行此应用程序? 【参考方案1】:

由于我还在 2.0.3 上,我尝试了更多的东西,这似乎是有效的:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
protected static class WebSecurityConfig extends WebSecurityConfigurerAdapter 

    @Override
    protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception 
        authManagerBuilder
            .inMemoryAuthentication()
                .withUser("user1").password("password1").roles("USER").and()
                .withUser("admin1").password("password1").roles("ADMIN");
    

    @Bean
    @Override
    public AuthenticationManager authenticationManager() throws Exception 
        return super.authenticationManager();
    

通过显式定义 authenticationManager bean,内置的用户身份验证消失了,它开始依赖我自己的 inMemoryAuthentication。当 2.0.4 发布时,我会重新评估 Dave 上面发布的解决方案,因为它看起来会更优雅。

【讨论】:

我认为当您需要在 OAuth 服务器中配置静态页面并且它们需要公开时,此解决方案更合适。您可以覆盖 configure(HttpSecurity http)configure(WebSecurity web) 并为此目的定义特定的 antMatchers 您知道如何将用户存储在数据库中并在此时检查他们的凭据吗?【参考方案2】:
@Configuration
protected static class AuthenticationManagerConfiguration extends GlobalAuthenticationConfigurerAdapter 

        @Override
        public void init(AuthenticationManagerBuilder auth) throws Exception 
            auth.inMemoryAuthentication().withUser("min").password("min").roles("USER");
        

    

【讨论】:

是的,这比我在 2.0.3 中使用的解决方案要好得多。

以上是关于如何获取 Spring Boot 和 OAuth2 示例以使用默认密码授予凭据以外的其他凭据的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring Boot 2 oauth2 中获取令牌?

如何在 Spring Boot OAuth2 的 SecurityContextHolder 中获取 JWT 令牌?

如何使用 Angular -> Spring Boot Oauth2 -> Keycloak 获取 keycloak 令牌

Spring boot security oauth2 从 cookie 获取 access_token

Spring Boot OAuth2 - 无法从令牌获取用户详细信息

创建隐式JWT时的Spring Boot OAuth2?