b_e*_*erb 7 java authentication restlet
我想使用具有细粒度身份验证的RESTlet公开资源.我ServerResource应该只能通过GET身份验证的成员访问(使用BASIC身份验证).但是,POST对于没有任何身份验证的呼叫者,也应该可以使用请求.
为了清除: 
 http:// path/myapp/user应该允许任何人注册使用POST,但只有注册的成员才能够GET拥有所有用户的列表.
遗憾的是,我很少进入RESTlet,我只找到使用粗略身份验证的整个Restlets或Routers的示例.
那么如何为资源启用可选身份验证并在每个方法级别上检查它们?
提前致谢!
Sam*_*Sam 16
要在RESTlet 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
        // ...
    }
}
我目前正在使用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进行身份验证的策略,UserResource而不是路由器处理的其他资源.