سؤال

أواجه مشكلة غريبة مع تطبيق JSF الذي أعمل عليه حاليًا.يبدو أن هناك جزأين من برنامجي يتصادمان.

هناك قسمان:

  • وظيفة "المصرفية".
  • وظيفة البريد

الجزء ذو الصلة من الوظيفة المصرفية (إنه بنك مزيف لهذا التمرين فقط):

String path = FacesContext.getCurrentInstance().getExternalContext()                .getRealPath("/") + "/WEB-INF/sec/certs.jks";

ErrorHandler.trace(path);

System.setProperty("javax.net.ssl.trustStore", path);

هنا يتم إعداد Trust Store مع شهادة خادم البنك.

ال بريد الجزء يبدو مثل هذا:

Properties props = new Properties();
props.put("mail.smtp.auth", this.smtpServer.isAuthenticated());
props.put("mail.smtp.starttls.enable", this.smtpServer.isTls());
props.put("mail.smtp.host", this.smtpServer.getHostaddr());
props.put("mail.smtp.port", this.smtpServer.getPort());
props.put("mail.smtps.auth", "true");
props.put("mail.smtp.debug", "true");

final String username = this.smtpServer.getUsername();
final String password = this.smtpServer.getPassword();

Session session = Session.getDefaultInstance(props,
        new javax.mail.Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        });

session.setDebug(true);

طريقة واحدة لإعادة إنتاج المشكلة:

المشكلة التي أواجهها هي أنني إذا قمت بتشغيل التطبيق، على سبيل المثال، استخدمت وظيفة "تغيير البريد" فسأتلقى بريد الإشعارات الخاص بي على الفور.لا مشكلة هناك.ثم سأحاول شراء منتج وبالتالي تفعيل وظائف البنك.

وهنا تظهر المشكلة:

Communication Error: javax.ws.rs.WebApplicationException: javax.xml.bind.MarshalException
 - with linked exception:
[javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target]

طريقة أخرى لإعادة إنتاج المشكلة:

لنفترض الآن أنني قمت بإعادة تشغيل تطبيقي وحاولت طلب شيء ما، سيعمل الأمر هذه المرة ولكن وظيفة البريد معطلة مع ظهور رسالة الخطأ هذه:

DEBUG: setDebug: JavaMail version 1.4.7
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle]
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "smtp.gmail.com", port 465, isSSL true
TRACE Error Could not connect to SMTP host: smtp.gmail.com, port: 465

الحد الأدنى:

إذا قمت بتشغيل البنك ثم البريد -> البريد لا يعمل إذا قمت بإطلاق البريد ثم البنك -> البنك لا يعمل

هل من الممكن أن يجد مشكلة هناك؟

شكرًا لك!

هل كانت مفيدة؟

المحلول

تعمل "وظيفتك المصرفية" على تغيير المتجر الموثوق.يحتاج مخزن الثقة الجديد هذا إلى الشهادات اللازمة للتحقق من صحة اتصال SSL بخادم البريد الخاص بك.يمكنك تهيئة مخزن الثقة الخاص بك بجميع شهادات CA من مخزن الثقة الافتراضي لـ JDK، أو يمكنك إضافة الشهادة المحددة لخادم البريد الخاص بك فقط - راجع InstallCert برنامج.وأخيرًا، يمكنك تكوين JavaMail لاستخدام مخزن ثقة منفصل، أو تغيير وظائفك المصرفية لاستخدام مخزن ثقة بشكل صريح بدلاً من تجاوز مخزن الثقة الافتراضي؛ربما تكون هذه أكثر تعقيدًا.

نصائح أخرى

كانت المشكلة هي أن وظيفة البريد كانت تعمل في حالة عدم وجود مجموعة TrustStore (لأنها تستخدم TrustStore الافتراضي للنظام الموجود في:

/Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/jre/lib/security/cacerts

على جهاز ماك.

تستخدم الوظيفة المصرفية شهادتها الخاصة والتي كانت موجودة في:

MyProject/.../WEB-INF/sec/certs.jks

في كل مرة حاول JavaMail المصادقة على خادم SMTP الخاص بـ Google، حاول استخدام certs.jks TrustStore على الرغم من أنني قمت بإلغاء تعيين خاصية TrustStore للوظيفة المصرفية التي تم تعيينها في طريقة البريد.

يصلح:

في بداية طريقة البريد:

String path = FacesContext.getCurrentInstance().getExternalContext()
            .getRealPath("/")
            + "WEB-INF/sec/certs.jks";
System.setProperty("javax.net.ssl.trustStore", path);

استيراد الافتراضي cacerts keyStore في متجر المفاتيح المخصص الخاص بنا:

keytool -importkeystore -srckeystore certs.jks -destkeystore cacerts
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top