Principal is null with client_credentials oauth2 Flow using Spring Boot.

authorization server to generate token
resource server to protect my url with the given token 

pom.xml:

<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</groupId>
    <artifactId>switch-auth-server</artifactId>
    <version>0.0.1</version>
    <name>switch-auth-server</name>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.2.RELEASE</version>
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
        <!--    <s3.url>s3://${artifact-repo}</s3.url> -->
        <spring-cloud.version>Dalston.SR1</spring-cloud.version>
    </properties>
    <dependencies>

        <dependency>
            <groupId>com.switch.adapter</groupId>
            <artifactId>switch-auth-server-adapter</artifactId>
            <version>0.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.switch.core</groupId>
            <artifactId>switch-common-logging</artifactId>
            <version>0.0.1</version>
        </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.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
            <version>2.3.0.RELEASE</version>
        </dependency>
         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.6.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.8</version>
        </dependency>
        <!-- Thanks for using https://jar-download.com -->
    </dependencies>
</project>

authAppServer

@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
@ComponentScan(basePackages = "com.switch")
@EnableJpaRepositories(basePackages = { "com.switch.auth.repository" })
@EntityScan(basePackages = { "com.switch.adapter.auth.entity" })
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "com.switch.adapter.auth.client")
public class AuthAppServer {
    public static void main(String[] args) {
        SpringApplication.run(AuthAppServer.class, args);
    }
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

AuthorizationServer

@Configuration
@EnableAuthorizationServer
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private DataSource dataSource;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    UserAuthenticationService userDetailsService;

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

    public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
        oauthServer.checkTokenAccess("permitAll()").passwordEncoder(passwordEncoder);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        logger.info("in configure method ::");
        clients.inMemory().withClient("client4").secret(passwordEncoder.encode("prod"))
                .authorizedGrantTypes("client_credentials").scopes("read", "write");
        clients.jdbc(dataSource);

    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(tokenStore()).authenticationManager(this.authenticationManager)
                .userDetailsService(userDetailsService);
    }
}

SpringSecurityConfig

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    UserAuthenticationService authenticationService;

    @Autowired
    PasswordEncoder passwordEncoder;

     @Resource(name = "userService")
     private UserDetailsService userDetailsService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        .antMatchers("/api/**", "/test").authenticated()
        .antMatchers("/**").permitAll()
        .anyRequest().authenticated();
    }

    @Autowired
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        authenticationService.addRootUser();
        auth.userDetailsService(authenticationService).passwordEncoder(passwordEncoder);
    }

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

    @Bean
    public FilterRegistrationBean corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(0);
        return bean;
    }
}

ResourceServerConfiguration

@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

    private static final String RESOURCE_ID = "rest_api";

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.resourceId(RESOURCE_ID).stateless(false);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.anonymous().disable()
            .authorizeRequests()
            .antMatchers("/test/**").authenticated()
            .and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
    }

}

ValidateUserController

@RestController
@EnableResourceServer
public class ValidateUserController {

    @RequestMapping(value ="/validateUser", method = RequestMethod.GET)
    public Principal user(Principal user) {
        return user;
    }
 }

application.yml

security:
  oauth2:
    client:
      clientId: client4
      clientSecret: prod
      accessTokenUri: http://localhost:9090/auth-service/oauth/token
      grant-type: client_credentials
      scope: read,write
    resource:
        user-info-uri: http://localhost:9090/auth-services/validateUser
        filter-order: 3

0 Answers