.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. Linux多任务编程之三:exec函数族及其基础实验(转)

    来源:CSDN  作者:王文松  转自:Linux公社 exec函数族 函数族说明 fork() 函数用于创建一个新的子进程,该子进程几乎复制了父进程的全部内容,但是,这个新创建的子进程如何执行呢?e ...

  2. Scala 基础(十六):泛型、类型约束-上界(Upper Bounds)/下界(lower bounds)、视图界定(View bounds)、上下文界定(Context bounds)、协变、逆变和不变

    1 泛型 1)如果我们要求函数的参数可以接受任意类型.可以使用泛型,这个类型可以代表任意的数据类型. 2)例如 List,在创建 List 时,可以传入整型.字符串.浮点数等等任意类型.那是因为 Li ...

  3. shell专题(七):流程控制(重点)

    7.1 if 判断 1.基本语法 if [ 条件判断式 ];then 程序 fi 或者 if [ 条件判断式 ] then 程序 fi 注意事项: (1)[ 条件判断式 ],中括号和条件判断式之间必须 ...

  4. web前端知识点(webpack篇)

    webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler).当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency gr ...

  5. C# - 设计- Struct与Class的选择

    选择Struct的原则 该类型的实例较小且通常为短生存期,或者通常嵌入到其他对象中. 它以逻辑方式表示单个值,类似于基元类型( int .等 double ). 它的实例大小为16字节. 它是不可变的 ...

  6. 06-Python元组,列表,字典,集合数据结构

    一.简介 数据结构是我们用来处理一些数据的结构,用来存储一系列的相关数据. 在python中,有列表,元组,字典和集合四种内建的数据结构. 二.列表 用于存储任意数目.任意类型的数据集合.列表是内置可 ...

  7. 微信小程序随手笔记

    1.全局导入vant时build后有问题(只能页面引入) 2.微信小程序只能用:https开头,在微信公众号里还要修改下配置 3.微信小程序里textarea与vant的van-popup有问题,手机 ...

  8. Ethical Hacking - Web Penetration Testing(2)

    INFORMATION GATHERING IP address. Domain name Info. Technologies used. Other websites on the same se ...

  9. P4017 最大食物链计数(洛谷)

    老师开始帮我们查漏补缺啦!我们的老师这两天给了我们一些我们没怎么学的函数和算法,比如STL的函数和拓扑排序之类的,这个题就是讲拓扑排序的. 先看题板: 题目背景 你知道食物链吗?Delia 生物考试的 ...

  10. javascript : 点击按钮,把某标签中的内容复制到剪贴板

    需求如题. 静态页面如下. 需要的库:jquery(不用应该也能做). 浏览器:PC chrome 68 Mobile MIUI9.5(Android 7) <p>1.用电脑打开网址:&l ...