Question

Je veux exposer une ressource à l'aide Restlet avec une authentification à grains fins. Mon ServerResource devrait être accessible via GET uniquement pour les membres authentifiés (en utilisant l'authentification de base). Toutefois, les demandes en utilisant POST devraient être disponibles également pour les appels sans authentification.

Pour clearify: http: // chemin / myapp / utilisateur devrait permettre à quiconque d'enregistrer à l'aide POST, mais seuls les membres inscrits devraient pouvoir GET une liste de tous les utilisateurs.

Je ne suis malheureusement pas grand-chose en Restlet et je trouve que des exemples en utilisant l'authentification pour tout le Restlets grossier ou Routers.

Alors, comment puis-je activer l'authentification facultative pour les ressources et les vérifier sur un niveau par méthode?

Merci d'avance!

Était-ce utile?

La solution

Pour l'authentification de base dans Restlet 2.0 (je suppose que vous utilisez 2.0 puisque vous mentionnez ServerResource), vous devez utiliser un ChallengeAuthenticator. Si cela est configuré avec optional = true alors l'authentification ne sera demandé si vous invoquez ChallengeAuthenticator.challenge().

Vous pouvez créer votre application avec une méthode authenticate() et appeler cela chaque fois que vous avez besoin d'accéder à une ressource à sécuriser:

Application:

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;
    }

}

Ressources:

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
        // ...
    }

}

Autres conseils

J'utilise actuellement v2.0.10 Restlet.

Le problème avec ChallengeAuthenticator.isOptional() est qu'il est tout ou rien. Une alternative à la réponse fournie par @ sea36 ci-dessus est de passer outre ChallengeAuthenticator.beforeHandle() soit effectuer l'authentification ou de l'ignorer selon la méthode de la demande. Par exemple, la ressource ci-dessous ne nécessite que l'authentification lorsque la méthode GET est utilisée.

Application:

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;
    }

}

Ressources:

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
        // ...
    }
}

Notez que cet exemple applique la politique d'authentification GET uniquement aux UserResource et non d'autres ressources gérées par le routeur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top