细粒度的认证与的Restlet
-
19-09-2019 - |
题
我要揭露使用的Restlet具有细粒度认证的资源。我ServerResource
应该通过GET
只对经过验证的成员(使用基本身份验证)accessable。然而,使用POST
请求应可也没有任何身份验证呼叫者。
在为了clearify:
的http://路径/ MYAPP /用户不允许任何人利用POST
注册,但只有注册会员应该可以GET
所有用户的列表。
我很遗憾没有多少成的Restlet,我只能用粗糙的身份验证整个Restlet
s或Router
s找到例子。
那么,如何使资源可选的认证和检查他们在每个方法的水平?
提前感谢!
解决方案
要做好的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
而不是其他资源的政策。
不隶属于 StackOverflow