当Coldfusion从'jar'文件中调用方法时,未编译的Java程序可以正常工作,但会产生错误?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当Coldfusion从'jar'文件中调用方法时,未编译的Java程序可以正常工作,但会产生错误?相关的知识,希望对你有一定的参考价值。
项目:
将JWT转换为已签名的加密JWE
环境:
- Windows 10
- Jdk1.d
- Apache Maven 3.5.4
- VSCode 1.25.1包含所有必需的Java扩展
- 带有JRE1.8的Adobe Coldfusion 11 Application Server
依赖关系:
- 灵气何塞 - 智威汤逊 - 6.0
- JSON-智能2.3
- ASM-1.0.2
问题:
首先,请理解我是Java的新手,但我对Coldfusion [CFML,如php]有很好的理解。
当我从VSCode中运行我的程序时,我得到序列化JWT字符串的预期结果。
当我尝试从'jar'文件中访问该方法时,使用我的服务器端语言Coldfusion [类似于PHP],我得到一个错误,来自最后一行。
构造函数已成功初始化,并且大多数方法调用都会执行。
我仔细测试了每一行,绝大多数代码在外部调用'JwtSignEncrypt'类的'Encrypt()'方法时都有效,但是最后一行失败并出现以下错误。
The JWE object must be in an encrypted or decrypted state
堆栈跟踪的重要部分:
java.lang.IllegalStateException: The JWE object must be in an encrypted or decrypted state
at com.nimbusds.jose.JWEObject.ensureEncryptedOrDecryptedState(JWEObject.java:320)
at com.nimbusds.jose.JWEObject.serialize(JWEObject.java:456)
at com.chamika.jwt.JwtSignEncrypt.Encrypt(JwtSignEncrypt.java:153)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at coldfusion.runtime.StructBean.invoke(StructBean.java:508)
at coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2553)
at cftest412ecfm1275900201.runPage(C:ColdFusion11cfusionwwwrootestablishmindfulnessunit-test est41.cfm:129)
at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:246)
at coldfusion.tagext.lang.IncludeTag.handlePageInvoke(IncludeTag.java:736)
at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:572)
at coldfusion.filter.CfincludeFilter.invoke(CfincludeFilter.java:65)
at coldfusion.filter.IpFilter.invoke(IpFilter.java:45)
at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:466)
at coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:42)
at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40)
at coldfusion.filter.PathFilter.invoke(PathFilter.java:142)
at coldfusion.filter.LicenseFilter.invoke(LicenseFilter.java:30)
at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:94)
at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)
at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38)
at coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:58)
at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)
at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)
at coldfusion.filter.CachingFilter.invoke(CachingFilter.java:62)
at coldfusion.CfmServlet.service(CfmServlet.java:219)
at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42)
at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at coldfusion.inspect.weinre.MobileDeviceDomInspectionFilter.doFilter(MobileDeviceDomInspectionFilter.java:121)
at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:422)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
JW TSI缸内encrypt.Java
package com.chamika.jwt;
import java.util.*;
import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.*;
import com.nimbusds.jwt.*;
public class JwtSignEncrypt
{
String issuer;
String subject;
List<String> audience;
Date expirationTime;
Date notBeforeTime;
Date issueTime;
String jwtID;
Map<String, Object> claim;
public JwtSignEncrypt(final String iss,
final String sub,
final String aud,
final Date exp,
final Date nbf,
final Date iat,
final String jti,
Map<String, Object> cla) {
if(iss != null) {
this.issuer = iss;
}
if(sub != null) {
this.subject = sub;
}
if(aud != null) {
List<String> items = Arrays.asList(aud.split("\s*,\s*"));
this.audience = items;
}
if(exp != null) {
this.expirationTime = exp;
}
if(nbf != null) {
this.notBeforeTime = nbf;
}
if(iat != null) {
this.issueTime = iat;
}
if(jti != null) {
this.jwtID = jti;
}
if(cla != null) {
this.claim = cla;
}
}
public String Encrypt(byte[] secretKeyEncoded) {
String key = null;
Object value = null;
for (Map.Entry<String, Object> entry : claim.entrySet()) {
key = entry.getKey();
value = entry.getValue();
}
JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer(this.issuer).subject(this.subject).audience(this.audience).expirationTime(this.expirationTime).notBeforeTime(this.notBeforeTime).issueTime(this.issueTime).jwtID(this.jwtID).claim(key,value).build();
String jweobject = "";
JWSSigner signer;
try {
signer = new MACSigner(secretKeyEncoded);
SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.HS256), claimsSet);
try {
signedJWT.sign(signer);
} catch (JOSEException e) {
e.printStackTrace();
}
JWEObject jweObject = new JWEObject(
new JWEHeader.Builder(JWEAlgorithm.DIR, EncryptionMethod.A256GCM)
.contentType("JWT")
.build(),
new Payload(signedJWT));
try {
jweObject.encrypt(new DirectEncrypter(secretKeyEncoded));
} catch (KeyLengthException e) {
e.printStackTrace();
} catch (JOSEException e) {
e.printStackTrace();
}
jweobject = jweObject.serialize();
} catch (KeyLengthException e) {
e.printStackTrace();
}
return jweobject;
}
}
在java文件中的以下行发生错误:
jweObject.encrypt(new DirectEncrypter(secretKeyEncoded));
Coldfusion onRequestStart方法中的Java Loader:
<cfset request.lckchamikajwtlibinit = true />
<cfif NOT StructKeyExists(APPLICATION,"chamikajwtlib") OR request.appreload>
<cftry>
<cflock name="chamikajwtlib" type="exclusive" timeout="#request.writelocktimeout#">
<cfset local.jbClasschamikajwt = "#request.filepathasset#libchamika-jwt-sign-encryptchamika-jwt-sign-encrypt-1.0.2.jar" />
<cfset local.javaloader = createObject('component','com.javaloader.JavaLoader') />
<cfset application.chamikajwtlib = local.javaloader.init([local.jbClasschamikajwt]) />
</cflock>
<cfcatch>
<cfset request.lckchamikajwtlibinit = false />
</cfcatch>
</cftry>
</cfif>
<cfif request.lckchamikajwtlibinit>
<cflock NAME="chamikajwtliblck" TIMEOUT="#request.readlocktimeout#" TYPE="READONLY">
<cfset request.chamikaJwtSignEncryptJar= application.chamikajwtlib />
</cflock>
<cfelse>
<cfset request.chamikaJwtSignEncryptJar= "" />
</cfif>
test.cfm
<cfscript>
local = {};
local.loader = request.chamikaJwtSignEncryptJar;
local.issuer = JavaCast("string","https://openid.net");
local.subject = JavaCast("string","Charles Robertson");
local.audience = "https://app-one.com,https://app-two.com";
local.expirationTime = createObject("java","java.util.Date").init().getTime() + 60 * 1000;
local.expirationTime = createObject("java","java.util.Date").init(local.expirationTime);
local.currentDateTime = createObject("java","java.util.Date").init();
local.notBeforeTime = local.currentDateTime;
local.issueTime = local.currentDateTime;
local.jwtID = JavaCast("string",CreateUUID());
local.claim = createObject("java", "java.util.LinkedHashMap").init();
local.json = {forename="Charles",surname='Robertson'};
local.claim['json'] = SerializeJson(local.json);
local.JwtSignEncrypt = local.loader.create("com.chamika.jwt.JwtSignEncrypt").init(local.issuer,local.subject,local.audience,local.expirationTime,local.notBeforeTime,local.issueTime,local.jwtID,local.claim);
local.keyGen = local.loader.create("javax.crypto.KeyGenerator").getInstance("AES");
local.keyGen.init(256);
local.secretKeyEncoded = local.keyGen.generateKey().getEncoded();
local.jweString = local.JwtSignEncrypt.Encrypt(local.secretKeyEncoded);
writeDump(var=local.jweString);
</cfscript>
pom.hml
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.chamika.jwt</groupId>
<artifactId>chamika-jwt-app</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>chamika-jwt-app</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
<version>6.0</version>
</dependency>
<dependency>
<groupId>net.minidev</groupId>
<artifactId>json-smart</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>net.minidev</groupId>
<artifactId>asm</artifactId>
<version>1.0.2</version>
</dependency>
</dependencies>
</project>
我已经正确地将所有必需的库包含在我的'jar'中。当我打包'jar'时,我还需要采取其他措施。我正在使用'pom.xml'文件,有3个依赖项。出于某种原因,当我跑:
nvm package
不包含依赖项。所以,我已经使用'jarsplice'来捆绑依赖项。可以在外部独立地正确访问所有依赖项。
问题:
- 当我尝试生成签名加密的JWT时,为什么我在使用Coldfusion调用'.jar'文件中的方法时会收到错误?
- 为什么我的依赖项不包含在打包的“.jar”文件中?
更新:
这是我的git回购:
https://bitbucket.org/charlesrobertson/chamika-jwt-app/src/master/
我的java类基于官方文档片段:
https://connect2id.com/products/nimbus-jose-jwt/examples/signed-and-encrypted-jwt
- 当我尝试生成签名加密的JWT时,为什么我在使用Coldfusion调用'.jar'文件中的方法时会收到错误?
我和CF11有同样的错误。问题是try/catch
代码基本上吞下了错误,因为CF没有在屏幕上显示e.printStackTrace()的输出。它被发送到默认日志文件。因此,您甚至不会知道发生异常 - 除非您检查CF日志。
错误处理全部取决于应用程序,但我的想法是,如果方法不能对错误做任何有用的事情,也可以让它冒泡并让调用者决定如何处理它。无论如何,一旦我摆脱了所有的try/catch
并为所有方法添加了throws XYZException
,如下所示:
public String Encrypt(byte[] secretKeyEncoded) throws KeyLengthException, JOSEException {
// ...
jweObject.encrypt(new DirectEncrypter(secretKeyEncoded));
// ...
}
...我可以在屏幕上看到错误消息。无法创建AES / GCM / NoPadding密码:密钥大小非法。这意味着除非安装了Unlimited JCE files,否则无法创建256位密钥(或更高)。解决方案是下载并安装Unlimited JCE文件并重新启动CF.之后,jar工作正常(具有3个依赖项)。
- 下载java版本的文件。例如,对于java 8 - jce_policy-8.zip
- 备份
local_policy.jar
中现有的US_export_policy.jar
和<java-home>libsecurity
文件 - 解压缩文件并将新的
local_policy.jar
和US_export_policy.jar
复制到<java-home>libsecurity
- 重启CF服务器(必填)
- 为什么我的依赖项不包含在打包的“.jar”文件中?
Maven不包含依赖项,除非它是specified in the pom.xml,它不适用于此项目。就个人而言,我避免这样做。将所有内容打包到一个大的超级jar中很方便,但是更难以处理依赖项中的版本更改。我只是分别加载相关的罐子。
以上是关于当Coldfusion从'jar'文件中调用方法时,未编译的Java程序可以正常工作,但会产生错误?的主要内容,如果未能解决你的问题,请参考以下文章