配置消费者鉴权

云原生网关支持为路由配置认证,并对指定的消费者进行鉴权,以允许对应消费者访问路由。本文介绍如何配置消费者鉴权。

背景信息

相比全局认证鉴权适用于统一登录认证等ToC场景,路由认证和消费者鉴权模式适用于授权API给合作伙伴等ToB场景。

对比项

全局认证鉴权

路由认证+消费者鉴权

适用场景

统一登录认证等ToC场景。

授权API给合作伙伴等ToB场景。

核心差异

开启认证的同时也开启鉴权。

开启认证后,需要额外做鉴权配置。

配置入口

安全管理 > 全局认证鉴权

  1. 路由管理 > 策略配置 > 认证

  2. 安全管理 > 消费者鉴权

认证方式配置(以JWT认证为例)

  1. 创建配置时填写全局的JWKS配置。

  2. 填写issuesub字段作为识别JWT是否合法的依据。

  1. 创建消费者配置时填写该消费者对应的JWKS配置。

  2. 填写消费者标识用于识别JWT是否为对应的消费者。默认为payload中的uid字段,可以自定义。

鉴权方式配置

创建配置时填写黑名单或白名单的域名路径(Path)列表。

  • 黑名单模式:名单中的域名路径(Path)需要进行认证,其余无需认证可直接访问。

  • 白名单模式:名单中的域名路径(Path)不需要认证即可访问,其余需要进行认证。

  1. 在路由策略配置中为路由开启认证

  2. 消费者鉴权中关联开启了认证的路由,完成授权。

创建消费者

  1. 登录MSE网关管理控制台,并在顶部菜单栏选择地域。

  2. 在左侧导航栏选择云原生网关 > 网关列表

  3. 网关列表页面,单击目标网关名称。

  4. 在左侧导航栏,单击安全管理 > 消费者鉴权

  5. 单击创建消费者按钮。

  6. 配置相关参数,然后单击确定

    创建消费者.png

    配置参数说明如下。

    配置项

    描述

    消费者名称

    自定义消费者的名称。

    消费者说明

    对消费者进行描述。

    认证方式

    当前消费者支持的认证方式。

    密钥类型

    • 对称密钥:生成一份默认的JWKS配置(每个消费者不同),包含加密或者解密Token时使用的密钥。

    • 非对称密钥:需要您自己填写完整的JWKS配置,使用私钥加密Token。网关根据JWKS中配置的公钥进行解密。

    JWKS

    设置JWKS配置,JWKS规范说明请参考JSON Web Key (JWK)

    JWT Token配置

    设置JWT Token配置信息。

    • 类型:Token参数类型。默认Header。

    • Key:Token参数名称。

    • 前缀:Token参数名的前缀。设置需要校验的Token参数信息,默认是以Bearer为前缀放在Authorization Header中,例如:Authorization: Bearer token

    • 是否透传:选中Token参数透传,表示透传此Token参数到后端服务。

    JWT Payload 内消费者标识

    指定从JWT Payload中的Key以及对应Value来识别为当前消费者。默认提供一对标识,Key为uid,Value为随机字符串,可以自行修改。

    以上图配置为例,JWT Token中的Payload应为如下所示:

    {
      "uid": "11215ac069234abcb8944232b79ae711"
    }

Token生成方式

本文应用Java示例说明,其他语言用户也可以找到相关的工具生成密钥对。

新建一个Maven项目,注入如下依赖:

<dependency>
    <groupId>org.bitbucket.b_c</groupId>
    <artifactId>jose4j</artifactId>
    <version>0.7.0</version>
</dependency>

使用默认对称密钥示例生成Token

展开查看代码内容

package org.example;

import java.io.UnsupportedEncodingException;
import java.security.PrivateKey;

import org.jose4j.base64url.Base64;
import org.jose4j.json.JsonUtil;
import org.jose4j.jwk.OctJwkGenerator;
import org.jose4j.jwk.OctetSequenceJsonWebKey;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.NumericDate;
import org.jose4j.keys.HmacKey;
import org.jose4j.lang.JoseException;
import sun.lwawt.macosx.CSystemTray;

public class Main {
    public static void main(String[] args) throws JoseException, UnsupportedEncodingException {
        //使用本文上述示例
        String privateKeyJson = "{\n"
                + "    \"k\": \"VoBG-oyqVoyCr9G56ozmq8n_rlDDyYMQOd_DO4GOkEY\",\n"
                + "    \"kty\": \"oct\",\n"
                + "    \"alg\": \"HS256\",\n"
                + "}";
        JwtClaims claims = new JwtClaims();
        claims.setGeneratedJwtId();
        claims.setIssuedAtToNow();
        //设置过期时间,并且小于7天
        NumericDate date = NumericDate.now();
        date.addSeconds(120*60);
        claims.setExpirationTime(date);
        claims.setNotBeforeMinutesInThePast(1);
        //添加自定义参数,所有值请都使用String类型
        //设置消费者标识
        claims.setClaim("uid", "11215ac069234abcb8944232b79ae711");
        JsonWebSignature jws = new JsonWebSignature();
        //设置加密算法
        jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA256);
        jws.setKey(new HmacKey(Base64.decode(JsonUtil.parseJson(privateKeyJson).get("k").toString())));
        jws.setPayload(claims.toJson());
        String jwtResult = jws.getCompactSerialization();
        System.out.println("Generate Json Web token , result is \n " + jwtResult);
    }
}

代码相关设置说明。

  • privateKeyJson:即在创建消费者时使用的JWKS,可以在创建消费者时记录下自己使用的JWKS,也可以在创建消费者后,在消费者基础配置页获取JWKS。

    消费者.png

  • 设置消费者标识。即claims.setClaim("uid", "11215ac069234abcb8944232b79ae711"),该消费者标识为创建消费者时控制台默认生成,也可以根据自身逻辑进行修改。

    消费者标识.png

    您也可以在创建消费者后,在消费者基础配置页获取消费者标识。获取消费者标识.png

  • 设置加密算法。即jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA256),该加密算法要和JWKS保持一致。

    说明

    目前支持的加密算法有ES256、ES384、ES512、RS256、RS384、RS512、PS256、PS384、PS512、HS256、HS384、HS512和EdDSA。

    加密算法.png

    使用对称加密的时候,需要对"k"进行解码。

    jws.setKey(new HmacKey(Base64.decode(JsonUtil.parseJson(privateKeyJson).get("k").toString())));
  • 设置过期时间。过期时间需要小于7天,超出过期时间后,请重新生成Token,以保证Token的安全性。

    ...
        NumericDate date = NumericDate.now();
        date.addSeconds(120*60);
        claims.setExpirationTime(date);
        claims.setNotBeforeMinutesInThePast(1);
    ...
  • 根据自身业务需要,可以在JWKS的PAYLOAD中添加自定义参数。

使用非对称密钥示例生成Token

展开查看代码内容

package org.example;

import java.io.UnsupportedEncodingException;
import java.security.PrivateKey;

import org.jose4j.base64url.Base64;
import org.jose4j.json.JsonUtil;
import org.jose4j.jwk.OctJwkGenerator;
import org.jose4j.jwk.OctetSequenceJsonWebKey;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.NumericDate;
import org.jose4j.keys.HmacKey;
import org.jose4j.lang.JoseException;
import sun.lwawt.macosx.CSystemTray;

public class Main {
    public static void main(String[] args) throws JoseException, UnsupportedEncodingException {
        //使用本文上述示例
        String privateKeyJson = "{\n"
                + "    \"k\": \"VoBG-oyqVoyCr9G56ozmq8n_rlDDyYMQOd_DO4GOkEY\",\n"
                + "    \"kty\": \"oct\",\n"
                + "    \"alg\": \"HS256\",\n"
                + "}";
        JwtClaims claims = new JwtClaims();
        claims.setGeneratedJwtId();
        claims.setIssuedAtToNow();
        //设置过期时间,并且小于7天
        NumericDate date = NumericDate.now();
        date.addSeconds(120*60);
        claims.setExpirationTime(date);
        claims.setNotBeforeMinutesInThePast(1);
        //添加自定义参数,所有值请都使用String类型
        //设置消费者标识
        claims.setClaim("uid", "11215ac069234abcb8944232b79ae711");
        JsonWebSignature jws = new JsonWebSignature();
        //设置加密算法
        jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA256);
        jws.setKey(new HmacKey(Base64.decode(JsonUtil.parseJson(privateKeyJson).get("k").toString())));
        jws.setPayload(claims.toJson());
        String jwtResult = jws.getCompactSerialization();
        System.out.println("Generate Json Web token , result is \n " + jwtResult);
    }
}

代码相关设置说明。

  • 设置privateKeyJson、消费者标识、过期时间,同对称加密算法。

  • 设置加密算法,即jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256)。该加密算法和JWKS保持一致。

    非对称加密.png

    对于非对称加密算法,要用其私钥进行加密。

    ...
        jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
        PrivateKey privateKey = new RsaJsonWebKey(JsonUtil.parseJson(privateKeyJson)).getPrivateKey();
        jws.setKey(privateKey);
    ...
  • 根据自身业务需要,可以在JWKS的PAYLOAD中添加自定义参数。

开启路由认证

  1. 登录MSE网关管理控制台,并在顶部菜单栏选择地域。

  2. 在左侧导航栏选择云原生网关 > 网关列表

  3. 网关列表页面,单击目标网关名称。

  4. 在左侧导航栏,单击路由管理,然后选择路由页签。

  5. 在需要变更的路由规则操作列,单击策略配置

  6. 策略配置页签,单击认证。配置完成后,单击保存

    参数

    描述

    认证方式

    当前路由认证消费者时使用的认证方式。

    开启状态

    开启后,认证鉴权生效。

授权给消费者

  1. 登录MSE网关管理控制台,并在顶部菜单栏选择地域。

  2. 在左侧导航栏选择云原生网关 > 网关列表

  3. 网关列表页面,单击目标网关名称。

  4. 在左侧导航栏,单击安全管理 > 消费者鉴权

  5. 在需要变更的消费者规则操作列单击授权

  6. 消费者授权页签,单击关联路由,选择要授权给当前消费者的路由,然后单击确定