使用RESTlet进行细粒度身份validation

我想使用具有细粒度身份validation的RESTlet公开资源。 我的ServerResource应该只能通过GET访问经过身份validation的成员(使用BASIC身份validation)。 但是,对于没有任何身份validation的呼叫者,使用POST请求也应该可用。

为了清除: http:// path / myapp / user应该允许任何人使用POST注册,但只有注册的成员才能获得所有用户的列表。

遗憾的是,我很少进入RESTlet,我只找到使用粗略身份validation整个RestletRouter的示例。

那么如何为资源启用可选身份validation并在每个方法级别上检查它们?

提前致谢!

要在RESTlet 2.0中进行基本身份validation(我假设您在使用ServerResource使用的是2.0),您需要使用ChallengeAuthenticator 。 如果使用optional = true配置,则只有在调用ChallengeAuthenticator.challenge()才会请求身份validation。

您可以使用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()以执行身份validation或基于请求方法跳过它。 例如,下面的资源只需要在使用GET方法时进行身份validation。

应用:

 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进行身份validation的策略应用于UserResource ,而不应用于路由器处理的其他资源。