.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中

最新文章

  1. [LeetCode] Encode and Decode Strings 加码解码字符串
  2. 在IIS8.5的环境下配置WCF的Restful Service
  3. 快速加载DXF、DWG格式文件控件ABViewer
  4. python练手项目
  5. SQL总结系列
  6. 第15章 设备无关位图_15.1 DIB文件格式
  7. #pragma pack(n)
  8. 求平均排序MATLAB code
  9. 跟我学机器视觉-HALCON学习例程中文详解-开关引脚测量
  10. 如何优化pom依赖项?
  11. 关于iptables的u32匹配
  12. mybatis-basedao的实现
  13. Arduino上传数据至贝壳物联并与FPGA进行交互
  14. BZOJ-1968
  15. Mysql分页查询性能分析
  16. [转]构建高性能MySQL体系
  17. Matlab:导数边界值的有限元(Galerkin)法
  18. Linux环境下运行简单java程序
  19. Django框架----外键关联
  20. git使用 从远程库克隆和更新到本地

热门文章

  1. WPF手机号码归属批量查询并导出到Excel
  2. day16 三层装饰器和迭代器
  3. uniapp,微信小程序中使用 MQTT
  4. Python 列表生成式 生成器
  5. Scala 基础(二):sbt介绍与构建Scala项目
  6. java 基本语法(十四)Lambda (一)表达式
  7. OSCP Learning Notes - Buffer Overflows(2)
  8. spring boot 整合 ehcache
  9. 如何证明sleep不释放锁,而wait释放锁?
  10. 动手实现一个简单的 rpc 框架到入门 grpc (下)