代码之家  ›  专栏  ›  技术社区  ›  Charles Robertson

未编译的Java程序可以工作,但是当Coldfusion从其“jar”文件调用方法时会产生错误?

  •  1
  • Charles Robertson  · 技术社区  · 6 年前

    项目:

    将JWT转换为签名加密JWE

    1. 窗口10
    2. 阿帕奇Maven 3.5.4
    3. 包含所有必需Java扩展的VSCODE1.25.1
    4. Adobe Coldfusion 11应用服务器与JRE1.8

    依赖项:

    1. nimbus-jose-jwt-6.0型
    2. json-smart-2.3版本

    问题:

    首先,请理解我是Java新手,但我对Coldfusion[CFML,比如PHP]有很好的理解。

    当我在VSCode中运行我的程序时,我得到了一个序列化JWT字符串的预期结果。

    当我尝试使用服务器端语言Coldfusion(类似于PHP)从“jar”文件中访问该方法时,从最后一行得到一个错误。

    我仔细测试了每一行代码,绝大多数代码在外部调用'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:\ColdFusion11\cfusion\wwwroot\establishmindfulness\unit-test\test41.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)
    

    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加载程序:

      <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#\lib\chamika-jwt-sign-encrypt\chamika-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>
    

    <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.xml文件

    <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”中。当我打包“罐子”的时候,还有别的步骤需要我做吗。我使用的是“pom.xml”文件,有3个依赖项。出于某种原因,当我跑步时:

    nvm package
    

    不包括依赖项。 所以,我使用“jarsplice”来绑定依赖项。所有依赖项都可以在外部正确、独立地访问。

    问题:

    1. 当我试图生成签名的 文件?
    2. 文件?

    更新:

    这是我的git回购协议:

    https://bitbucket.org/charlesrobertson/chamika-jwt-app/src/master/

    我的java类基于官方文档片段:

    https://connect2id.com/products/nimbus-jose-jwt/examples/signed-and-encrypted-jwt

    1 回复  |  直到 6 年前
        1
  •  1
  •   SOS    6 年前
    1. 当我试图生成带签名的encrytped JWT时,当使用Coldfusion调用“.jar”中的方法时,为什么会出现错误

    我对CF11也有同样的错误。问题是 try/catch 由于CF不显示 e.printStackTrace()

    错误处理完全取决于应用程序,但我的想法是,如果方法无法处理错误,那么不妨让它冒泡起来,让调用方决定如何处理它。不管怎样,一旦我把所有的 尝试/抓住 throws XYZException 所有的方法,像这样:

    public String Encrypt(byte[] secretKeyEncoded) throws KeyLengthException, JOSEException {
        // ...
        jweObject.encrypt(new DirectEncrypter(secretKeyEncoded));
        // ...
    }
    

    无法创建AES/GCM/NoPadding cipher:密钥大小非法。 也就是说,除非安装了 Unlimited JCE files . 解决方案是下载并安装无限的JCE文件并重新启动CF。之后,jar工作正常(有3个依赖项)。

    • 下载java版本的文件。例如,对于java 8- jce_policy-8.zip
    • local_policy.jar US_export_policy.jar 文件 <java-home>\lib\security
    • 解压缩文件并复制新的 美国出口政策.jar <java主页>\lib\security
    • 重新启动CF服务器(必需)
    1. 文件?

    Maven不包含依赖项,除非 specified in the pom.xml ,但不是为了这个项目。就我个人而言,我避免那样做。将所有内容打包到一个大的uber jar中很方便,但会使依赖项中的版本更改更难处理。我只需要把依赖的罐子分开装。