自学内容网 自学内容网

网关鉴权之JWT

网关的鉴权是保障系统安全的重要环节,它涉及在请求到达系统之前对请求进行身份验证和授权的过程。以下是对网关鉴权的详细介绍:

一、网关鉴权的基本概念

1. 定义:

网关鉴权是指在请求到达系统之前,通过网关对请求进行身份验证和授权的过程。这包括验证请求的发起者身份是否合法,以及确定该发起者是否有权限访问所请求的资源。

2. 重要性:

网关作为系统和外部世界之间的入口,负责路由请求、流量控制以及安全保护等任务。鉴权机制能够有效防止非法访问和恶意攻击,保护系统资源的安全。

二、网关鉴权的步骤

1. 接收请求:

网关作为系统与外部世界之间的接口,首先会接收到来自客户端的请求。

2. 解析认证信息:

网关会解析请求中的认证信息,这些信息通常包含在HTTP请求的头部(Headers)中,如Authorization字段。认证信息可能包括用户名、密码、Token(如JWT Token)等。

3. 验证用户身份:

通过查询数据库、调用认证服务或使用其他身份验证机制,网关会验证请求中提供的认证信息是否有效,以确认用户的身份是否合法。

4. 权限校验:

在确认用户身份后,网关会根据用户的角色、权限等信息,判断用户是否有权访问所请求的资源。这通常涉及到对请求URL、请求方法、请求参数等进行匹配和验证。

5. 生成响应:

根据验证结果,网关会生成相应的响应。如果验证通过,则允许请求继续访问系统资源;如果验证失败,则返回错误响应,如HTTP 401 Unauthorized,表明用户未经授权。

三、网关鉴权的实现方式

网关鉴权的实现方式多种多样,以下以几种常见的实现方式为例进行说明:

1.使用JWT(JSON Web Tokens):

步骤:
用户通过登录认证流程获得JWT Token。
用户在后续请求中将JWT Token放在Authorization头部中发送给网关。
网关解析JWT Token,验证其合法性和有效性(如检查签名、过期时间等)。
根据JWT Token中的用户信息(如用户ID、角色等)进行权限校验。
根据校验结果生成响应。
优点:JWT Token自包含且可签名,支持无状态认证,易于扩展和分布式部署。

2. 集成OAuth认证服务:

步骤:
用户在OAuth认证服务上进行登录认证。
OAuth认证服务颁发访问令牌(Access Token)给用户。
用户在后续请求中将访问令牌放在请求中发送给网关。
网关通过OAuth认证服务的API验证访问令牌的合法性和有效性。
根据验证结果和用户的权限信息进行权限校验。
根据校验结果生成响应。
优点:OAuth支持第三方应用接入,提供统一的认证和授权机制,易于集成和管理。

3. 自定义鉴权逻辑:

步骤:
根据业务需求,在网关中编写自定义的鉴权逻辑。
鉴权逻辑可以包括解析请求中的特定字段、查询数据库或调用其他服务以验证用户身份和权限。
根据鉴权逻辑的结果生成响应。
优点:灵活性高,可以根据业务需求进行定制化开发。

四、具体实现示例(以Spring Cloud Gateway为例)

在Spring Cloud Gateway中,可以通过编写自定义过滤器(GlobalFilter或GatewayFilter)来实现网关鉴权。以下是一个简单的示例:

步骤 1: 添加依赖

首先,确保你的 Spring Cloud Gateway 项目中包含了必要的依赖。对于 JWT 处理,你可以使用 jjwt 或 spring-security-oauth2-jose。这里我们将使用 jjwt 来生成和解析 JWT。

<!-- pom.xml 文件中添加依赖 -->  
<dependencies>  
    <!-- Spring Cloud Gateway -->  
    <dependency>  
        <groupId>org.springframework.cloud</groupId>  
        <artifactId>spring-cloud-starter-gateway</artifactId>  
    </dependency>  
  
    <!-- Spring Boot Starter Security -->  
    <dependency>  
        <groupId>org.springframework.boot</groupId>  
        <artifactId>spring-boot-starter-security</artifactId>  
    </dependency>  
  
    <!-- JWT 依赖 -->  
    <dependency>  
        <groupId>io.jsonwebtoken</groupId>  
        <artifactId>jjwt</artifactId>  
        <version>0.9.1</version>  
    </dependency>  
  
    <!-- Spring Cloud Starter Netflix Eureka Client (如果需要服务发现) -->  
    <dependency>  
        <groupId>org.springframework.cloud</groupId>  
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>  
    </dependency>  
  
    <!-- 其他依赖... -->  
</dependencies>

步骤 2: 自定义 GatewayFilter

创建一个自定义的 GlobalFilter 来处理 JWT 验证。

import org.springframework.cloud.gateway.filter.GatewayFilterChain;  
import org.springframework.cloud.gateway.filter.GlobalFilter;  
import org.springframework.core.Ordered;  
import org.springframework.http.HttpStatus;  
import org.springframework.http.server.reactive.ServerHttpResponse;  
import org.springframework.stereotype.Component;  
import org.springframework.web.server.ServerWebExchange;  
import reactor.core.publisher.Mono;  
  
import io.jsonwebtoken.Claims;  
import io.jsonwebtoken.Jwts;  
import io.jsonwebtoken.SignatureAlgorithm;  
  
import java.util.Date;  
  
@Component  
public class JwtGatewayFilter implements GlobalFilter, Ordered {  
  
    private static final String AUTHORIZATION_HEADER = "Authorization";  
  
    @Override  
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {  
        String jwt = exchange.getRequest().getHeaders().getFirst(AUTHORIZATION_HEADER);  
  
        if (jwt == null || !jwt.startsWith("Bearer ")) {  
            ServerHttpResponse response = exchange.getResponse();  
            response.setStatusCode(HttpStatus.UNAUTHORIZED);  
            return response.setComplete();  
        }  
  
        jwt = jwt.substring(7);  
  
        try {  
            Claims claims = Jwts.parser()  
                .setSigningKey("your-secret-key".getBytes())  
                .parseClaimsJws(jwt)  
                .getBody();  
  
            // 在这里可以添加对claims的校验逻辑  
  
            return chain.filter(exchange);  
        } catch (Exception e) {  
            ServerHttpResponse response = exchange.getResponse();  
            response.setStatusCode(HttpStatus.UNAUTHORIZED);  
            return response.setComplete();  
        }  
    }  
  
    @Override  
    public int getOrder() {  
        return -1; // 确保这个过滤器尽可能早地执行  
    }  
}

步骤 3: 配置 Security

虽然这个例子主要展示了如何在 Gateway 层面处理 JWT,但你可能还需要配置 Spring Security 来保护其他部分的应用。

步骤 4: 测试

启动你的 Spring Cloud Gateway 应用,并使用包含 JWT 的请求来测试你的 API。你可以使用 Postman 或 curl 等工具来发送请求,并在请求头中包含 Authorization: Bearer 。

注意

这个示例仅用于演示目的,实际项目中你可能需要处理更多的细节,如 JWT 的刷新、错误处理和日志记录等。
确保使用安全的密钥来签名和验证 JWT,并且不要将密钥硬编码在代码中。
根据你的需求,你可能还需要配置路由断言和过滤器来进一步控制访问权限。
对于生产环境,考虑使用更完整的 OAuth2 解决方案,如 Spring Security OAuth2 或 Keycloak 等。


原文地址:https://blog.csdn.net/m0_63550220/article/details/142407142

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!