Spring Cloud下基于OAUTH2+ZUUL认证授权的实现
Spring Cloud下基于OAUTH2认证授权的实现
在Spring Cloud需要使用OAUTH2来实现多个微服务的统一认证授权,通过向OAUTH服务发送某个类型的grant type进行集中认证和授权,从而获得access_token,而这个token是受其他微服务信任的,我们在后续的访问可以通过access_token来进行,从而实现了微服务的统一认证授权。
本示例提供了四大部分:
eureka:服务注册和发现的基本模块auth:OAUTH2认证授权中心account:普通微服务,用来验证认证和授权gateway:边界网关(所有微服务都在它之后)
OAUTH2中的角色:
Resource Server:被授权访问的资源Authotization Server:OAUTH2认证授权中心Resource Owner: 用户Client:使用API的客户端(如Android 、IOS、web app)
Grant Type:
authorization_code:implicit:password:refrsh_token:
1.基础环境
使用Postgres作为账户存储,Redis作为Token存储,使用docker-compose在服务器上启动Postgres和Redis。
Redis:
image: sameersbn/redis:latest
ports:
- "6379:6379"
volumes:
- /srv/docker/redis:/var/lib/redis:Z
restart: always PostgreSQL:
restart: always
image: sameersbn/postgresql:9.6-2
ports:
- "5432:5432"
environment:
- DEBUG=false - DB_USER=wang
- DB_PASS=yunfei
- DB_NAME=order
volumes:
- /srv/docker/postgresql:/var/lib/postgresql:Z
2.auth-server
2.1 OAuth2服务配置
Redis用来存储token,服务重启后,无需重新获取token.
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private RedisConnectionFactory connectionFactory; @Bean
public RedisTokenStore tokenStore() {
return new RedisTokenStore(connectionFactory);
} @Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService)//若无,refresh_token会有UserDetailsService is required错误
.tokenStore(tokenStore());
} @Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security
.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
} @Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("android")
.scopes("xx") //此处的scopes是无用的,可以随意设置
.secret("android")
.authorizedGrantTypes("password", "authorization_code", "refresh_token")
.and()
.withClient("webapp")
.scopes("xx")
.authorizedGrantTypes("implicit");
}
}
2.2 Resource服务配置
auth-server提供user信息,所以auth-server也是一个Resource Server
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.exceptionHandling()
.authenticationEntryPoint((request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic();
}
}
@RestController
public class UserController { @GetMapping("/user")
public Principal user(Principal user){
return user;
}
}
2.3 安全配置
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter { @Bean
public UserDetailsService userDetailsService(){
return new DomainUserDetailsService();
} @Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
} @Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService())
.passwordEncoder(passwordEncoder());
} @Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
return new SecurityEvaluationContextExtension();
} //不定义没有password grant_type
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
} }
2.4 权限设计
采用用户(SysUser)<->角色(SysRole)<->权限(SysAuthotity)设置,彼此之间的关系是多对多。通过DomainUserDetailsService 加载用户和权限。
2.5 配置
spring:
profiles:
active: ${SPRING_PROFILES_ACTIVE:dev}
application:
name: auth-server jpa:
open-in-view: true
database: POSTGRESQL
show-sql: true
hibernate:
ddl-auto: update
datasource:
platform: postgres
url: jdbc:postgresql://192.168.1.140:5432/auth
username: wang
password: yunfei
driver-class-name: org.postgresql.Driver
redis:
host: 192.168.1.140 server:
port: 9999 eureka:
client:
serviceUrl:
defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/ logging.level.org.springframework.security: DEBUG logging.leve.org.springframework: DEBUG
2.6 测试数据
data.sql里初始化了两个用户admin->ROLE_ADMIN->query_demo,wyf->ROLE_USER
3.account
3.1 Resource服务配置
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter{ @Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.exceptionHandling()
.authenticationEntryPoint((request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic();
}
}
3.2 用户信息配置
account是一个简单的微服务,使用auth-server进行认证授权,在它的配置文件指定用户信息在auth-server的地址即可:
security:
oauth2:
resource:
id: order-service
user-info-uri: http://localhost:8080/uaa/user
prefer-token-info: false
3.3 权限测试控制器
具备authority未query-demo的才能访问,即为admin用户
@RestController
public class DemoController {
@GetMapping("/demo")
@PreAuthorize("hasAuthority('query-demo')")
public String getDemo(){
return "good";
}
}
4 api-gateway
api-gateway在本例中有2个作用:
本身作为一个client,使用
implicit作为外部app访问的方向代理
4.1 关闭csrf并开启Oauth2 client支持
@Configuration
@EnableOAuth2Sso
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); } }
4.2 配置
zuul:
routes:
uaa:
path: /uaa/**
sensitiveHeaders:
serviceId: auth-server
order:
path: /order/**
sensitiveHeaders:
serviceId: order-service
add-proxy-headers: true security:
oauth2:
client:
access-token-uri: http://localhost:8080/uaa/oauth/token
user-authorization-uri: http://localhost:8080/uaa/oauth/authorize
client-id: webapp
resource:
user-info-uri: http://localhost:8080/uaa/user
prefer-token-info: false
4.3 服务之间互调
feign client没有将access token放入请求头里,需定义一个OAuth2FeignRequestInterceptor的bean:
5 演示
5.1 客户端调用
使用Postman向http://localhost:8080/uaa/oauth/token发送请求获得access_token(admin用户的如7f9b54d4-fd25-4a2c-a848-ddf8f119230b)
- admin用户



wyf用户



5.2 api-gateway中的webapp调用
暂时没有做测试,下次补充。
代码开源
代码已经开源、托管到我的码云:
https://gitee.com/senhelpa-vivo/spring-cloud.git
Spring Cloud下基于OAUTH2+ZUUL认证授权的实现的更多相关文章
- Spring Cloud下基于OAUTH2认证授权的实现
GitHub(spring -boot 2.0.0):https://github.com/bigben0123/uaa-zuul 示例(spring -boot 2.0.0): https://gi ...
- Spring Cloud Zuul 网关使用与 OAuth2.0 认证授权服务
API 网关的出现的原因是微服务架构的出现,不同的微服务一般会有不同的服务地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题: 客户端会 ...
- Spring Cloud Security OAuth2.0 认证授权系列(一) 基础概念
世界上最快的捷径,就是脚踏实地,本文已收录[架构技术专栏]关注这个喜欢分享的地方. 前序 最近想搞下基于Spring Cloud的认证授权平台,总体想法是可以对服务间授权,想做一个基于Agent 的无 ...
- Spring Security OAuth2.0认证授权六:前后端分离下的登录授权
历史文章 Spring Security OAuth2.0认证授权一:框架搭建和认证测试 Spring Security OAuth2.0认证授权二:搭建资源服务 Spring Security OA ...
- Spring Security OAuth2.0认证授权四:分布式系统认证授权
Spring Security OAuth2.0认证授权系列文章 Spring Security OAuth2.0认证授权一:框架搭建和认证测试 Spring Security OAuth2.0认证授 ...
- Spring Security OAuth2.0认证授权二:搭建资源服务
在上一篇文章[Spring Security OAuth2.0认证授权一:框架搭建和认证测试](https://www.cnblogs.com/kuangdaoyizhimei/p/14250374. ...
- Spring Security OAuth2.0认证授权五:用户信息扩展到jwt
历史文章 Spring Security OAuth2.0认证授权一:框架搭建和认证测试 Spring Security OAuth2.0认证授权二:搭建资源服务 Spring Security OA ...
- Spring Security OAuth2.0认证授权三:使用JWT令牌
Spring Security OAuth2.0系列文章: Spring Security OAuth2.0认证授权一:框架搭建和认证测试 Spring Security OAuth2.0认证授权二: ...
- Spring Cloud下微服务权限方案
背景从传统的单体应用转型Spring Cloud的朋友都在问我,Spring Cloud下的微服务权限怎么管?怎么设计比较合理?从大层面讲叫服务权限,往小处拆分,分别为三块:用户认证.用户权限.服务校 ...
随机推荐
- golang开发:类库篇(三)命令行工具cli的使用
为什么要使用命令行 觉得这个问题不应该列出来,又觉得如果初次进行WEB开发的话,可能会觉得所有的东西都可以使用API去做,会觉得命令行没有必要. 其实,一个生产的项目命令行是绕不过去的.比如运营需要导 ...
- Java文本类型输入与输出
import java.io.*; import java.time.LocalDate; import java.util.Scanner; public class Test { public s ...
- Spring 注解编程之 AnnotationMetadata
在上篇文章 Spring 注解编程之模式注解 中我们讲到 Spring 模式注解底层原理,依靠 AnnotationMetadata 接口判断是否存在指定元注解. 这篇文章我们主要深入 Annotat ...
- MD5的简单用法
非常简单的MD5加密和解密(即用即copy) 点击帮助灯泡引用就可使用 //生成MD5帮助文件文件 public class MD5Help{ ///MD5加密 方法类 public static s ...
- 从后端到前端之Vue(三)小结以及一颗真实的大树
上一篇写了一下tab,下面整理一下用过的知识点,本想按照官网的文档,整理一下可以更清晰,结果也许是我的方法不对吧,总之更模糊了. 按照官网文档的顺序整理到了表单输入绑定之前,因为之前大致也就只涉及到这 ...
- 安装解压版MySQL5.76及以上版本 出现服务正在启动-服务无法启动的问题
最近重装了系统,去MySQL官网下载了最新的MySQL5.7.9,我选择的是解压版,安装之后启动服务的时候,提示服务无法启动,在网上找了很多教程,弄了很久都没有弄好,后来还是决定去英文官网找找答案, ...
- maven打包添加依赖
<plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <versio ...
- [Revit]Autodesk Revit 二次开发整理(资料、准备工作和环境搭建)
1 前言 Revit被Autodesk收购之后,整理和开放了一大部分API,供开发者实现自己的功能和程序,总体来说API的功能比较完善,毕竟市面上已经出现了各式各样的插件. 本人也是初学者,在Revi ...
- 程序员的长安十二时辰:Java实现从Google oauth2.0认证调用谷歌内部api
最近公司在做一个app购买的功能,主要思路就是客户在app上购买套餐以后,Google自动推送消息到Java后端,然后Java后端通过订单的token获取订单信息,保存到数据库. Java后端要获取订 ...
- Linux基础之快照克隆、Xshell优化、Linux历史
今天主要分享4个Linux基础知识,第一个知识是虚拟机快照,第二个是虚拟机克隆,第三个是优化Xshell,第四个是简述Linux历史. 先分享第一个知识——虚拟机快照. 1.4)虚拟机快照 虚拟机快照 ...