سؤال

أحتاج إلى الاتصال بخدمة ويب مكتوبة بلغة .NET من Java.تطبق خدمة الويب مكدس WS-Security (إما WSE 2 أو WSE 3، هذا غير واضح من المعلومات المتوفرة لدي).

تتضمن المعلومات التي تلقيتها من موفر الخدمة WSDL، وملف PolicyCache.config، وبعض نماذج تعليمات برمجية C#، ونموذج تطبيق يمكنه الاتصال بالخدمة بنجاح.

هذا ليس مفيدًا كما يبدو لأنه ليس من الواضح كيف من المفترض أن أستخدم هذه المعلومات لكتابة عميل Java.إذا لم يتم توقيع طلب خدمة الويب وفقًا للسياسة، فسيتم رفضه من قبل الخدمة.أحاول استخدام Apache Axis2 ولا يمكنني العثور على أي تعليمات حول كيفية استخدام ملف PolicyCahce.config وWSDL لإنشاء عميل.

هناك العديد من الأمثلة التي عثرت عليها على الويب، ولكن في جميع الحالات كان مؤلفو الأمثلة يتحكمون في كل من الخدمة والعميل، وبالتالي كانوا قادرين على إجراء تعديلات على كلا الجانبين حتى تعمل الخدمة.أنا لست في هذا الموقف.

لقد فعلت كل هذا بنجاح؟

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

المحلول 2

يبدو أن هذا سؤال شائع لذا سأقدم نظرة عامة على ما فعلناه في موقفنا.

يبدو أن الخدمات المضمنة في .NET تتبع معيارًا أقدم لعناوين ws (http://schemas.xmlsoap.org/ws/2004/03/addressing/) والمحور 2 يفهم فقط المعيار الأحدث (http://schemas.xmlsoap.org/ws/2004/08/addressing/).

بالإضافة إلى ذلك، فإن الملف PolicyCache.config المقدم موجود في نموذج لا تستطيع وحدة axis2 المتراس فهمه.

إذن الخطوات التي كان علينا القيام بها باختصار:

  • اقرأ ملف PolicyCache.config وحاول فهمه.ثم أعد كتابتها في سياسة يمكن أن يفهمها المتراس.(بعض المستندات المحدثة ساعد.)
  • تكوين متراس مع هذه السياسة.
  • خذ المفاتيح التي تم توفيرها في ملف .pfx وقم بتحويلها إلى مخزن مفاتيح جافا.هناك أداة مساعدة تأتي مع Jetty يمكنها القيام بذلك.
  • قم بتكوين متراس مع مخزن المفاتيح هذا.
  • اكتب معالج axis2 مخصصًا يقوم بتحويل عناصر عنوان ws الأحدث التي تخرج من axis2 إلى العناصر الأقدم التي تتوقعها الخدمة.
  • قم بتكوين axis2 لاستخدام المعالج على الرسائل الصادرة.

في النهاية، كان هناك الكثير من التكوينات والتعليمات البرمجية لشيء من المفترض أن يكون معيارًا مفتوحًا يدعمه البائعون.

على الرغم من أنني لست متأكدًا من البديل... هل يمكنك الانتظار حتى يتأكد البائعون (أو البائع الوحيد في هذه الحالة) من أن كل شيء سيتم تنفيذه بشكل متبادل؟

كملحق، سأضيف أنني لم أنهي العمل في نهاية المطاف، بل كان شخصًا آخر في فريقي، لكنني أعتقد أنني حصلت على التفاصيل البارزة بشكل صحيح.كان الخيار الآخر الذي كنت أفكر فيه (قبل أن يتولى زميلي في الفريق) هو الاتصال بواجهة برمجة تطبيقات WSS4J مباشرة لإنشاء مظروف SOAP كما توقعته خدمة .NET.أعتقد أن هذا كان سينجح أيضًا.

نصائح أخرى

لا يتم تضمين مواصفات WS-Security عادةً في WSDL (ليس في WSE WSDL أبدًا).لذا فإن wsdl2java لا يعرف أن WS-Security مطلوب حتى لهذه الخدمة.حقيقة أن القيود الأمنية غير موجودة في WSE WSDL هي خيبة أمل كبيرة بالنسبة لي (سوف يتضمن WCF معلومات WS-Trust في WSDL).

من ناحية العميل، سوف تحتاج إلى استخدام رامبارت لإضافة رؤوس WS-Security الضرورية إلى رسالة العميل الصادرة.نظرًا لأن WSDL لا يُبلغ عن إعدادات WS-Security الضرورية، فمن الأفضل أن تسأل مزود الخدمة عما هو مطلوب.قد تكون متطلبات WS-Security عبارة عن كلمة مرور نصية بسيطة، أو قد تكون شهادات X509، أو قد تكون رسالة مشفرة .....يجب أن يكون Rampart قادرًا على التعامل مع معظم هذه السيناريوهات.

يتم "تشغيل" Apache Rampart من خلال إشراك الوحدة في ملف axis2.xml الخاص بك.ستحتاج إلى تنزيل وحدة Rampart ووضعها في مكان محدد في دليل axis2 الخاص بك، ثم تعديل ملف xml.يمكنك أيضًا إشراك Rampart برمجيًا (يُرجى تعديل سؤالك الأصلي إذا كان هذا مطلبًا وسأقوم بتحرير هذا الرد).

اعتمادًا على كيفية تكوين المتراس (من خلال ملفات XML أخرى أو برمجيًا)، فإنه سيعترض أي رسائل صادرة ويضيف معلومات WS-Security الضرورية إليه.لقد استخدمت شخصيًا axis2 مع المتراس للاتصال بخدمة WSE3 المؤمنة باستخدام UsernameToken بنص عادي وقد عملت بشكل رائع.يجب أيضًا أن تعمل السيناريوهات المشابهة، ولكن الأكثر تقدمًا.هناك المزيد من التفاصيل حول كيفية الإعداد والبدء باستخدام Rampart على الموقع المرتبط أعلاه.إذا كانت لديك مشاكل حول تفاصيل Rampart أو كيفية استخدام Rampart مع إعداد WSE الخاص بك، فقم بتحرير سؤالك وسأبذل قصارى جهدي للإجابة.

@ مايك

لقد قمت مؤخرًا بإجراء اختبار وهذا هو الرمز الذي استخدمته.أنا لا أستخدم عناصر السياسة، ولكنني استخدمت WS-Security مع مصادقة النص العادي.لدى CXF وثائق جيدة حقًا حول كيفية إنجاز هذه الأشياء.

لقد استخدمت wsdl2java ثم أضفت هذا الرمز لاستخدام خدمة الويب مع ws-security.

آمل أن يكون هذا يساعدك.

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSPasswordCallback;
import org.apache.ws.security.handler.WSHandlerConstants;

public class ServiceTest implements CallbackHandler
{

     public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {

            WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
            // set the password for our message.
            pc.setPassword("buddah");
        }

    public static void main(String[] args){
        PatientServiceImplService locator = new PatientServiceImplService();
        PatientService service = locator.getPatientServiceImplPort();

        org.apache.cxf.endpoint.Client client = org.apache.cxf.frontend.ClientProxy.getClient(service);
        org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint();

        Map<String, Object> outProps = new HashMap<String, Object>();
        outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN + " " +  WSHandlerConstants.TIMESTAMP);
        outProps.put(WSHandlerConstants.USER, "joe");
        outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);

        // Callback used to retrieve password for given user.
        outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ServiceTest.class.getName());

        WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
        cxfEndpoint.getOutInterceptors().add(wssOut);


        try
        {
            List list = service.getInpatientCensus();
            for(Patient p : list){
                System.out.println(p.getFirstName() + " " + p.getLastName());
            }

        }
        catch (Exception e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

CXF - سأبحث في CXF.لقد استخدمته لإنشاء خدمة ويب وعميل في Java باستخدام ws-secuirty.لقد قمت أيضًا بتوصيل خدمة ويب .net بها.

لديهم وثائق جيدة جدا أيضا.لقد كان حظي به أكثر من المحور.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top