Pregunta

Quiero exponer un recurso mediante Restlet con una autenticación de grano fino. Mi ServerResource debe ser accesible a través de GET sólo para los miembros autenticados (mediante la autenticación básica). Sin embargo, las solicitudes utilizando POST deben estar disponibles también para las personas que llaman sin ningún tipo de autenticación.

Para clearify: http: // ruta / miaplicacion / usuario debe permitir que nadie se registra utilizando POST, pero sólo los usuarios registrados debe ser capaz de GET una lista de todos los usuarios.

Estoy por desgracia no mucho en Restlet y sólo encuentro ejemplos más grueso mediante la autenticación de Restlets enteros o Routers.

Entonces, ¿cómo puedo activar la autenticación opcional para los recursos y que no estén en un nivel por método?

Gracias de antemano!

¿Fue útil?

Solución

Para realizar la autenticación básica en Restlet 2.0 (supongo que está utilizando 2.0 ya que mencionas ServerResource), es necesario utilizar un ChallengeAuthenticator. Si esto se configura con optional = true entonces sólo se solicitará la autenticación si se invoca ChallengeAuthenticator.challenge().

Puede crear su aplicación con un método authenticate(), y llamar a esto cada vez que necesite acceso a un recurso para ser asegurado:

Aplicación:

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

}

Recurso:

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

}

Otros consejos

Estoy utilizando actualmente v2.0.10 Restlet.

El problema con ChallengeAuthenticator.isOptional() es que es todo o nada. Una alternativa a la respuesta proporcionada por @ sea36 anterior es para anular ChallengeAuthenticator.beforeHandle() ya sea a realizar la autenticación o saltar basado en método de la petición. Por ejemplo, el recurso a continuación sólo se requiere autenticación cuando se utiliza el método GET.

Aplicación:

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

}

Recurso:

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

Tenga en cuenta que este ejemplo se aplica la política de autenticación de obtener sólo a los UserResource y no otros recursos manejados por el router.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top