Spring OAuth2: всегда возвращать неверный токен - PullRequest
0 голосов
/ 30 июня 2019

Я пытаюсь реализовать OAuth2-сервер с одним сервером ресурсов с Spring Boot.Я могу запрашивать токены, но если я использую их для запроса ресурсов с сервера ресурсов, результатом всегда будет «недопустимый токен».

Это конфигурация сервера авторизации:

@Configuration
@EnableAuthorizationServer
public class AuthserverConfiguration extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authorizationCodeServices(authorizationCodeServices())
        // injects the Spring Security authentication manager (set up in WebSecurityConfiguration )
                .authenticationManager(authenticationManager)
                .tokenStore(tokenStore());
    }
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        // configure security for /oauth/check_token and /oauth/token_key endpoint
        security.tokenKeyAccess("permitAll()")
                .checkTokenAccess("permitAll()"); // should be isAuthenticated()

    }
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("clientId").secret("{noop}clientsecret")
                .authorizedGrantTypes("authorization_code", "refresh_token", "password")
                .scopes("read");
    }
    @Bean
    public TokenStore tokenStore() {
        return new InMemoryTokenStore();
    }
    @Bean
    protected AuthorizationCodeServices authorizationCodeServices() {
        // creates authorization codes, stores the codes in memory.
        return new InMemoryAuthorizationCodeServices();
    }
}

WebSecurityConfigurationis:

@EnableWebSecurity
@Configuration
@Order(SecurityProperties.BASIC_AUTH_ORDER - 20)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("user").password("{noop}password").roles("USER");
        /* for now testing with inMemoryAuthentication, later I want to use: 
         * auth.userDetailsService(userDetailsService); */
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .requestMatchers().antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access")
            .and()
            .formLogin().loginPage("/login").permitAll().failureUrl("/login?error")
            .and()
            .authorizeRequests().anyRequest().authenticated();
    }

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

И UserInfoController:

@RestController
public class UserInfoController {

    @RequestMapping(value = "/user")
    public Principal userInfo(@AuthenticationPrincipal Principal user) {
        return user;
    }
}

pom.xml содержит следующие зависимости: +

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security.oauth</groupId>
        <artifactId>spring-security-oauth2</artifactId>
        <version>2.0.5.RELEASE</version>
    </dependency>
</dependencies>

Сервер ресурсов с другой стороныстандартный проект Spring Boot с tomcat, прослушивающий GET / products (возвращающий список в формате JSON) через порт 8081. Его основной класс помечен @EnableResourceServer, а его конфигурация содержит:

security:
  oauth2:
    resource:
      user-info-uri: http://localhost:8090/user

, где 8090является портом вышеупомянутого сервера аутентификации.

Тестирование с помощью curl:

> curl clientId:clientsecret@localhost:8090/oauth/token -d grant_type=password -d username=user -d password=password -d scope=read`
{"access_token":"1cdd6dc2-42fe-4b55-b16d-78d189a88cc4","token_type":"bearer","refresh_token":"d59d78b5-43c8-4d12-b4ee-007da8548744","expires_in":43199,"scope":"read"}

> curl -H 'Authorization: Bearer 1cdd6dc2-42fe-4b55-b16d-78d189a88cc4' 'localhost:8090/oauth/check_token?token=1cdd6dc2-42fe-4b55-b16d-78d189a88cc4'
{"exp":1561956415,"user_name":"user","authorities":["ROLE_USER"],"client_id":"clientId","scope":["read"]}+ set +o xtrace

Токен кажется действительным и распознанным (если я подделаю токен, я получаю другую ошибку: "нераспознанный токен ").

Но если я пытаюсь запросить данные с сервера ресурсов с помощью токена:

> curl -H 'Authorization: Bearer 1cdd6dc2-42fe-4b55-b16d-78d189a88cc4' localhost:8081/products
{"error":"invalid_token","error_description":"Invalid access token: 1cdd6dc2-42fe-4b55-b16d-78d189a88cc4"}

Эта ошибка очень непротиворечивая, я попыталсяt различных изменений в конфигурации и даже добавление пользовательских реализаций TokenServices, UserDetailsService и т. д.

В журналах отладки я нахожу следующую строку в выходных данных сервера ресурсов каждый раз, когда я делаю запрос через curl:

Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@2b139cc0: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS

Это сбивает меня с толку, потому что Принципал не должен быть анонимным пользователем в моем понимании.

Как я могу решить эту проблему и запросить данные с моего сервера ресурсов?Любая помощь высоко ценится.

...