之前的一篇文章讲解了spring cloud搭建使用方法:SpringBoot + SpringCloud Feign 多模块 框架搭建案例 ,这一篇 记录 spring cloud oauth2微服务 统一认证授权 框架搭建。这里依然是最简单的方式实现统一认证,是纯client模式,如果要使用数据库,用户,权限等,可以在此基础上继续开发。
1.要实现的目标
spring cloud有很多服务组件,不同的组件提供不同的服务,有第三方应用,web,app,小程序等,需要调用这些服务,需要获取token 令牌,才能访问这些服务,而且一个token 令牌可以访问所有的服务。
就像微信公众平台,阿里平i台一样,调用接口需要先获取token,调用接口带着token令牌,然后平台再对token验证,有权限才可以调用。
这就是我要实现的统一验证授权框架。
2.搭建统一认证服务 service-auth
service-auth服务 用来获取token,验证token
2.1 pom 依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<!-- 可以选择 注册到 eureka
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
-->
</dependencies>
打开spring-cloud-starter-oauth2依赖可以看到,它已经整合了spring-cloud-starter-security、spring-security-oauth2 和 spring-security-jwt 这3个基本依赖。
2.2 继承 AuthorizationServerConfigurerAdapter 配置 权限服务
/**
* 启用权限服务,作为统一鉴权服务器
* @Author: houyong
* @Date: 2019/11/14
*/
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfigurer extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserDetailsService userDetailsService;
/**
* 指定client凭证,不需要考虑用户权限,只使用 client_credentials 模式鉴权
* @param clients
* @throws Exception
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
//配置客户端凭证
clients.inMemory()
.withClient("cloudClientId")
.secret("{noop}cloudClientSecret")
.scopes("all");
}
}
2.3 启用 ResourceServer 资源服务
这里就是为了启用注解@EnableResourceServer,也有可能有更深入的配置,如果没有,加载启动类上是一样的
@Configuration
@EnableResourceServer
public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {
}
2.4 配置 启用spring security
更深入的用户,权限 ,用户数据库配置 都可以配置在这里,我这里就用最简单的默认用户权限实现
/**
* 使用Security来保护项目
* @Author: houyong
* @Date: 2019/11/13
*/
@Configuration
@EnableWebSecurity
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception{
return super.authenticationManagerBean();
}
@Override
@Bean
public UserDetailsService userDetailsServiceBean() throws Exception {
return super.userDetailsServiceBean();
}
}
2.5 获取当前用户接口
用来获取验证token的当前用户
/**
* @Author: houyong
* @Date: 2019/11/15
*/
@RestController
@Slf4j
@RequestMapping("/user")
public class UserController {
@RequestMapping("current")
public Principal user(Principal user) {
log.warn("### getCurrent"+ JSON.toJSONString(user));
return user;
}
}
2.6 启动类
@SpringBootApplication
//@EnableEurekaClient 可以选择注册到eureka
public class ServiceAuthApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceAuthApplication.class, args);
}
}
2.7 application.properties
spring.application.name=service-auth
server.port=8100
#eureka.client.service-url.defaultZone=http://127.0.0.1:8000/eureka/
2.8 测试启动认证服务 service-auth 获取token
直接访问http://localhost:8100/user/current 显示无权限
http://localhost:8100/oauth/token 获取token
选择Basic Auth 填写前面配置的客户端凭证,并且 传递body 参数 grant_type=client_credentials
使用获得的token再次访问 http://localhost:8100/user/current,返回用户信息
3.客户端服务搭建 product-server
搭建一个第三方要使用这个 service-auth 统一验证的服务,商品管理服务product-server
3.1 pom
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<!-- 可以选择 注册到 eureka
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
-->
</dependencies>
3.2 OAuth2ClientConfig 类
下面配置是为了解决 spring cloud feign 内部服务间调用 没有token的问题,因为所有接口都被保护起来了,没有token就访问不了
@Configuration
@EnableOAuth2Client //作为 Oauth2 客户端
@EnableResourceServer //提供商品服务,所以也是资源服务器
public class OAuth2ClientConfig {
/**
* 下面两个bean配置 是为了解决 feign 模式下 统一验证凭证的问题
* @return
*/
@Bean
@ConfigurationProperties(prefix = "security.oauth2.client")
public ClientCredentialsResourceDetails clientCredentialsResourceDetails() {
return new ClientCredentialsResourceDetails();
}
@Bean
public RequestInterceptor oauth2FeignRequestInterceptor(){
return new OAuth2FeignRequestInterceptor(new DefaultOAuth2ClientContext(), clientCredentialsResourceDetails());
}
}
3.3 启动类
//@EnableEurekaClient //可以开启注册到eureka
//@EnableFeignClients(basePackages = "net.itxw.demo")
@SpringBootApplication
public class ProductServerApplication {
public static void main(String[] args) {
SpringApplication.run(ProductServerApplication.class, args);
}
}
3.4.application.properties
spring.application.name=product-server
server.port=8001
#可以选择注册到eureka
#eureka.client.service-url.defaultZone=http://127.0.0.1:8000/eureka/
#spring.main.allow-bean-definition-overriding=true
#security 客户端凭证对应 service-auth 配置
security.oauth2.client.access-token-uri=http://localhost:8100/oauth/token
security.oauth2.resource.user-info-uri=http://localhost:8100/user/current
security.oauth2.client.grant-type=client_credentials
security.oauth2.client.client-id=cloudClientId
security.oauth2.client.client-secret=cloudClientSecret
3.5 编写测试controller
@RestController
public class TestController {
@RequestMapping("/getProduct")
public String getProduct(){
return "您要获取的商品来了!";
}
}
4.整体测试统一验证服务
4.1 调用product-server http://localhost:8001/getProduct
显示无权限
使用上面service-auth 获取的token 再次访问
访问成功!
spring cloud oauth2 微服务 统一认证授权 框架搭建 就这么顺利的完成了!!!