문제

세분화 된 인증이있는 Restlet을 사용하여 리소스를 노출하고 싶습니다. 나의 ServerResource 접근 할 수 있어야합니다 GET 인증 된 멤버 (기본 인증 사용)에만 해당됩니다. 그러나 사용 요청 POST 인증없이 발신자에게도 사용할 수 있어야합니다.

개간하기 위해 :http : // path/myapp/user 누구나 사용하여 등록 할 수 있어야합니다 POST, 그러나 등록 된 회원 만 할 수 있어야합니다 GET 모든 사용자의 목록.

불행히도 Restlet에별로 빠지지 않으며 전체에 대한 더 거친 인증을 사용하여 예제 만 찾습니다. Restlets 또는 Router에스.

그렇다면 리소스에 대한 선택적 인증을 어떻게 활성화하고 메드 당 수준에서 확인합니까?

미리 감사드립니다!

도움이 되었습니까?

해결책

Restlet 2.0에서 기본 인증을 수행하려면 (언급 한 이후 2.0을 사용하고 있다고 가정합니다. ServerResource), 당신은 a를 사용해야합니다 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
        // ...
    }
}

이 예는 Get On Get에 대한 인증 정책을 적용합니다. UserResource 라우터가 처리하는 다른 리소스가 아닙니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top