在使用Spring Boot的client_credentials oauth2 Flow中,主体为空。
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