المصادقة الجميلة المحبوب مع الرينلت
-
19-09-2019 - |
سؤال
أريد أن أعرض موردا باستخدام الرينلت مع مصادقة محتملة على ما يرام. لي ServerResource
يجب أن يكون الوصول إليها عبر GET
فقط للمصادقة الأعضاء (باستخدام المصادقة الأساسية). ومع ذلك، تطلب الطلبات POST
يجب أن تكون متاحة أيضا للمتصلين دون أي مصادقة.
من أجل مسح:http: // path / myapp / المستخدم يجب أن تسمح لأي شخص التسجيل باستخدام POST
, ، ولكن الأعضاء المسجلين فقط يجب أن يكونوا قادرين على GET
قائمة بجميع المستخدمين.
أنا لسوء الحظ ليس كثيرا في الرؤية وأجد أمثلة فقط باستخدام مصادقة الخشرية بالكامل Restlet
S أو Router
س.
إذن كيف يمكنني تمكين المصادقة الاختيارية للموارد وتحقق منها على مستوى لكل طريقة؟
شكرا لك مقدما!
المحلول
للقيام المصادقة الأساسية في الرؤية 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
// ...
}
}
نصائح أخرى
أنا حاليا باستخدام الرؤية 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
وليس موارد أخرى يتم التعامل معها بواسطة جهاز التوجيه.