簡體   English   中英

從Java 7更新45開始,如果不觸發警告就不能不再查找清單信息嗎?

[英]As of Java 7 update 45, one can no longer lookup manifest information without triggering a warning?

不幸的是,如果您的應用程序需要訪問其加載的已簽名簽名的jar清單,那么Oracle和其他人在此處提供的解決方法( Java applet清單-允許所有Caller-Allowable-Codebase )解決7 update 45問題不起作用。 就我而言,我們的應用程序這樣做是為了記錄相關的清單信息。

使用我的網絡啟動應用程序,使用7u21需要添加的“ Trusted-Library”屬性,一切正常且繁瑣。 使用7u45時,刪除“ Trusted-Library”屬性並添加其他變通方法中討論的所有其他屬性將不起作用-如果您在沒有Trusted-Library屬性的情況下運行7u21,我將得到相同的警告(說明應用程序包含簽名和未簽名的代碼):

Java 7 Update 45警告]![在此處輸入圖像描述

我已經嘗試了幾乎所有可能的清單/ JNLP排列-沒什么能榨菜的。

我發現,基本上,當我們加載小程序的jar清單之一(而不是JRE jar)並調用hasMoreElements時,會發生其他安全檢查,並觸發警告:

   public List<String> getManifests() {
          ...         

          Enumeration<URL> urls = getClass().getClassLoader().getResources("META-INF/MANIFEST.MF");

          while (urls.hasMoreElements()) {
                 .... a bunch of loop stuff
                 // at the end of the loop...
                 System.out.println("Checkpoint SGMLOOP8.");

                 System.out.println("Breaking....");
                 //break; <<<<<<---- if the next jar is one of our signed jars, the next line will trigger the warning. If instead we choose to break, the app works perfectly with no warning.

                 System.out.println("urls.hasMoreElements(): " + (urls.hasMoreElements() ? "true" : "false"));  <<<<<<-------- will evaluate to false if user clicks Block on the warning, otherwise will evaluate to true when our signed jars are next

                 System.out.println("Checkpoint SGMLOOP9."); 
          }
          ...
      }

這是在Java控制台中以最大跟蹤輸出的內容:

Checkpoint SGMLOOP8.
Breaking....                  <<<<---- console output pauses here until user answers warning
security: resource name "META-INF/MANIFEST.MF" in http://<path_to_jar> : java.lang.SecurityException: trusted loader attempted to load sandboxed resource from http://<path_to_jar>
(message repeats for all our signed jars)
urls.hasMoreElements(): false <<<<---- false because user clicked blocked, otherwise true when user clicks don't block
Checkpoint SGMLOOP9.

我花了永遠的時間來解決這個問題,因為出於某種原因,當簽名的清單在啟動過程的早期通過安全檢查,然后又被訪問並遭到抱怨時,我自然不會認為它在抱怨清單 ,而是清單所引用的資源。 去搞清楚!

查看Java源代碼,可以看到為什么可能發生警告(hasMoreElements導致更多的安全檢查):

// getResources is called in my code above
java.lang.ClassLoader
public Enumeration<URL> getResources(String name) throws IOException {
    Enumeration[] tmp = new Enumeration[2];
    if (parent != null) {
        tmp[0] = parent.getResources(name);
    } else {
        tmp[0] = getBootstrapResources(name);
    }
    tmp[1] = findResources(name); <<<<------ This returns a new Enumeration<URL> object which has its own “hasMoreElments()” method overwritten – see below code

    return new CompoundEnumeration<>(tmp);
}

java.net.URLClassLoader
public Enumeration<URL> findResources(final String name)
    throws IOException
{
    final Enumeration<URL> e = ucp.findResources(name, true);

    return new Enumeration<URL>() {
        private URL url = null;

        private boolean next() {
            if (url != null) {
                return true;
            }
            do {
                URL u = AccessController.doPrivileged(  <<-- Security context could block this
                    new PrivilegedAction<URL>() {
                        public URL run() {
                            if (!e.hasMoreElements())
                                return null;
                            return e.nextElement();
                        }
                    }, acc);
                if (u == null)
                    break;
                url = ucp.checkURL(u);  <<-- Security checks done in here
            } while (url == null);
            return url != null;
        }

        public URL nextElement() {
            if (!next()) {
                throw new NoSuchElementException();
            }
            URL u = url;
            url = null;
            return u;
        }

        public boolean hasMoreElements() {
            return next();
        }
    };
}

是的,清單已正確簽名! 是的,清單確實具有適當的屬性! 實際上,只要我們不嘗試直接訪問它們的清單,罐子就可以很好地加載並執行,這證明了這一點! 為了減輕您的恐懼,以下是相關的清單屬性(我嘗試過對以下屬性進行很多加/減):

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.0
Created-By: 24.45-b08 (Oracle Corporation)
Application-Name: AppName
Codebase: *
Permissions: all-permissions
Application-Library-Allowable-Codebase: *
Caller-Allowable-Codebase: *
Trusted-Only: false
Class-Path: jar1.jar jar2.jar jar3.jar
Specification-Title: AppName
Specification-Version: 1.0
Specification-Vendor: CompanyName
Implementation-Title: AppName
Implementation-Version: 1.0
Implementation-Vendor: CompanyName

問題是:當我們嘗試訪問清單時是否應該發出警告? 就目前而言,我們要么必須選擇強制用戶每次都看到警告,要么我們必須刪除對已簽名的jar清單信息的記錄。 似乎是一個錯誤的選擇,尤其是因為此清單信息對於調試問題非常有用,因為它實際上是驗證最終用戶是否運行了正確版本的應用程序的唯一方法(缺少現場直接物理檢查)。 這對於我們的applet尤其如此,因為允許將jar緩存在客戶端系統上(連同相應的JavaScript來訪問applet),這意味着它們可能在升級/降級等之后很容易地運行錯誤的jar。我們日志中的信息將來可能會引起很大的麻煩。

有任何想法嗎? 由於Oracle打算以任何方式解決Trusted-Library問題,這一點尤其令人沮喪,因此,將所有這些調查工作都用於此可能只是浪費我的周末。 哎呀....

編輯:我的一個觀察是,遇到安全異常的第一個jar實際上依賴於我應用程序中的另一個jar。 我想,“也許應該首先閱讀依賴罐的清單?” 因此,我強制了加載順序,以便首先加載非依賴的jar。 最終結果? 我可以看到非依賴的jar現在首先拋出了安全異常...並且仍然有警告。

我遇到了applet的問題,發現我在自己的applet .jar文件(不是循環中前幾次返回的Java系統.jars)上的hasMoreElements上收到警告,並且僅當applet .jar出現時在Java控制面板中啟用了文件緩存。

我不能讓所有客戶禁用.jar文件緩存,但是那些客戶對此感到滿意,因為不會為他們顯示混合代碼警告。 這不是答案,充其量是一種解決方法。

想要更新這個問題,說從Java 7 Update 55開始,這個問題已被解決,因為可以再次同時放置“ Trusted-Library”和“ Caller-Allowable-Codebase”清單屬性。 在清單中同時使用這兩個屬性時,不會觸發警告。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM