質問

私は細粒度の認証でのRestletを使用してリソースを公開します。私ServerResourceは認証済みメンバー(BASIC認証を使用して)ためGET経由でアクセス可能でなければなりません。しかし、POSTを使用して要求は認証なし発信者のためにも利用可能であるべきです。

clearifyするために: のhttp://パス/ myappに/ユーザーはには、誰でもPOSTを使用して登録できるようにする必要がありますが、登録したメンバーだけのことができるようになりすべてのユーザのリストをGET

私はあまりのRestletに、残念ながらだと私は全体のみRestletsまたはRoutersのための粗い認証を用いた例を見つけます。

それでは、どのように私は、リソースのためのオプションの認証を有効にし、メソッドごとのレベルでそれらをチェックしますか?

事前に感謝します!

役に立ちましたか?

解決

のRestlet 2.0で基本的な認証を行うには(あなたがServerResourceに言及以来、私はあなたが2.0を使用していると仮定)、あなたは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
        // ...
    }

}

他のヒント

私は現在のRestlet 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とされていない他のリソースへのGETに認証のポリシーを適用されることに注意します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top