【问题标题】:Connecting OAuth2 resource server with authentication server连接 OAuth2 资源服务器和认证服务器
【发布时间】:2018-05-01 00:54:01
【问题描述】:

我正在尝试制作一个示例 OAuth2 Spring 授权和资源服务器。我的意图是实现两个独立的应用程序——一个代表授权服务器,另一个代表资源服务器。由于我是 Spring Security 的初学者,我想我需要一些指导来完成我的任务。

我已经设法使用内存令牌存储(名为“OAuth”的应用程序)实现了一个简单的授权服务器。

AuthServerOAuth2Config.java

@Configuration
@EnableAuthorizationServer
public class AuthServerOAuth2Config extends AuthorizationServerConfigurerAdapter {
    private static final String RESOURCE_ID = "myResource";

    @Autowired
    private UserApprovalHandler handler;

    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authManager;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
         // @formatter:off
         clients.inMemory()
                 .withClient("test")
                    .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
                    .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
                    .scopes("read", "write", "trust")
                    .resourceIds(RESOURCE_ID)
                    .secret("test")
                    .accessTokenValiditySeconds(300).//invalid after 5 minutes.
                    refreshTokenValiditySeconds(600);//refresh after 10 minutes.
         // @formatter:on
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(tokenStore()).userApprovalHandler(handler).authenticationManager(authManager);
    }

    @Bean
    public TokenStore tokenStore() {
        return new InMemoryTokenStore();
    }

}

OAuth2SecurityConfig.java

@Configuration
@EnableWebSecurity
public class OAuth2SecurityConfig extends WebSecurityConfigurerAdapter {
    private static final Logger LOG = LoggerFactory.getLogger(OAuth2SecurityConfig.class);

    @Autowired
    private ClientDetailsService clientService;

    @Autowired
    private DataSource dataSource;

    @Autowired
    public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
        // @formatter:off
        auth.inMemoryAuthentication()
        .withUser("javabycode").password("123456").roles("USER")
        .and()
        .withUser("admin").password("admin123").roles("ADMIN");
        // @formatter:on
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
         http
         .csrf().disable()
         .anonymous().disable()
            .authorizeRequests()
            .antMatchers("/oauth/token").permitAll();
        // @formatter:on
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public TokenStore tokenStore() {
        return new JdbcTokenStore(dataSource);
    }

    @Bean
    @Autowired
    public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore) {
        TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
        handler.setTokenStore(tokenStore);
        handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientService));
        handler.setClientDetailsService(clientService);
        return handler;
    }

    @Bean
    @Autowired
    public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception {
        TokenApprovalStore store = new TokenApprovalStore();
        store.setTokenStore(tokenStore);
        return store;
    }

}

访问http://localhost:9081/OAuth/oauth/token?grant_type=password&username=admin&password=admin123按预期返回令牌,所以我猜测授权服务器配置正常。

现在有一个资源服务器部分(名为“RestTest”的应用程序)。我设法找到了一些使用RemoteTokenServices 访问驻留在另一个应用程序中的令牌服务的示例。到目前为止,这是我的资源服务器。

OAuth2ResourceConfig.java

@Configuration
@EnableResourceServer
@EnableWebSecurity
public class OAuth2ResourceConfig extends ResourceServerConfigurerAdapter {
    private static final String RESOURCE_ID = "myResource";

    private TokenExtractor tokenExtractor = new BearerTokenExtractor();

    @Override
    public void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http.
        anonymous().disable()
        .requestMatchers().antMatchers("/v1/**")
        .and().authorizeRequests()
        .antMatchers("/v1/**").access("hasRole('ADMIN')")
        .and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
        // @formatter:on
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws 
        Exception {
         resources.tokenServices(tokenService()).resourceId(RESOURCE_ID).stateless(true);
    }

    @Primary
    @Bean
    public RemoteTokenServices tokenService() {
        RemoteTokenServices tokenService = new RemoteTokenServices();
        tokenService.setCheckTokenEndpointUrl("http://localhost:9081/OAuth/oauth/check_token/");
        tokenService.setClientId("test");
        tokenService.setClientSecret("test");
        return tokenService;
    }
}

我正在尝试保护我的 REST API (http://localhost:9081/RestTest/v1/foobar),所以我相信上面的配置是正确的,对吧?问题是当我访问v1/foobar 端点(通过邮递员)时,无需任何身份验证即可访问它。所以我认为我只是缺少配置的某些部分,但我无法弄清楚如何正确连接到授权服务器。还要提一件事 - 我没有使用 Spring Boot!

非常感谢一些指导以使我的示例工作。谢谢!

EDIT1:我已将 resourceId 添加到身份验证和资源服务器 - 不走运。 resourceId 是强制性的吗?

【问题讨论】:

    标签: rest spring-security oauth-2.0 access-token spring-security-oauth2


    【解决方案1】:

    您应该在ResourceServerAuthorizationServer 中都添加RESOURCE_ID,方式是(尽管您使用那个sn-p 更新了您的问题)

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.tokenServices(tokenService()).resourceId(RESOURCE_ID).stateless(true);
    }
    

    在您的身份验证服务器中

    .scopes("read", "write", "trust").resourceIds(RESOURCE_ID)
    

    添加一个springSecurityFilterChain,因为您在web.xml 中错过了您在评论中已经说过的内容

    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    来自spring docs

    它创建一个称为 springSecurityFilterChain 的 Servlet 过滤器,它负责您应用程序中的所有安全性(保护应用程序 URL、验证提交的用户名和密码、重定向到登录表单等) .

    【讨论】:

    • 我如何在 Spring Boot 中进行相同的配置
    • 你要配置哪个部分?过滤器?
    • Filter .. 我正在实现 spring oauth2.0 并创建了 authserver,但在配置资源服务器时遇到了一些困难。 resourceserver 和 authserver 在不同的端口上。
    • @PiyushMittal,您可以提出另一个问题来描述您的问题。
    猜你喜欢
    • 2013-08-24
    • 2018-07-08
    • 2017-04-13
    • 2019-10-27
    • 2018-08-29
    • 2017-06-23
    • 2015-05-14
    • 2016-05-21
    • 2014-07-09
    相关资源
    最近更新 更多