Making an Authorization Server application a ResourceServer and OAuth2 client












0















I have an application which is my Authorization Server.It is also a ResourceServer and also a OAuth2 client. I am using JWT token. Everything seems to be working except Server to Server authentication between the Auth Server and other services, when the Authorization Server application tries to call another service e.g



ResponseEntity<Notification> restExchange =oAuth2RestTemplate.exchange(
"http://notifications-service/v1/notifications", HttpMethod.POST, null, Notification.class);


i get the following error:



Error creating bean with name 'scopedTarget.oauth2ClientContext': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.


The following are my config classes:



@Configuration
@EnableAuthorizationServer
public class OAuth2Configuration extends
AuthorizationServerConfigurerAdapter {
@Autowired
@Qualifier("dataSource")
private DataSource dataSource;
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private PasswordEncoder passwordEncoder;
@Value("classpath:schema.sql")
private Resource schemaScript;


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

@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new CustomAccessTokenConverter();
KeyStoreKeyFactory keyStoreKeyFactory =
new KeyStoreKeyFactory(new ClassPathResource("jwt.jks"), "#####".toCharArray());
converter.setKeyPair(keyStoreKeyFactory.getKeyPair("jwt"));
return converter;
}

@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource).passwordEncoder(passwordEncoder);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints.tokenStore(tokenStore()).tokenEnhancer(jwtAccessTokenConverter())
.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService);
}

@Bean
public DataSourceInitializer dataSourceInitializer() {
final DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource);
initializer.setDatabasePopulator(databasePopulator());
return initializer;
}

private DatabasePopulator databasePopulator() {
final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
populator.addScript(schemaScript);
return populator;
}


}



@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends
ResourceServerConfigurerAdapter {
private final TokenStore tokenStore;
@Value("${security.oauth2.resource.id}")
private String resourceId;

public ResourceServerConfiguration(TokenStore tokenStore) {
this.tokenStore = tokenStore;
}

@Override
public void configure(HttpSecurity http) throws Exception {
http.cors()
.and().csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.antMatchers("/browser/**").permitAll()
.antMatchers("/swagger-ui.html").permitAll()
.antMatchers("/v2/api-docs/**").permitAll()
.antMatchers("/v2/api-docs").permitAll()
.antMatchers("/v1/user-accounts/sign-up").permitAll()
.anyRequest().authenticated();
}

@Override
public void configure(ResourceServerSecurityConfigurer config) {
config.tokenServices(tokenServices());
config.resourceId(resourceId);
}


@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore);
return defaultTokenServices;
}


}



@Configuration
@EnableOAuth2Client
public class ClientConfiguration {

@LoadBalanced
@Bean
public OAuth2RestTemplate oauth2RestTemplate(OAuth2ClientContext
oauth2ClientContext,
OAuth2ProtectedResourceDetails details) {
return new OAuth2RestTemplate(details, oauth2ClientContext);
}


}



public class CustomAccessTokenConverter extends JwtAccessTokenConverter {
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
Map<String, Object> additionalInformation = new LinkedHashMap<String, Object>(accessToken.getAdditionalInformation());
if(!authentication.isClientOnly()){
UserAccount userAccount = (UserAccount) authentication.getPrincipal();
additionalInformation.put("email", userAccount.getContactDetails().getEmail());
}
DefaultOAuth2AccessToken customAccessToken = new DefaultOAuth2AccessToken(accessToken);
customAccessToken.setAdditionalInformation(additionalInformation);
return super.enhance(customAccessToken, authentication);
}


}



@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;

@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}

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

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}

@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
web.ignoring().antMatchers("/v2/api-docs", "/configuration/**",
"/swagger-resources/**", "/swagger-ui.html", "/webjars/**", "/api-docs/**");
}

@Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.csrf().disable();
}


}



And my pom.xml is as follows:



<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.####.onlinelibrary</groupId>
<artifactId>online-library-authorization-service-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<guava.version>25.1-jre</guava.version>
<springfox.swagger2.version>2.9.2</springfox.swagger2.version>
<spring-cloud.version>Finchley.SR1</spring-cloud.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox.swagger2.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${springfox.swagger2.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>com.####.onlinelibrary</groupId>
<artifactId>online-library-authorization-service-data</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.####.onlinelibrary</groupId>
<artifactId>online-library-authorization-service-business</artifactId>
<version>${project.version}</version>
</dependency>

</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>











share|improve this question



























    0















    I have an application which is my Authorization Server.It is also a ResourceServer and also a OAuth2 client. I am using JWT token. Everything seems to be working except Server to Server authentication between the Auth Server and other services, when the Authorization Server application tries to call another service e.g



    ResponseEntity<Notification> restExchange =oAuth2RestTemplate.exchange(
    "http://notifications-service/v1/notifications", HttpMethod.POST, null, Notification.class);


    i get the following error:



    Error creating bean with name 'scopedTarget.oauth2ClientContext': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.


    The following are my config classes:



    @Configuration
    @EnableAuthorizationServer
    public class OAuth2Configuration extends
    AuthorizationServerConfigurerAdapter {
    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource;
    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Value("classpath:schema.sql")
    private Resource schemaScript;


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

    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
    JwtAccessTokenConverter converter = new CustomAccessTokenConverter();
    KeyStoreKeyFactory keyStoreKeyFactory =
    new KeyStoreKeyFactory(new ClassPathResource("jwt.jks"), "#####".toCharArray());
    converter.setKeyPair(keyStoreKeyFactory.getKeyPair("jwt"));
    return converter;
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
    oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
    }
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    clients.jdbc(dataSource).passwordEncoder(passwordEncoder);
    }
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
    endpoints.tokenStore(tokenStore()).tokenEnhancer(jwtAccessTokenConverter())
    .authenticationManager(authenticationManager)
    .userDetailsService(userDetailsService);
    }

    @Bean
    public DataSourceInitializer dataSourceInitializer() {
    final DataSourceInitializer initializer = new DataSourceInitializer();
    initializer.setDataSource(dataSource);
    initializer.setDatabasePopulator(databasePopulator());
    return initializer;
    }

    private DatabasePopulator databasePopulator() {
    final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
    populator.addScript(schemaScript);
    return populator;
    }


    }



    @Configuration
    @EnableResourceServer
    public class ResourceServerConfiguration extends
    ResourceServerConfigurerAdapter {
    private final TokenStore tokenStore;
    @Value("${security.oauth2.resource.id}")
    private String resourceId;

    public ResourceServerConfiguration(TokenStore tokenStore) {
    this.tokenStore = tokenStore;
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
    http.cors()
    .and().csrf().disable()
    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
    .and().authorizeRequests()
    .antMatchers("/").permitAll()
    .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
    .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
    .antMatchers("/browser/**").permitAll()
    .antMatchers("/swagger-ui.html").permitAll()
    .antMatchers("/v2/api-docs/**").permitAll()
    .antMatchers("/v2/api-docs").permitAll()
    .antMatchers("/v1/user-accounts/sign-up").permitAll()
    .anyRequest().authenticated();
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer config) {
    config.tokenServices(tokenServices());
    config.resourceId(resourceId);
    }


    @Bean
    @Primary
    public DefaultTokenServices tokenServices() {
    DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
    defaultTokenServices.setTokenStore(tokenStore);
    return defaultTokenServices;
    }


    }



    @Configuration
    @EnableOAuth2Client
    public class ClientConfiguration {

    @LoadBalanced
    @Bean
    public OAuth2RestTemplate oauth2RestTemplate(OAuth2ClientContext
    oauth2ClientContext,
    OAuth2ProtectedResourceDetails details) {
    return new OAuth2RestTemplate(details, oauth2ClientContext);
    }


    }



    public class CustomAccessTokenConverter extends JwtAccessTokenConverter {
    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
    Map<String, Object> additionalInformation = new LinkedHashMap<String, Object>(accessToken.getAdditionalInformation());
    if(!authentication.isClientOnly()){
    UserAccount userAccount = (UserAccount) authentication.getPrincipal();
    additionalInformation.put("email", userAccount.getContactDetails().getEmail());
    }
    DefaultOAuth2AccessToken customAccessToken = new DefaultOAuth2AccessToken(accessToken);
    customAccessToken.setAdditionalInformation(additionalInformation);
    return super.enhance(customAccessToken, authentication);
    }


    }



    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;

    @Bean
    public PasswordEncoder passwordEncoder() {
    return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }

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

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Override
    public void configure(WebSecurity web) {
    web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
    web.ignoring().antMatchers("/v2/api-docs", "/configuration/**",
    "/swagger-resources/**", "/swagger-ui.html", "/webjars/**", "/api-docs/**");
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
    http
    .authorizeRequests()
    .anyRequest().authenticated()
    .and()
    .httpBasic()
    .and()
    .csrf().disable();
    }


    }



    And my pom.xml is as follows:



    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.####.onlinelibrary</groupId>
    <artifactId>online-library-authorization-service-api</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.6.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <guava.version>25.1-jre</guava.version>
    <springfox.swagger2.version>2.9.2</springfox.swagger2.version>
    <spring-cloud.version>Finchley.SR1</spring-cloud.version>
    </properties>

    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.security.oauth.boot</groupId>
    <artifactId>spring-security-oauth2-autoconfigure</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    </dependency>
    <dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>${guava.version}</version>
    </dependency>
    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>${springfox.swagger2.version}</version>
    </dependency>
    <dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>${springfox.swagger2.version}</version>
    </dependency>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
    <groupId>com.####.onlinelibrary</groupId>
    <artifactId>online-library-authorization-service-data</artifactId>
    <version>${project.version}</version>
    </dependency>
    <dependency>
    <groupId>com.####.onlinelibrary</groupId>
    <artifactId>online-library-authorization-service-business</artifactId>
    <version>${project.version}</version>
    </dependency>

    </dependencies>
    <dependencyManagement>
    <dependencies>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-dependencies</artifactId>
    <version>${spring-cloud.version}</version>
    <type>pom</type>
    <scope>import</scope>
    </dependency>
    </dependencies>
    </dependencyManagement>
    <build>
    <plugins>
    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
    <addResources>true</addResources>
    </configuration>
    </plugin>
    </plugins>
    </build>











    share|improve this question

























      0












      0








      0








      I have an application which is my Authorization Server.It is also a ResourceServer and also a OAuth2 client. I am using JWT token. Everything seems to be working except Server to Server authentication between the Auth Server and other services, when the Authorization Server application tries to call another service e.g



      ResponseEntity<Notification> restExchange =oAuth2RestTemplate.exchange(
      "http://notifications-service/v1/notifications", HttpMethod.POST, null, Notification.class);


      i get the following error:



      Error creating bean with name 'scopedTarget.oauth2ClientContext': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.


      The following are my config classes:



      @Configuration
      @EnableAuthorizationServer
      public class OAuth2Configuration extends
      AuthorizationServerConfigurerAdapter {
      @Autowired
      @Qualifier("dataSource")
      private DataSource dataSource;
      @Autowired
      @Qualifier("authenticationManagerBean")
      private AuthenticationManager authenticationManager;
      @Autowired
      private UserDetailsService userDetailsService;
      @Autowired
      private PasswordEncoder passwordEncoder;
      @Value("classpath:schema.sql")
      private Resource schemaScript;


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

      @Bean
      public JwtAccessTokenConverter jwtAccessTokenConverter() {
      JwtAccessTokenConverter converter = new CustomAccessTokenConverter();
      KeyStoreKeyFactory keyStoreKeyFactory =
      new KeyStoreKeyFactory(new ClassPathResource("jwt.jks"), "#####".toCharArray());
      converter.setKeyPair(keyStoreKeyFactory.getKeyPair("jwt"));
      return converter;
      }

      @Override
      public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
      oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
      }
      @Override
      public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
      clients.jdbc(dataSource).passwordEncoder(passwordEncoder);
      }
      @Override
      public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
      endpoints.tokenStore(tokenStore()).tokenEnhancer(jwtAccessTokenConverter())
      .authenticationManager(authenticationManager)
      .userDetailsService(userDetailsService);
      }

      @Bean
      public DataSourceInitializer dataSourceInitializer() {
      final DataSourceInitializer initializer = new DataSourceInitializer();
      initializer.setDataSource(dataSource);
      initializer.setDatabasePopulator(databasePopulator());
      return initializer;
      }

      private DatabasePopulator databasePopulator() {
      final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
      populator.addScript(schemaScript);
      return populator;
      }


      }



      @Configuration
      @EnableResourceServer
      public class ResourceServerConfiguration extends
      ResourceServerConfigurerAdapter {
      private final TokenStore tokenStore;
      @Value("${security.oauth2.resource.id}")
      private String resourceId;

      public ResourceServerConfiguration(TokenStore tokenStore) {
      this.tokenStore = tokenStore;
      }

      @Override
      public void configure(HttpSecurity http) throws Exception {
      http.cors()
      .and().csrf().disable()
      .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
      .and().authorizeRequests()
      .antMatchers("/").permitAll()
      .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
      .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
      .antMatchers("/browser/**").permitAll()
      .antMatchers("/swagger-ui.html").permitAll()
      .antMatchers("/v2/api-docs/**").permitAll()
      .antMatchers("/v2/api-docs").permitAll()
      .antMatchers("/v1/user-accounts/sign-up").permitAll()
      .anyRequest().authenticated();
      }

      @Override
      public void configure(ResourceServerSecurityConfigurer config) {
      config.tokenServices(tokenServices());
      config.resourceId(resourceId);
      }


      @Bean
      @Primary
      public DefaultTokenServices tokenServices() {
      DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
      defaultTokenServices.setTokenStore(tokenStore);
      return defaultTokenServices;
      }


      }



      @Configuration
      @EnableOAuth2Client
      public class ClientConfiguration {

      @LoadBalanced
      @Bean
      public OAuth2RestTemplate oauth2RestTemplate(OAuth2ClientContext
      oauth2ClientContext,
      OAuth2ProtectedResourceDetails details) {
      return new OAuth2RestTemplate(details, oauth2ClientContext);
      }


      }



      public class CustomAccessTokenConverter extends JwtAccessTokenConverter {
      @Override
      public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
      Map<String, Object> additionalInformation = new LinkedHashMap<String, Object>(accessToken.getAdditionalInformation());
      if(!authentication.isClientOnly()){
      UserAccount userAccount = (UserAccount) authentication.getPrincipal();
      additionalInformation.put("email", userAccount.getContactDetails().getEmail());
      }
      DefaultOAuth2AccessToken customAccessToken = new DefaultOAuth2AccessToken(accessToken);
      customAccessToken.setAdditionalInformation(additionalInformation);
      return super.enhance(customAccessToken, authentication);
      }


      }



      @Configuration
      @EnableWebSecurity
      public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
      @Autowired
      private UserDetailsService userDetailsService;

      @Bean
      public PasswordEncoder passwordEncoder() {
      return PasswordEncoderFactories.createDelegatingPasswordEncoder();
      }

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

      @Override
      protected void configure(AuthenticationManagerBuilder auth) throws Exception {
      auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
      }

      @Override
      public void configure(WebSecurity web) {
      web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
      web.ignoring().antMatchers("/v2/api-docs", "/configuration/**",
      "/swagger-resources/**", "/swagger-ui.html", "/webjars/**", "/api-docs/**");
      }

      @Override
      public void configure(HttpSecurity http) throws Exception {
      http
      .authorizeRequests()
      .anyRequest().authenticated()
      .and()
      .httpBasic()
      .and()
      .csrf().disable();
      }


      }



      And my pom.xml is as follows:



      <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
      http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.####.onlinelibrary</groupId>
      <artifactId>online-library-authorization-service-api</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>jar</packaging>

      <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.0.6.RELEASE</version>
      <relativePath/> <!-- lookup parent from repository -->
      </parent>

      <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
      <java.version>1.8</java.version>
      <guava.version>25.1-jre</guava.version>
      <springfox.swagger2.version>2.9.2</springfox.swagger2.version>
      <spring-cloud.version>Finchley.SR1</spring-cloud.version>
      </properties>

      <dependencies>
      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
      </dependency>
      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>
      </dependency>
      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
      <groupId>org.springframework.security.oauth.boot</groupId>
      <artifactId>spring-security-oauth2-autoconfigure</artifactId>
      </dependency>
      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
      </dependency>
      <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
      <version>${guava.version}</version>
      </dependency>
      <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      </dependency>
      <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger2</artifactId>
      <version>${springfox.swagger2.version}</version>
      </dependency>
      <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger-ui</artifactId>
      <version>${springfox.swagger2.version}</version>
      </dependency>
      <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-config</artifactId>
      </dependency>
      <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
      </dependency>
      <dependency>
      <groupId>com.####.onlinelibrary</groupId>
      <artifactId>online-library-authorization-service-data</artifactId>
      <version>${project.version}</version>
      </dependency>
      <dependency>
      <groupId>com.####.onlinelibrary</groupId>
      <artifactId>online-library-authorization-service-business</artifactId>
      <version>${project.version}</version>
      </dependency>

      </dependencies>
      <dependencyManagement>
      <dependencies>
      <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-dependencies</artifactId>
      <version>${spring-cloud.version}</version>
      <type>pom</type>
      <scope>import</scope>
      </dependency>
      </dependencies>
      </dependencyManagement>
      <build>
      <plugins>
      <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <configuration>
      <addResources>true</addResources>
      </configuration>
      </plugin>
      </plugins>
      </build>











      share|improve this question














      I have an application which is my Authorization Server.It is also a ResourceServer and also a OAuth2 client. I am using JWT token. Everything seems to be working except Server to Server authentication between the Auth Server and other services, when the Authorization Server application tries to call another service e.g



      ResponseEntity<Notification> restExchange =oAuth2RestTemplate.exchange(
      "http://notifications-service/v1/notifications", HttpMethod.POST, null, Notification.class);


      i get the following error:



      Error creating bean with name 'scopedTarget.oauth2ClientContext': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.


      The following are my config classes:



      @Configuration
      @EnableAuthorizationServer
      public class OAuth2Configuration extends
      AuthorizationServerConfigurerAdapter {
      @Autowired
      @Qualifier("dataSource")
      private DataSource dataSource;
      @Autowired
      @Qualifier("authenticationManagerBean")
      private AuthenticationManager authenticationManager;
      @Autowired
      private UserDetailsService userDetailsService;
      @Autowired
      private PasswordEncoder passwordEncoder;
      @Value("classpath:schema.sql")
      private Resource schemaScript;


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

      @Bean
      public JwtAccessTokenConverter jwtAccessTokenConverter() {
      JwtAccessTokenConverter converter = new CustomAccessTokenConverter();
      KeyStoreKeyFactory keyStoreKeyFactory =
      new KeyStoreKeyFactory(new ClassPathResource("jwt.jks"), "#####".toCharArray());
      converter.setKeyPair(keyStoreKeyFactory.getKeyPair("jwt"));
      return converter;
      }

      @Override
      public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
      oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
      }
      @Override
      public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
      clients.jdbc(dataSource).passwordEncoder(passwordEncoder);
      }
      @Override
      public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
      endpoints.tokenStore(tokenStore()).tokenEnhancer(jwtAccessTokenConverter())
      .authenticationManager(authenticationManager)
      .userDetailsService(userDetailsService);
      }

      @Bean
      public DataSourceInitializer dataSourceInitializer() {
      final DataSourceInitializer initializer = new DataSourceInitializer();
      initializer.setDataSource(dataSource);
      initializer.setDatabasePopulator(databasePopulator());
      return initializer;
      }

      private DatabasePopulator databasePopulator() {
      final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
      populator.addScript(schemaScript);
      return populator;
      }


      }



      @Configuration
      @EnableResourceServer
      public class ResourceServerConfiguration extends
      ResourceServerConfigurerAdapter {
      private final TokenStore tokenStore;
      @Value("${security.oauth2.resource.id}")
      private String resourceId;

      public ResourceServerConfiguration(TokenStore tokenStore) {
      this.tokenStore = tokenStore;
      }

      @Override
      public void configure(HttpSecurity http) throws Exception {
      http.cors()
      .and().csrf().disable()
      .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
      .and().authorizeRequests()
      .antMatchers("/").permitAll()
      .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
      .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
      .antMatchers("/browser/**").permitAll()
      .antMatchers("/swagger-ui.html").permitAll()
      .antMatchers("/v2/api-docs/**").permitAll()
      .antMatchers("/v2/api-docs").permitAll()
      .antMatchers("/v1/user-accounts/sign-up").permitAll()
      .anyRequest().authenticated();
      }

      @Override
      public void configure(ResourceServerSecurityConfigurer config) {
      config.tokenServices(tokenServices());
      config.resourceId(resourceId);
      }


      @Bean
      @Primary
      public DefaultTokenServices tokenServices() {
      DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
      defaultTokenServices.setTokenStore(tokenStore);
      return defaultTokenServices;
      }


      }



      @Configuration
      @EnableOAuth2Client
      public class ClientConfiguration {

      @LoadBalanced
      @Bean
      public OAuth2RestTemplate oauth2RestTemplate(OAuth2ClientContext
      oauth2ClientContext,
      OAuth2ProtectedResourceDetails details) {
      return new OAuth2RestTemplate(details, oauth2ClientContext);
      }


      }



      public class CustomAccessTokenConverter extends JwtAccessTokenConverter {
      @Override
      public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
      Map<String, Object> additionalInformation = new LinkedHashMap<String, Object>(accessToken.getAdditionalInformation());
      if(!authentication.isClientOnly()){
      UserAccount userAccount = (UserAccount) authentication.getPrincipal();
      additionalInformation.put("email", userAccount.getContactDetails().getEmail());
      }
      DefaultOAuth2AccessToken customAccessToken = new DefaultOAuth2AccessToken(accessToken);
      customAccessToken.setAdditionalInformation(additionalInformation);
      return super.enhance(customAccessToken, authentication);
      }


      }



      @Configuration
      @EnableWebSecurity
      public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
      @Autowired
      private UserDetailsService userDetailsService;

      @Bean
      public PasswordEncoder passwordEncoder() {
      return PasswordEncoderFactories.createDelegatingPasswordEncoder();
      }

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

      @Override
      protected void configure(AuthenticationManagerBuilder auth) throws Exception {
      auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
      }

      @Override
      public void configure(WebSecurity web) {
      web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
      web.ignoring().antMatchers("/v2/api-docs", "/configuration/**",
      "/swagger-resources/**", "/swagger-ui.html", "/webjars/**", "/api-docs/**");
      }

      @Override
      public void configure(HttpSecurity http) throws Exception {
      http
      .authorizeRequests()
      .anyRequest().authenticated()
      .and()
      .httpBasic()
      .and()
      .csrf().disable();
      }


      }



      And my pom.xml is as follows:



      <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
      http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.####.onlinelibrary</groupId>
      <artifactId>online-library-authorization-service-api</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>jar</packaging>

      <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.0.6.RELEASE</version>
      <relativePath/> <!-- lookup parent from repository -->
      </parent>

      <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
      <java.version>1.8</java.version>
      <guava.version>25.1-jre</guava.version>
      <springfox.swagger2.version>2.9.2</springfox.swagger2.version>
      <spring-cloud.version>Finchley.SR1</spring-cloud.version>
      </properties>

      <dependencies>
      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
      </dependency>
      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>
      </dependency>
      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
      <groupId>org.springframework.security.oauth.boot</groupId>
      <artifactId>spring-security-oauth2-autoconfigure</artifactId>
      </dependency>
      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
      </dependency>
      <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
      <version>${guava.version}</version>
      </dependency>
      <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      </dependency>
      <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger2</artifactId>
      <version>${springfox.swagger2.version}</version>
      </dependency>
      <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger-ui</artifactId>
      <version>${springfox.swagger2.version}</version>
      </dependency>
      <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-config</artifactId>
      </dependency>
      <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
      </dependency>
      <dependency>
      <groupId>com.####.onlinelibrary</groupId>
      <artifactId>online-library-authorization-service-data</artifactId>
      <version>${project.version}</version>
      </dependency>
      <dependency>
      <groupId>com.####.onlinelibrary</groupId>
      <artifactId>online-library-authorization-service-business</artifactId>
      <version>${project.version}</version>
      </dependency>

      </dependencies>
      <dependencyManagement>
      <dependencies>
      <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-dependencies</artifactId>
      <version>${spring-cloud.version}</version>
      <type>pom</type>
      <scope>import</scope>
      </dependency>
      </dependencies>
      </dependencyManagement>
      <build>
      <plugins>
      <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <configuration>
      <addResources>true</addResources>
      </configuration>
      </plugin>
      </plugins>
      </build>








      spring-security-oauth2 server-to-server






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 25 '18 at 9:24









      FactFact

      12




      12
























          0






          active

          oldest

          votes











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53466168%2fmaking-an-authorization-server-application-a-resourceserver-and-oauth2-client%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53466168%2fmaking-an-authorization-server-application-a-resourceserver-and-oauth2-client%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          404 Error Contact Form 7 ajax form submitting

          How to know if a Active Directory user can login interactively

          Refactoring coordinates for Minecraft Pi buildings written in Python