zoukankan      html  css  js  c++  java
  • OAuth2.0-4整合网关

     

     

     

     

     

     

     

     

     

     

     

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

     

  • 相关阅读:
    微信小程序开发9-宿主环境(2)
    微信小程序开发8-小程序的宿主环境(1)
    微信小程序开发7-JavaScript脚本
    微信小程序开发6-WXSS
    点击底部input输入框,弹出的软键盘挡住input(苹果手机使用第三方输入法 )
    极光推送能获取 registrationId,但是接收不到通知
    App 运行后屏幕顶部和底部各留黑边问题
    App 分辨率相关
    配置隐私协议
    极光推送小结
  • 原文地址:https://www.cnblogs.com/jiawen010/p/12981456.html
Copyright © 2011-2022 走看看