当前位置:首页 > 技术分析 > 正文内容

如何通过SpringBoot开发一个鉴权网关?

ruisui882个月前 (04-30)技术分析28

想要开发一个带有鉴权网关可以通过结合Spring Cloud Gateway和Spring Security来实现,通过两者结合可以提供灵活且强大的鉴权和网关功能,下面我们就来看看如何在Spring Boot中实现相关的功能。

引入依赖

首先,需要在Spring Boot项目的pom.xml中引入必要的依赖,包括Spring Cloud Gateway和Spring Security,如下所示。

<dependencies>
    <!-- Spring Cloud Gateway -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>

    <!-- Spring Security -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

    <!-- JWT (如果使用JWT进行认证) -->
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
    </dependency>
</dependencies>

Spring Cloud Gateway可以根据路径或者其他条件将请求转发到下游服务,但是需要在配置文件中对相关的操作进行配置,如下所示。

spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service  # 使用服务发现,如Eureka
          predicates:
            - Path=/user/**
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/order/**

配置鉴权过滤器

可以通过自定义过滤器在网关层进行鉴权,在这个过滤器中可以通过解析JWT令牌或者其他鉴权方式,来验证用户是否有权限访问某个服务,如下所示。

自定义全局过滤器

在Spring Cloud Gateway中我们可以自定义全局过滤器,实现在请求到达下游服务前进行JWT验证操作,如下所示。

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class AuthenticationFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        HttpHeaders headers = exchange.getRequest().getHeaders();
        
        // 检查Authorization头部是否存在
        if (!headers.containsKey(HttpHeaders.AUTHORIZATION)) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }

        String authHeader = headers.getFirst(HttpHeaders.AUTHORIZATION);

        try {
            // 验证JWT或其他令牌逻辑
            String token = authHeader.replace("Bearer ", "");
            // TODO: 验证token的合法性
            // 如果验证失败,返回401
            if (!validateToken(token)) {
                exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
                return exchange.getResponse().setComplete();
            }
        } catch (Exception e) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }

        // 如果验证成功,继续请求
        return chain.filter(exchange);
    }

    // 简单的token验证方法,实际可以引入JWT库
    private boolean validateToken(String token) {
        // TODO: 实现JWT或其他认证方式的验证
        return true;
    }

    @Override
    public int getOrder() {
        return -1; // 保证此过滤器优先级较高
    }
}

JWT验证逻辑

我们可以使用jjwt库来解析和验证JWT,如下所示。

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureException;

public class JwtUtil {

    private static final String SECRET_KEY = "your-secret-key";

    public static Claims parseToken(String token) {
        try {
            return Jwts.parser()
                    .setSigningKey(SECRET_KEY)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (SignatureException e) {
            throw new RuntimeException("Invalid JWT signature");
        }
    }

    public static boolean validateToken(String token) {
        try {
            Claims claims = parseToken(token);
            // TODO: 进一步验证token信息,如过期时间等
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}

然后在过滤器中调用JwtUtil.validateToken(token)来完成JWT的验证。

Spring Security配置

可以在SecurityConfig中配置一些基本的安全规则,例如对部分路由的权限控制。如下所示。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;

@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        http
            .authorizeExchange()
            .pathMatchers("/login", "/register").permitAll() // 允许访问登录和注册接口
            .anyExchange().authenticated() // 其他请求需要认证
            .and()
            .csrf().disable(); // 关闭CSRF
        return http.build();
    }
}

完成上述配置后,我们的Spring Boot鉴权网关基本就搭建好了。可以通过发送带有JWT的请求来测试网关的鉴权功能,如下所示。

curl -H "Authorization: Bearer your-jwt-token" http://localhost:8080/user/123

如果JWT令牌有效,请求将会被转发到user-service,否则网关将返回401 Unauthorized错误。

总结

通过Spring Cloud Gateway和Spring Security,结合JWT等鉴权机制,可以很方便地搭建一个鉴权网关。该网关不仅可以作为服务入口,还可以确保各个服务的安全性,防止未经授权的访问。

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/3716.html

分享给朋友:

“如何通过SpringBoot开发一个鉴权网关?” 的相关文章

「 VUE3 + TS + Vite 」父子组件间如何通信?

组件之间传值,大家都很熟悉,涉及到 VUE3 +TS 好多同学就无从下手了,所以分享这篇文章,希望看完后提起 VUE3+TS 能够不慌不忙。平时使用的函数如:ref、reactive、watch、computed 等需要先引入才能使用,但是本篇文章介绍的 defineProps、withDefaul...

掌握版本控制:Git的那些常见用法与技巧

Git作为现代开发中最常用的版本控制系统,它的普及和高效性使得程序员几乎每天都在与它打交道。无论是个人项目,还是团队协作,Git都能帮助我们追踪代码的修改历史,保证代码版本的管理井井有条,并在多人协作时有效地避免冲突。本文将分享一些常见的Git用法与技巧,帮助你更好地掌握Git的强大功能,并提升你在...

身体越柔软越好?刻苦拉伸可能反而不健康 | 果断练

坐下伸直膝盖,双手用力向前伸,再用力……比昨天前进了一厘米,又进步了! 这么努力地拉伸,每个人都有自己的目标,也许是身体健康、线条柔美、放松肌肉、体测满分,也可能为了随时劈个叉,享受一片惊呼。 不过,身体柔软,可以享受到灵活的福利,也可能付出不稳定的代价,并不是越刻苦拉伸越好。太硬或者太软,都不安全...

雅马哈TMAX 560 TECH MAX 外媒深度测评

应雅马哈(Yamaha)的邀请,在葡萄牙埃斯托里尔对全新的Yamaha TMAX 560 Tech Max踏板车进行了测试,在这里TMAX 560 Tech Max售价为11649英镑。雅马哈TMAX长期以来一直站在踏板车的顶端,就声誉和知名度而言,它是当之无愧的大踏板界NO.1。2020 TMAX...

thinkphp8+vue3微信小程序商城,发布公众号App+SAAS+多商户

项目介绍三勾小程序商城基于thinkphp8+vue3+element-ui+uniapp打造的面向开发的小程序商城,方便二次开发或直接使用,可发布到多端,包括微信小程序、微信公众号、QQ小程序、支付宝小程序、字节跳动小程序、百度小程序、android端、ios端。支持主题色+自定义头部导航+自定义...

三勾商城(java+vue3)微信小程序商城+SAAS+前后端源码

项目介绍本系统功能包括: 前台展示+后台管理+SAAS管理端,包括最基本的用户登录注册,下单, 购物车,购买,结算,订单查询,收货地址,后台商品管 理,订单管理,用户管理等等功能,小伙伴一起来看看吧。三勾小程序商城基于springboot+element-ui+uniapp打造的面向开发的小程序商城...