Spring Cloud下基于OAUTH2认证授权的实现
2023-09-14 09:08:26 时间
GitHub(spring -boot 2.0.0):https://github.com/bigben0123/uaa-zuul
示例(spring -boot 2.0.0): https://github.com/bigben0123/sample-spring-oauth2-microservices (讲解:https://piotrminkowski.wordpress.com/2017/12/01/part-2-microservices-security-with-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学习笔记(八)——SpringMVC响应数据和结果视图
- Spring学习笔记(十八)——spring日志框架的配置和使用
- 解决在 Spring Boot 中运行 JUnit 测试遇到的 NoSuchMethodError 错误
- 通过@MapperScan源码了解Spring自定义注解扫描器[通俗易懂]
- spring boot整合shiro_Spring框架介绍及使用
- Spring Security身份认证之UserDetailsService[通俗易懂]
- spring mvc HTTP Status 406 错误
- Spring基础(十):AOP概念和原理
- ElasticSearch全文搜索引擎 -Spring Boot操作ES(SpringData概述、Spring Data Elasticsearch、基本操作、ElasticSearch操作文档)
- Spring Boot 整合单机websocket
- Security安全认证 | Spring Boot如何集成Security实现安全认证
- Spring Cloud Config 高级功能(一)
- Spring Cloud Gateway网关安全性的保障(一)
- Spring Cloud Security OAuth2的授权模式授权码模式(二)
- Spring Cloud Bus在服务之间传递自定义事件(一)
- Spring Cloud Bus集成Spring Cloud Config Server实现全局配置的自动刷新(一)
- 配置 Spring Cloud Bus 的消息代理示例
- Spring MVC文件下载
- Spring Cloud Feign的文件上传实现详解编程语言
- Spring @Conditional注解的使用详解编程语言
- Spring Boot2.0之多环境配置详解编程语言
- Spring Boot 单元测试详解+实战教程编程语言
- Spring Boot(十四):spring boot整合shiro-登录认证和权限管理详解编程语言
- Spring——声明式事务详解编程语言