SpringCloud整合Zuul验证Token笔记

  1. 添加依赖
    <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
    </dependency>
    
  2. 启动类添加@EnableZuulProxy注解
  3. 添加配置
    # zuul 路由配置
    zuul.routes.token.url=http://localhost:9090
    zuul.routes.order.url=http://localhost:9080
    # ZuulProperties中sensitiveHeaders默认值"Cookie", "Set-Cookie", "Authorization"
    # 这里需动设置敏感头字段,zuul默认header不带Authorization
    zuul.sensitive-headers=Cookie,Set-Cookie
    
  4. 添加认证过滤器
    @Component
    public class OAuth2AuthenticationFilter extends ZuulFilter {
        @Autowired
        private RestTemplate restTemplate ;
        @Override
        public String filterType() {
            return "pre";
        }
        @Override
        public int filterOrder() {
            return 1;
        }
        @Override
        public boolean shouldFilter() {
            return true;
        }
        @Override
        public Object run() throws ZuulException {
            log.info("====> authentication filter start..");
            RequestContext currentContext = RequestContext.getCurrentContext();
            HttpServletRequest request = currentContext.getRequest();
            String authorization = request.getHeader("Authorization");
            if (StringUtils.isBlank(authorization)){
                return null ;
            }
            // 校验token的合法性
            if (!StringUtils.startsWith(authorization,"bearer ")){
                return null ;
            }
            TokenInfo tokenInfo = getTokenInfo(authorization);
            request.setAttribute("tokenInfo", tokenInfo);
            return null;
        }
        // 校验token的合法性
        private TokenInfo getTokenInfo(String authorization) {
            String url = "http://localhost:9090/oauth/check_token" ;
            String token = StringUtils.substringAfter(authorization, "bearer ") ;
            HttpHeaders headers = new HttpHeaders() ;
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            headers.setBasicAuth("orderService", "123456");
            MultiValueMap<String, String> params = new LinkedMultiValueMap<>() ;
            params.add("token", token);
            HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(params, headers) ;
            ResponseEntity<TokenInfo> exchange = restTemplate.exchange(url, HttpMethod.POST, httpEntity, TokenInfo.class);
            log.info("token info : {}", exchange.getBody());
            return exchange.getBody() ;
        }
    }
    
  5. 添加授权过滤器
    @Component
    public class OAuth2AuthorizationFilter extends ZuulFilter {
        @Override
        public String filterType() {
            return "pre";
        }
        @Override
        public int filterOrder() {
            return 3;
        }
        @Override
        public boolean shouldFilter() {
            return true;
        }
        @Override
        public Object run() throws ZuulException {
            log.info("====> authorization filter start..");
            RequestContext currentContext = RequestContext.getCurrentContext();
            HttpServletRequest request = currentContext.getRequest();
            TokenInfo tokenInfo = (TokenInfo) request.getAttribute("tokenInfo");
            if (tokenInfo != null && tokenInfo.isActive()){
                if (!hasPermission(tokenInfo, request)){
                    log.info("audit log update fail 403");
                    handleError(403, currentContext) ;
                }
                // 将用户信息放在header中传给后面的微服务
                String username = tokenInfo.getUser_name();
                currentContext.addZuulRequestHeader("username", username);
            }else {
                if (!isOauthServerRequest(request)){
                    log.info("audit log update fail 401");
                    handleError(401, currentContext) ;
                }
            }
            return null;
        }
        private boolean isOauthServerRequest(HttpServletRequest request){
            String uri = request.getRequestURI();
            return StringUtils.startsWith(uri, "/token") ;
        }
        // 是否有权限访问资源
        private boolean hasPermission(TokenInfo tokenInfo, HttpServletRequest request) {
            return RandomUtils.nextInt() %2 == 0 ;
        }
        private void handleError(int status, RequestContext ctx) {
            ctx.getResponse().setContentType("application/json");
            ctx.setResponseStatusCode(status);
            ctx.setResponseBody("{\"message\":\"audit fail !\"}");
            ctx.setSendZuulResponse(false);
        }
    }
    
  6. Token信息entity编写
    @Data
    public class TokenInfo {
        private boolean active;
        private String user_name ;
        private String client_id ;
        private Date exp ;
        private String [] scope ;
        private String [] authorities ;
        private String [] aud ;
    }
    
  7. 删除资源服务器中oauth2相关权限校验
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
对于Spring Cloud整合Spring Security和Token认证,你可以按照以下步骤进行操作: 1. 首先,确保你已经配置好了Spring CloudSpring Security依赖。 2. 创建一个Spring Security的配置类,这个类应该继承自`WebSecurityConfigurerAdapter`,并且覆写`configure(HttpSecurity http)`方法。在这个方法中,你可以配置需要认证和授权的URL路径,例如: ``` @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers("/api/public/**").permitAll() .anyRequest().authenticated(); } } ``` 3. 创建一个Token生成和验证的服务类。你可以使用Spring Security提供的`Jwt`库来处理Token操作。这个服务类应该有两个核心方法:一个用于生成Token,一个用于验证Token的有效性。 4. 在需要进行认证和授权的接口上添加`@PreAuthorize`注解,指定需要的权限。例如: ``` @RestController @RequestMapping("/api/public") public class PublicController { @GetMapping("/hello") @PreAuthorize("hasAnyRole('ADMIN', 'USER')") public String hello() { return "Hello, world!"; } } ``` 5. 在Spring Cloud的网关中配置Token验证过滤器。你可以使用Spring Cloud Gateway或者Zuul来实现网关功能,并在网关层进行Token验证。 以上是基本的步骤,你可以根据具体的需求进行调整和扩展。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值