.antMatchers("/**").access("#oauth2.hasScope('scope1')")
上面这行代码,只是控制大范围的访问权限,具体到方法级的访问 还得看permission

以上教程代码顺序如下:

网关服务:

1.application.properties

#zuul不传递cookie和head信息
#方法1:这个设置是开启全局的cookie和head传递
zuul.sensitive-headers=

2.application.yml

server:
port: 5001
spring:
application:
name: zuul
cloud:
client:
ipAddress: 127.0.0.1
eureka:
instance:
prefer-ip-address: false
instance-id: ${spring.cloud.client.ipAddress}:${server.port}
hostname: ${spring.cloud.client.ipAddress}
client:
serviceUrl:
#eurekaServers
defaultZone: http://127.0.0.1:2001/eureka
zuul:
routes:
authorization_server: /uaa/**
order_server: /order/**
sensitive-headers:

3.网关资源服务:

/**
* 网关资源类
*/
@Configuration
public class ResourceServerConfig {
public static final String RESOURCE_ID="res1"; //1 uaa认证授权服务资源 配置
@Configuration
@EnableResourceServer
public class UAAServerConfig extends ResourceServerConfigurerAdapter{
@Autowired
private TokenStore tokenStore;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources
//设置我这个resource的id
.resourceId(RESOURCE_ID)
.tokenStore(tokenStore)
//这个貌似是配置要不要把token信息记录在session中
.stateless(true);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/uaa/**").permitAll();//放行所有授权验证请求
}
} //2 order_server……等等微服务资源
@Configuration
@EnableResourceServer
public class orderServerConfig extends ResourceServerConfigurerAdapter{
@Autowired
private TokenStore tokenStore;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources
.resourceId(RESOURCE_ID)
.tokenStore(tokenStore)
.stateless(true);
} @Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
//本项目所需要的授权范围,这个scope是写在auth服务的配置里的
.antMatchers("/order/**").access("#oauth2.hasScope('scope1')");
} } }
TokenConfig
@Configuration
public class TokenConfig { //配置如何把普通token转换成jwt token
@Bean
public JwtAccessTokenConverter tokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); //使用对称秘钥加密token,resource那边会用这个秘钥校验token
converter.setSigningKey("uaa123");
return converter;
} //配置token的存储方法
@Bean
public TokenStore tokenStore() {
//把用户信息都存储在token当中,相当于存储在客户端,性能好很多
return new JwtTokenStore(tokenConverter());
}
}

网关约束WebSecurityConfig

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
} @Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/**").permitAll(); // .and()
// .formLogin() // .and()
// .logout();
} @Override
@Bean
public UserDetailsService userDetailsService() {
/**
* 基于内存创建用户
*/
InMemoryUserDetailsManager manager=new InMemoryUserDetailsManager(); manager.createUser(User.withUsername("zhangsan").password(passwordEncoder().encode("123")).authorities("admin").build());
manager.createUser(User.withUsername("lisi").password(passwordEncoder().encode("123")).authorities("user").build());
return manager;
}
}
配置网关过滤器ZuulConfig、AuthFilter
/**
* @Autor zhangjiawen
* @Date: 2020/5/29 9:56
*/
@Configuration
public class ZuulConfig { @Bean
public AuthFilter preAuthFilter(){
return new AuthFilter();
} @Bean
public FilterRegistrationBean corsFilter(){
final UrlBasedCorsConfigurationSource source=new UrlBasedCorsConfigurationSource();
final CorsConfiguration config=new CorsConfiguration();
config.setAllowCredentials(true);
List<String> ruleList=new ArrayList<>();
ruleList.add("*");
config.setAllowedOrigins(ruleList);
config.setAllowedHeaders(ruleList);
config.setAllowedMethods(ruleList);
config.setMaxAge(1800L);
source.registerCorsConfiguration("/**",config);
CorsFilter corsFilter=new CorsFilter(source);
FilterRegistrationBean bean=new FilterRegistrationBean(corsFilter);
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean; }
}
@Slf4j
public class AuthFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";//表示请求之前拦截
} @Override
public int filterOrder() {
return -1;
} @Override
public boolean shouldFilter() {
return true;//如果想要过滤器生效必须改成true
} /**
* 转发解析token
* @return
* @throws ZuulException
*/
@Override
public Object run() throws ZuulException {
//1获取当前用户身份信息
RequestContext ctx=RequestContext.getCurrentContext();
//从上下文拿到身份对象
Authentication authentication= SecurityContextHolder.getContext().getAuthentication();
if(!(authentication instanceof OAuth2Authentication)){
log.error("-----!(authentication instanceof OAuth2Authentication)");
return null;//如果不是oauth2.0格式的对象 直接返回;
}
OAuth2Authentication oAuth2Authentication=(OAuth2Authentication) authentication;
Authentication userAuthentication = oAuth2Authentication.getUserAuthentication();
//取出用户身份
String principal = userAuthentication.getName();
//2获取当前用户权限信息
List<String> authorities=new ArrayList<>();
//采用stream流的方式遍历
userAuthentication.getAuthorities().stream().forEach(c-> authorities.add(c.getAuthority()));
//将原请求参数重新放回
OAuth2Request oAuth2Request = oAuth2Authentication.getOAuth2Request();
Map<String, String> requestParameters = oAuth2Request.getRequestParameters();
Map<String, Object> jsonToken =new HashMap<>(requestParameters);
//3把用户身份权限信息放入json,存入http的header中
if(userAuthentication!=null){
jsonToken.put("principal",principal);
jsonToken.put("authorities",authorities);
} ctx.addZuulRequestHeader("json-token", Base64.encode(JSON.toJSONString(jsonToken)));
//4转发给微服务 return null;
}
}

授权服务uaa:

资源order服务:

用户权限过滤器TokenAuthenticationFilter

/
* @Autor zhangjiawen
* @Date: 2020/5/29 10:16
*/
@Component
public class TokenAuthenticationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//解析出头中的token
String token = request.getHeader("json-token");
if(!StringUtils.isEmpty(token)){
String json= Base64.decodeStr(token);
//将token转成json对象
JSONObject jsonObject= JSON.parseObject(json);
//获取身份信息
String principal = jsonObject.getString("principal");
UserDTO userDTO=new UserDTO();
userDTO.setUsername(principal); //获取权限信息
JSONArray authoritiesArray = jsonObject.getJSONArray("authorities");
String[] authorities=authoritiesArray.toArray(new String[authoritiesArray.size()]);
//将用户身份权限信息填充到用户token对象中
UsernamePasswordAuthenticationToken authenticationToken
=new UsernamePasswordAuthenticationToken(userDTO,null, AuthorityUtils.createAuthorityList(authorities));
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
//将authenticationToken填充到安全上下文
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
filterChain.doFilter(request,response); } }
}

所有项目源码本人结合网友提供的代码整理了最后一部分 分布式的权限控制 参考:

https://gitee.com/jiawenzhang/Oauth-cloud

感谢哔哩哔哩提供的视频,地址:https://www.bilibili.com/video/BV1VE411h7aL?p=45

测试效果:

将用户信息转成json对象放到username中

OAuth2.0-4整合网关的更多相关文章

  1. security和oauth2.0的整合

    security和oauth2.0的整合 之前已经介绍过security的相关的介绍,现在所需要做的就是security和oauth2.0的整合,在原有的基础上我们加上一些相关的代码;代码实现如下: ...

  2. 整合spring cloud云架构 - SSO单点登录之OAuth2.0登录认证(1)

    之前写了很多关于spring cloud的文章,今天我们对OAuth2.0的整合方式做一下笔记,首先我从网上找了一些关于OAuth2.0的一些基础知识点,帮助大家回顾一下知识点: 一.oauth中的角 ...

  3. SpringBootSecurity学习(14)前后端分离版之 OAuth2.0介绍

    登录总结 前面基本介绍了security的常规用法,同时介绍了JWT和它的一个简单实现,基本上开发中遇到的登录问题都能解决了,即使在分布式开发,或者微服务开发中实现登录也基本没有问题了.securit ...

  4. Spring Cloud云架构 - SSO单点登录之OAuth2.0登录认证(1)

    今天我们对OAuth2.0的整合方式做一下笔记,首先我从网上找了一些关于OAuth2.0的一些基础知识点,帮助大家回顾一下知识点: 一.oauth中的角色 client:调用资源服务器API的应用 O ...

  5. Spring Cloud Zuul 网关使用与 OAuth2.0 认证授权服务

    API 网关的出现的原因是微服务架构的出现,不同的微服务一般会有不同的服务地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题: 客户端会 ...

  6. Oauth2.0 整合springCloud的Zuul 解决关键BUG 报错信息:Principal must not be null

    不清楚Oauth2.0 的 可以查看我前几篇博文 2018.4.8 补充 我出现这个原因:是我在资源服务器使用了 如下图所示 Principal Oauth2.0 提供的获取用户信息的方法 使其找到相 ...

  7. 妹子始终没搞懂OAuth2.0,今天整合Spring Cloud Security 一次说明白!

    大家好,我是不才陈某~ 周二发了Spring Security 系列第一篇文章,有妹子留言说看了很多文章,始终没明白OAuth2.0,这次陈某花了两天时间,整理了OAuth2.0相关的知识,结合认证授 ...

  8. (十一) 整合spring cloud云架构 - SSO单点登录之OAuth2.0登录流程(2)

    上一篇是站在巨人的肩膀上去研究OAuth2.0,也是为了快速帮助大家认识OAuth2.0,闲话少说,我根据框架中OAuth2.0的使用总结,画了一个简单的流程图(根据用户名+密码实现OAuth2.0的 ...

  9. QQ登录整合/oauth2.0认证-04-调整到QQ互联进行QQ登录

    ---------------------------------目录------------------------------------- QQ登录整合/oauth2.0认证-03-对第二节的代 ...

  10. QQ登录整合/oauth2.0认证-03-对第二节的代码改进

    ---------------------------目录---------------------------------- QQ登录整合/oauth2.0认证-01-申请appkey和appid ...

随机推荐

  1. day27 作业

    # 学校类 class School: #校区的名字:如"老男孩上海校区" #校区的地址:如"上海虹桥" def __init__(self,s_name,s_ ...

  2. 利用docker部署oxidized网络设备备份系统

    随着网络设备的增多,通过人手备份网络设备倍感压力,而且效率低.有编程基础的人可能会通过Python的parimiko 或者netmiko 连接到设备操作 把文件通过ftp 上传到FTP服务器, 在通过 ...

  3. MYSQL 之 JDBC(三): 增删改查(一)通过Statement执行更新操作

    Statement测试 /** * 通过JDBC向指定的数据表中插入一条记录 * 1. Statement:用于执行sql语句的对象 * 1.1 通过Connection的createStatemen ...

  4. Python之爬虫(十四) Scrapy框架的架构和原理

    这一篇文章主要是为了对scrapy框架的工作流程以及各个组件功能的介绍 Scrapy目前已经可以很好的在python3上运行Scrapy使用了Twisted作为框架,Twisted有些特殊的地方是它是 ...

  5. python面向对象07/异常处理

    python面向对象07/异常处理 目录 python面向对象07/异常处理 1. 异常错误分类 2. 什么是异常? 3. 异常处理 4. 为什么要有异常处理 5. 异常处理的两种方式 1.if判断 ...

  6. bzoj4631踩气球

    bzoj4631踩气球 题意: 有一个序列和一个区间集合,每次将序列中的一个数-1,求此时集合里有多少个区间和为0.序列大小≤100000,区间数≤100000,操作数≤100000. 题解: 此题解 ...

  7. 没错,用三方 Github 做授权登录就是这么简单!(OAuth2.0实战)

    本文收录在个人博客:www.chengxy-nds.top,技术资源共享. 上一篇<OAuth2.0 的四种授权方式>文末说过,后续要来一波OAuth2.0实战,耽误了几天今儿终于补上了. ...

  8. 第七章:Android动画深入分析

    7.1 View动画 View动画的作用对象是View,它支持四种动画效果,分别是平移动画,缩放动画,旋转动画和透明动画. 帧动画也属于View动画,但是帧动画的表现形式和上面的四种变换效果不太一样. ...

  9. 你闺女也能看懂的插画版 Kubernetes 指南

    Matt Butcher是Deis的平台架构师,热爱哲学,咖啡和精雕细琢的代码.有一天女儿走进书房问他什么是Kubernetes,于是就有了这本插画版的Kubernetes指南,讲述了勇敢的Phipp ...

  10. spring boot 整合 ehcache

    1. 该说的话 每个人都应当学会独立地去思考.去寻找答案,而不是一味地伸手向他人索取所谓的标准答案. 首先,别成为"拿来主义"者,其次远离"拿来主义"的人. 2 ...