سؤال

أريد أن أعرض موردا باستخدام الرينلت مع مصادقة محتملة على ما يرام. لي ServerResource يجب أن يكون الوصول إليها عبر GET فقط للمصادقة الأعضاء (باستخدام المصادقة الأساسية). ومع ذلك، تطلب الطلبات POST يجب أن تكون متاحة أيضا للمتصلين دون أي مصادقة.

من أجل مسح:http: // path / myapp / المستخدم يجب أن تسمح لأي شخص التسجيل باستخدام POST, ، ولكن الأعضاء المسجلين فقط يجب أن يكونوا قادرين على GET قائمة بجميع المستخدمين.

أنا لسوء الحظ ليس كثيرا في الرؤية وأجد أمثلة فقط باستخدام مصادقة الخشرية بالكامل RestletS أو Routerس.

إذن كيف يمكنني تمكين المصادقة الاختيارية للموارد وتحقق منها على مستوى لكل طريقة؟

شكرا لك مقدما!

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

المحلول

للقيام المصادقة الأساسية في الرؤية 2.0 (أفترض أنك تستخدم 2.0 منذ أن ذكرت ServerResource)، تحتاج إلى استخدام ChallengeAuthenticator. وبعد إذا تم تكوين هذا مع optional = true ثم سيتم طلب المصادقة إلا إذا استدعيت ChallengeAuthenticator.challenge().

يمكنك إنشاء طلبك مع authenticate() الطريقة، واتصل بهذا كلما احتجت إلى الحصول على مورد مضمون:

تطبيق:

package example;

import org.restlet.*;
import org.restlet.data.ChallengeScheme;
import org.restlet.routing.Router;
import org.restlet.security.*;

public class ExampleApp extends Application {

    private ChallengeAuthenticator authenticatior;

    private ChallengeAuthenticator createAuthenticator() {
        Context context = getContext();
        boolean optional = true;
        ChallengeScheme challengeScheme = ChallengeScheme.HTTP_BASIC;
        String realm = "Example site";

        // MapVerifier isn't very secure; see docs for alternatives
        MapVerifier verifier = new MapVerifier();
        verifier.getLocalSecrets().put("user", "password".toCharArray());

        ChallengeAuthenticator auth = new ChallengeAuthenticator(context, optional, challengeScheme, realm, verifier) {
            @Override
            protected boolean authenticate(Request request, Response response) {
                if (request.getChallengeResponse() == null) {
                    return false;
                } else {
                    return super.authenticate(request, response);
                }
            }
        };

        return auth;
    }

    @Override
    public Restlet createInboundRoot() {
        this.authenticatior = createAuthenticator();

        Router router = new Router();
        router.attach("/user", UserResource.class);

        authenticatior.setNext(router);
        return authenticatior;
    }

    public boolean authenticate(Request request, Response response) {
        if (!request.getClientInfo().isAuthenticated()) {
            authenticatior.challenge(response, false);
            return false;
        }
        return true;
    }

}

الموارد:

package example;

import org.restlet.data.MediaType;
import org.restlet.representation.EmptyRepresentation;
import org.restlet.representation.Representation;
import org.restlet.representation.StringRepresentation;
import org.restlet.resource.ServerResource;

public class UserResource extends ServerResource {

    @Override
    public Representation get() {
        ExampleApp app = (ExampleApp) getApplication();
        if (!app.authenticate(getRequest(), getResponse())) {
            // Not authenticated
            return new EmptyRepresentation();
        }

        // Generate list of users
        // ...
    }     

    @Override
    public Representation post(Representation entity) {
        // Handle post
        // ...
    }

}

نصائح أخرى

أنا حاليا باستخدام الرؤية v2.0.10.

المشكلة مع ChallengeAuthenticator.isOptional() هو أنه كل شيء أو لا شيء. بديل للإجابة المقدمة من قبل @ Sea36 أعلاه هو تجاوز ChallengeAuthenticator.beforeHandle() إما لأداء المصادقة أو تخطيها بناء على طريقة الطلب. على سبيل المثال، ستطلب المورد أدناه مصادقة فقط عند استخدام طريقة Get.

تطبيق:

package example;

import org.restlet.*;
import org.restlet.data.ChallengeScheme;
import org.restlet.routing.Router;
import org.restlet.security.ChallengeAuthenticator;
import org.restlet.security.MapVerifier;

public class ExampleApp extends Application {

    private ChallengeAuthenticator createAuthenticator() {
        Context context = getContext();
        ChallengeScheme challengeScheme = ChallengeScheme.HTTP_BASIC;
        String realm = "Example site";

        // MapVerifier isn't very secure; see docs for alternatives
        MapVerifier verifier = new MapVerifier();
        verifier.getLocalSecrets().put("user", "password".toCharArray());

        ChallengeAuthenticator authOnGet = new ChallengeAuthenticator(context, challengeScheme, realm) {
            @Override
            protected int beforeHandle(Request request, Response response) {
                if (request.getMethod() == Method.GET)
                    return super.beforeHandle(request, response);

                response.setStatus(Status.SUCCESS_OK);
                return CONTINUE;
            }
        };

        return authOnGet;
    }

    @Override
    public Restlet createInboundRoot() {
        ChallengeAuthenticator userResourceWithAuth = createAuthenticator();
        userResourceWithAuth.setNext(UserResource.class);

        Router router = new Router();
        router.attach("/user", userResourceWithAuth);

        return router;
    }

}

الموارد:

package example;

import org.restlet.resource.Get;
import org.restlet.resource.Post;
import org.restlet.representation.Representation;
import org.restlet.resource.ServerResource;

public class UserResource extends ServerResource {

    @Get
    public Representation listUsers() {
        // retrieve list of users and generate response
        // ...
    }     

    @Post
    public void register(Representation entity) {
        // handle post
        // ...
    }
}

لاحظ أن هذا المثال ينطبق على سياسة المصادقة على الحصول على فقط إلى UserResource وليس موارد أخرى يتم التعامل معها بواسطة جهاز التوجيه.

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