自定义 JWT 生成在 WSO2 APIM 3.1.0 中不起作用
Customizing JWT generation not working in WSO2 APIM 3.1.0
我尝试执行 WSO2 3.1.0 文档 (https://apim.docs.wso2.com/en/3.0.0/learn/api-gateway/passing-end-user-attributes-to-the-backend/passing-enduser-attributes-to-the-backend-using-jwt/) 中给出的步骤来自定义 JWT。
如文档中所述,我创建了自定义 JWT 生成器 java class,生成了 jar 并将其放在 WSO2 Home/repository/components/lib 文件夹下。是否在 deployment.toml 中进行了必要的配置以启用 JWT 并重新启动了服务器。
当我用不记名令牌点击 API 时,我在碳日志中得到 X-JWT-Assertion header 但是当我解码它时,它不包含自定义声称我在自定义 JWT 生成器中添加 java class.
它包含下图中所示的标准声明,而不是添加的自定义声明(current_timestamp,消息)。
需要这方面的建议,因为我已按照文档中给出的步骤操作。
我试图在本地重现这个场景。当我们使用 JWT 访问令牌调用 API.
时,它是可重现的
但在使用 OAuth 令牌时,我能够在 X-JWT-Assertion header 中成功获得自定义声明。请看下图。
在使用 JWT 访问令牌调用 API 时,您需要按照 this documentation 进行自定义。
我按照您共享的文档使用 JWT 访问令牌调用 API。我克隆了文档中给出的 GIT 存储库:https://github.com/wso2/samples-apim/tree/master/CustomGatewayJWTGenerator,将 CustomGatewayJWTGenerator 代码导入到 Eclipse 中。导入成功后,我在eclipse中看到构建路径错误: joda-time-2.9.4.wso2v1.jar' in project 'CustomGatewayJWTGenerator' cannot be read or is not一个有效的 ZIP 文件。即使在 eclipse 中看到错误,我也能够使用 Maven 构建 jar。我将生成的 jar 放在 lib 文件夹中,并在服务器重新启动后验证该 jar 也存在于 dropins 文件夹中。但不知何故,我在 CustomGatewayJWTGenerator java class 中添加的自定义声明仍然没有出现在 X-JWT-Assertion header 中。是我在导入 CustomGatewayJWTGenerator 项目后在 eclipse 中遇到的错误有关,还是我在其他地方出错了?
我保留了产品预定义的默认 JWT 属性和值,并添加了您告诉的那个。将 CustomGatewayJWTGenerator jar 放在 dropins 文件夹中。
JWT 属性现在在 deployment.toml 中如下所示。请让我知道下面显示的配置是否正确。
[apim.jwt]
启用=真
encoding = "base64" # base64,base64url
generator_impl = "org.wso2.carbon.apimgt.keymgt.token.JWTGenerator"
claim_dialect = "http://wso2.org/claims"
header = "X-JWT-Assertion"
signing_algorithm = "SHA256withRSA"
enable_user_claims = 真
claims_extractor_impl = "org.wso2.carbon.apimgt.impl.token.DefaultClaimsRetriever"
[apim.jwt.gateway_generator]
impl = "org.wso2.carbon.test.CustomGatewayJWTGenerator"
重新启动服务器,现在当我使用 JWT 访问令牌测试 API 时,调用失败并出现空指针异常。
错误详情如下:
ERROR {org.apache.synapse.transport.passthru.ServerWorker} - 处理 GET 请求时出错:/pizzashack/1.0.0/menu。 java.lang.NullPointerException
在 org.wso2.carbon.apimgt.gateway.handlers.security.jwt.JWTValidator.generateAndRetrieveJWTToken_aroundBody2(JWTValidator.java:353)
在 org.wso2.carbon.apimgt.gateway.handlers.security.jwt.JWTValidator.generateAndRetrieveJWTToken(JWTValidator.java:336)
在 org.wso2.carbon.apimgt.gateway.handlers.security.jwt.JWTValidator.authenticate_aroundBody0(JWTValidator.java:319)
在 org.wso2.carbon.apimgt.gateway.handlers.security.jwt.JWTValidator.authenticate(JWTValidator.java:110)
在 org.wso2.carbon.apimgt.gateway.handlers.security.oauth.OAuthAuthenticator.authenticate_aroundBody4(OAuthAuthenticator.java:334)
在 org.wso2.carbon.apimgt.gateway.handlers.security.oauth.OAuthAuthenticator.authenticate(OAuthAuthenticator.java:109)
在 org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.isAuthenticate_aroundBody42(APIAuthenticationHandler.java:419)
在 org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.isAuthenticate(APIAuthenticationHandler.java:413)
在 org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.handleRequest_aroundBody36(APIAuthenticationHandler.java:349)
在 org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.handleRequest(APIAuthenticationHandler.java:320)
在 org.apache.synapse.rest.API.process(API.java:367)
在 org.apache.synapse.rest.RESTRequestHandler.apiProcessNonDefaultStrategy(RESTRequestHandler.java:149)
在 org.apache.synapse.rest.RESTRequestHandler.dispatchToAPI(RESTRequestHandler.java:95)
在 org.apache.synapse.rest.RESTRequestHandler.process(RESTRequestHandler.java:71)
在 org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:327)
在 org.apache.synapse.core.axis2.SynapseMessageReceiver.receive(SynapseMessageReceiver.java:98)
在 org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
在 org.apache.synapse.transport.passthru.ServerWorker.processNonEntityEnclosingRESTHandler(ServerWorker.java:368)
在 org.apache.synapse.transport.passthru.ServerWorker.运行(ServerWorker.java:189)
在 org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
在 java.lang.Thread.run(Thread.java:813)
经过一番研究,我发现它是一个运行在 Apache Felix 之上的 OSGi 包。
请检查示例代码中可用的以下导入 (CustomGatewayJWTGenerator):
import org.osgi.service.component.annotations.Component;
另请参阅示例 pom.xml。它添加了一些关于 OSGi 包的信息:
这是重要的部分:
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>3.2.0</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Name>${project.artifactId}</Bundle-Name>
<Export-Package>
org.wso2.carbon.test.*
</Export-Package>
<Import-Package>
org.wo2.carbon.apimgt.gateway.*,
org.wso2.carbon.apimgt.impl.*
com.nimbusds.jwt.*,
*;resolution:=optional
</Import-Package>
</instructions>
</configuration>
</plugin>
如您所见,它将组件导出为 OSGi。看下面我的 pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.wso2</groupId>
<artifactId>wso2</artifactId>
<version>1.2</version>
</parent>
<groupId>org.example</groupId>
<artifactId>CustomGatewayJWTGenerator</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<groupId>org.wso2.carbon.apimgt</groupId>
<artifactId>org.wso2.carbon.apimgt.gateway</artifactId>
<version>${carbon.apimgt.version}</version>
</dependency>
<dependency>
<groupId>org.wso2.orbit.com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
<version>7.3.0.wso2v1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>3.2.0</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Name>${project.artifactId}</Bundle-Name>
<Export-Package>
la.foton.wso2.apim.custom.*
</Export-Package>
<Import-Package>
org.wo2.carbon.apimgt.gateway.*,
org.wso2.carbon.apimgt.impl.*
com.nimbusds.jwt.*,
*;resolution:=optional
</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<carbon.apimgt.version>6.6.163</carbon.apimgt.version>
</properties>
</project>
我相信你只需要更改 <Export-Package>
中的包信息,将 JAR 文件复制到 $APIM_HOME/repository/components/dropins
并重新启动服务器。
如果出现问题,请告诉我。如果有效,请将答案标记为正确以帮助他人。 :)
我尝试执行 WSO2 3.1.0 文档 (https://apim.docs.wso2.com/en/3.0.0/learn/api-gateway/passing-end-user-attributes-to-the-backend/passing-enduser-attributes-to-the-backend-using-jwt/) 中给出的步骤来自定义 JWT。
如文档中所述,我创建了自定义 JWT 生成器 java class,生成了 jar 并将其放在 WSO2 Home/repository/components/lib 文件夹下。是否在 deployment.toml 中进行了必要的配置以启用 JWT 并重新启动了服务器。
当我用不记名令牌点击 API 时,我在碳日志中得到 X-JWT-Assertion header 但是当我解码它时,它不包含自定义声称我在自定义 JWT 生成器中添加 java class.
它包含下图中所示的标准声明,而不是添加的自定义声明(current_timestamp,消息)。
需要这方面的建议,因为我已按照文档中给出的步骤操作。
我试图在本地重现这个场景。当我们使用 JWT 访问令牌调用 API.
时,它是可重现的但在使用 OAuth 令牌时,我能够在 X-JWT-Assertion header 中成功获得自定义声明。请看下图。
在使用 JWT 访问令牌调用 API 时,您需要按照 this documentation 进行自定义。
我按照您共享的文档使用 JWT 访问令牌调用 API。我克隆了文档中给出的 GIT 存储库:https://github.com/wso2/samples-apim/tree/master/CustomGatewayJWTGenerator,将 CustomGatewayJWTGenerator 代码导入到 Eclipse 中。导入成功后,我在eclipse中看到构建路径错误: joda-time-2.9.4.wso2v1.jar' in project 'CustomGatewayJWTGenerator' cannot be read or is not一个有效的 ZIP 文件。即使在 eclipse 中看到错误,我也能够使用 Maven 构建 jar。我将生成的 jar 放在 lib 文件夹中,并在服务器重新启动后验证该 jar 也存在于 dropins 文件夹中。但不知何故,我在 CustomGatewayJWTGenerator java class 中添加的自定义声明仍然没有出现在 X-JWT-Assertion header 中。是我在导入 CustomGatewayJWTGenerator 项目后在 eclipse 中遇到的错误有关,还是我在其他地方出错了?
我保留了产品预定义的默认 JWT 属性和值,并添加了您告诉的那个。将 CustomGatewayJWTGenerator jar 放在 dropins 文件夹中。 JWT 属性现在在 deployment.toml 中如下所示。请让我知道下面显示的配置是否正确。
[apim.jwt]
启用=真
encoding = "base64" # base64,base64url
generator_impl = "org.wso2.carbon.apimgt.keymgt.token.JWTGenerator"
claim_dialect = "http://wso2.org/claims"
header = "X-JWT-Assertion"
signing_algorithm = "SHA256withRSA"
enable_user_claims = 真
claims_extractor_impl = "org.wso2.carbon.apimgt.impl.token.DefaultClaimsRetriever"
[apim.jwt.gateway_generator]
impl = "org.wso2.carbon.test.CustomGatewayJWTGenerator"
重新启动服务器,现在当我使用 JWT 访问令牌测试 API 时,调用失败并出现空指针异常。 错误详情如下:
ERROR {org.apache.synapse.transport.passthru.ServerWorker} - 处理 GET 请求时出错:/pizzashack/1.0.0/menu。 java.lang.NullPointerException 在 org.wso2.carbon.apimgt.gateway.handlers.security.jwt.JWTValidator.generateAndRetrieveJWTToken_aroundBody2(JWTValidator.java:353) 在 org.wso2.carbon.apimgt.gateway.handlers.security.jwt.JWTValidator.generateAndRetrieveJWTToken(JWTValidator.java:336) 在 org.wso2.carbon.apimgt.gateway.handlers.security.jwt.JWTValidator.authenticate_aroundBody0(JWTValidator.java:319) 在 org.wso2.carbon.apimgt.gateway.handlers.security.jwt.JWTValidator.authenticate(JWTValidator.java:110) 在 org.wso2.carbon.apimgt.gateway.handlers.security.oauth.OAuthAuthenticator.authenticate_aroundBody4(OAuthAuthenticator.java:334) 在 org.wso2.carbon.apimgt.gateway.handlers.security.oauth.OAuthAuthenticator.authenticate(OAuthAuthenticator.java:109) 在 org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.isAuthenticate_aroundBody42(APIAuthenticationHandler.java:419) 在 org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.isAuthenticate(APIAuthenticationHandler.java:413) 在 org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.handleRequest_aroundBody36(APIAuthenticationHandler.java:349) 在 org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.handleRequest(APIAuthenticationHandler.java:320) 在 org.apache.synapse.rest.API.process(API.java:367) 在 org.apache.synapse.rest.RESTRequestHandler.apiProcessNonDefaultStrategy(RESTRequestHandler.java:149) 在 org.apache.synapse.rest.RESTRequestHandler.dispatchToAPI(RESTRequestHandler.java:95) 在 org.apache.synapse.rest.RESTRequestHandler.process(RESTRequestHandler.java:71) 在 org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:327) 在 org.apache.synapse.core.axis2.SynapseMessageReceiver.receive(SynapseMessageReceiver.java:98) 在 org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180) 在 org.apache.synapse.transport.passthru.ServerWorker.processNonEntityEnclosingRESTHandler(ServerWorker.java:368) 在 org.apache.synapse.transport.passthru.ServerWorker.运行(ServerWorker.java:189) 在 org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) 在 java.lang.Thread.run(Thread.java:813)
经过一番研究,我发现它是一个运行在 Apache Felix 之上的 OSGi 包。
请检查示例代码中可用的以下导入 (CustomGatewayJWTGenerator):
import org.osgi.service.component.annotations.Component;
另请参阅示例 pom.xml。它添加了一些关于 OSGi 包的信息:
这是重要的部分:
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>3.2.0</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Name>${project.artifactId}</Bundle-Name>
<Export-Package>
org.wso2.carbon.test.*
</Export-Package>
<Import-Package>
org.wo2.carbon.apimgt.gateway.*,
org.wso2.carbon.apimgt.impl.*
com.nimbusds.jwt.*,
*;resolution:=optional
</Import-Package>
</instructions>
</configuration>
</plugin>
如您所见,它将组件导出为 OSGi。看下面我的 pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.wso2</groupId>
<artifactId>wso2</artifactId>
<version>1.2</version>
</parent>
<groupId>org.example</groupId>
<artifactId>CustomGatewayJWTGenerator</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<groupId>org.wso2.carbon.apimgt</groupId>
<artifactId>org.wso2.carbon.apimgt.gateway</artifactId>
<version>${carbon.apimgt.version}</version>
</dependency>
<dependency>
<groupId>org.wso2.orbit.com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
<version>7.3.0.wso2v1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>3.2.0</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Name>${project.artifactId}</Bundle-Name>
<Export-Package>
la.foton.wso2.apim.custom.*
</Export-Package>
<Import-Package>
org.wo2.carbon.apimgt.gateway.*,
org.wso2.carbon.apimgt.impl.*
com.nimbusds.jwt.*,
*;resolution:=optional
</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<carbon.apimgt.version>6.6.163</carbon.apimgt.version>
</properties>
</project>
我相信你只需要更改 <Export-Package>
中的包信息,将 JAR 文件复制到 $APIM_HOME/repository/components/dropins
并重新启动服务器。
如果出现问题,请告诉我。如果有效,请将答案标记为正确以帮助他人。 :)