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下的微服务权限怎么管?怎么设计比较合理?从大层面讲叫服务权限,往小处拆分,分别为三块:用户认证.用户权限.服务校 ...
随机推荐
- HDU 2089:不要62(数位DP)
http://acm.hdu.edu.cn/showproblem.php?pid=2089 不要62 Problem Description 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer) ...
- navicat中查重并删除
# 查询所有重复的数据 SELECT * FROM hao123 WHERE ir_url IN (SELECT ir_url FROM `hao123` GROUP BY ir_url having ...
- springboot自动装配(1)---@SpringBootApplication注解怎么自动装配各种组件
1.对于springboot个人认为它就是整合了各种组件,然后提供对应的自动装配和启动器(starter) 2.@SpringBootApplication注解其实就是组合注解,通过它找到自动装配的注 ...
- Java学习笔记之---单例模型
Java学习笔记之---单例模型 单例模型分为:饿汉式,懒汉式 (一)要点 1.某个类只能有一个实例 2.必须自行创建实例 3.必须自行向整个系统提供这个实例 (二)实现 1.只提供私有的构造方法 2 ...
- 剑指offer第二版-8.二叉树的下一个节点
描述:给定一棵二叉树和其中的一个节点,找出中序遍历序列的下一个节点.树中应定义指向左节点.右节点.父节点的三个变量. 思路: 1.如果输入的当前节点有右孩子,则它的下一个节点即为该右孩子为根节点的子树 ...
- CDQZ集训DAY5 日记
又一个爆炸的一天…… 早上起来发现貌似是周末,七中放假(别人家的学校(一周一放,一放两天)……)然而感觉状态不是很好,感觉药丸. 题目一上来就装弱,有诈.第一题上来先打暴力,T2不知道怎么打.T3暴力 ...
- xfs 文件系统修复
pvcreate /dev/sdb1 pvcreate /dev/sdc1 pvcreate /dev/sdd1 vgcreate vg_bricks /dev/sdb1 vgcreate vg_br ...
- 【题解】生日蛋糕-C++
Description 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体.设从下往上数第i(1 <= i <= M)层蛋糕是半径为Ri, ...
- C语言入门2-程序设计的灵魂—算法及Raptor的应用
一. 什么是算法(5个特性) 算法就是 解决问题的方法和步骤. 算法为解决一个具体问题而采取的确定的 有限的 执行步骤 ,仅指 计算机 能执行的算法. 算法是程序设计的灵魂和核心 ...
- [leetcode] #279 Perfect Squares (medium)
原题链接 题意: 给一个非整数,算出其最少可以由几个完全平方数组成(1,4,9,16……) 思路: 可以得到一个状态转移方程 dp[i] = min(dp[i], dp[i - j * j] + ) ...