Spring Cloud下基于OAUTH2认证授权的实现
在Spring Cloud
需要使用OAUTH2
来实现多个微服务的统一认证授权,通过向OAUTH服务
发送某个类型的grant type
进行集中认证和授权,从而获得access_token
,而这个token是受其他微服务信任的,我们在后续的访问可以通过access_token
来进行,从而实现了微服务的统一认证授权。
格式正常地址:Spring Cloud下基于OAUTH2认证授权的实现包含源码
本示例提供了四大部分:
discovery-service
:服务注册和发现的基本模块auth-server
:OAUTH2认证授权中心order-service
:普通微服务,用来验证认证和授权api-gateway
:边界网关(所有微服务都在它之后)
OAUTH2中的角色:
Resource Server
:被授权访问的资源Authotization Server
:OAUTH2认证授权中心Resource Owner
: 用户Client
:使用API的客户端(如Android 、IOS、web app)
Grant Type:
Authorization Code
:用在服务端应用之间Implicit
:用在移动app或者web app(这些app是在用户的设备上的,如在手机上调起微信来进行认证授权)Resource Owner Password Credentials(password)
:应用直接都是受信任的(都是由一家公司开发的,本例子使用)Client Credentials
:用在应用API访问。
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)
.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
##很重要
security:
oauth2:
resource:
filter-order: 3
2.6 测试数据
data.sql
里初始化了两个用户admin
->ROLE_ADMIN
->query_demo
,wyf
->ROLE_USER
3.order-service
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 用户信息配置
order-service
是一个简单的微服务,使用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
http://www.360doc.com/content/17/0728/14/16915_674776055.shtml
Spring Cloud下基于OAUTH2认证授权的实现的更多相关文章
- Spring Cloud下基于OAUTH2+ZUUL认证授权的实现
Spring Cloud下基于OAUTH2认证授权的实现 在Spring Cloud需要使用OAUTH2来实现多个微服务的统一认证授权,通过向OAUTH服务发送某个类型的grant type进行集中认 ...
- Spring Cloud下微服务权限方案
背景从传统的单体应用转型Spring Cloud的朋友都在问我,Spring Cloud下的微服务权限怎么管?怎么设计比较合理?从大层面讲叫服务权限,往小处拆分,分别为三块:用户认证.用户权限.服务校 ...
- Spring Cloud Gateway + Jwt + Oauth2 实现网关的鉴权操作
Spring Cloud Gateway + Jwt + Oauth2 实现网关的鉴权操作 一.背景 二.需求 三.前置条件 四.项目结构 五.网关层代码的编写 1.引入jar包 2.自定义授权管理器 ...
- 几种常见的微服务架构方案简述——ZeroC IceGrid、Spring Cloud、基于消息队列
微服务架构是当前很热门的一个概念,它不是凭空产生的,是技术发展的必然结果.虽然微服务架构没有公认的技术标准和规范草案,但业界已经有一些很有影响力的开源微服务架构平台,架构师可以根据公司的技术实力并结合 ...
- 几种常见的微服务架构方案——ZeroC IceGrid、Spring Cloud、基于消息队列、Docker Swarm
微服务架构是当前很热门的一个概念,它不是凭空产生的,是技术发展的必然结果.虽然微服务架构没有公认的技术标准和规范草案,但业界已经有一些很有影响力的开源微服务架构平台,架构师可以根据公司的技术实力并结合 ...
- 【spring boot】spring cloud下spring boot微服务启动没有报错,但是访问访问不到
spring cloud下spring boot微服务启动没有报错,但是访问访问不到 解决方法: 可能是端口被占用了,但是依旧启用成功了. 更改一下项目启用的端口号,再重新启动查看是否可以正常访问.
- Spring Cloud Security&Eureka安全认证(Greenwich版本)
Spring Cloud Security&Eureka安全认证(Greenwich版本) 一·安全 Spring Cloud支持多种安全认证方式,比如OAuth等.而默认是可以直接添加spr ...
- Spring Cloud下使用Feign Form实现微服务之间的文件上传
背景 Spring Cloud现在已经被越来越多的公司采用了,微服务架构比传统意义上的单服务架构从复杂度上多了很多,出现了很多复杂的场景.比如,我们的产品是个app,支持第三方登录功能,在手机端调 ...
- Spring Cloud Feign 使用OAuth2
Spring Cloud 微服务架构下,服务间的调用采用的是Feign组件,为了增加服务安全性,server之间互相调用采用OAuth2的client模式.Feign使用http进行服务间的通信,同时 ...
随机推荐
- 使用css控制文字显示几行并且剩余部分隐藏(移动端和PC端同样适用)
前言 有些需求需要我们控制一段文本最多显示几行,就像逛淘宝京东的评价楼层一样,有时可能还需要隐藏剩余部分,这样的需求我们怎么来解决呢? 解决办法 我们完全可以使用css来解决这一需求 1. 解决文本显 ...
- Mac 在terminal 上用命令打开sublime
Step1. 安装Sublime Text编辑器 可直接到以下网址下载dmg安装文件: Sublime Text 3 Step2. 添加命令行别名 打开用户配置文件 vim ~/.bash_profi ...
- C# Note28: Dispatcher类
在项目中也是经常用到: 刚见到它时,你会想:为什么不直接使用System.Windows命名空间下的MessageBox类,何必要这么麻烦?(认真分析看它做了什么,具体原因下面解释) 主要介绍的方法: ...
- kprobe原理解析
参考 http://www.cnblogs.com/honpey/p/4575928.html kprobe是linux内核的一个重要特性,是一个轻量级的内核调试工具,同时它又是其他一些更高级的内核 ...
- python学习笔记(2)--基本语法元素
来看一个非常简单的温度转换程序 #Tempconvert.py tempstr = input("输入:") if tempstr[-1] in ['F', 'f']: C = ( ...
- nginx反向代理proxy_pass的问题
起因:今天企业部署一个项目,用的nginx做的反向代理,配置如下: 测试结果令人失望,IP:端口 能访问项目,域名:端口 也能访问 ,但是 域名/接口名 访问失败 ################## ...
- react & youtube
react & youtube https://www.npmjs.com/package/react-youtube https://developers.google.com/youtub ...
- Python自动化运维之pexpect从入门到精通
1. 应用场景 模拟ssh, telnet远程登录, 模拟ftp文件上传 2. 安装 参考资料: <pexpect实例分析>https://www.ibm.com/developerwor ...
- hdu1875(最小生成树prime)
思路:一开始想用贪心来着,发现贪心有缺陷,然后就用了最小生成树来写,这里用了prime算法,首先,先建个图,两点之间的边的权值就是两个点的距离,然后直接prime模板 代码 #include<i ...
- mysql语句-DML语句
DML语句 DML是指对数据库中表记录的操作,主要包括数据的增删改查以及更新,下面依次介绍 首先创建一张表:: 表名:emp 字段:ename varchar(20),hiredate date ,s ...