Настроить аутентификацию для сервлетов в OSGi
В качестве контейнера у меня установлен Karaf 3.0.2, в котором используется сеть pax (я думаю, что опять-таки используется причал). У меня есть несколько сервлетов, которые я регистрирую как сервис OSGi под определенным псевдонимом.
По умолчанию файл etc/jetty.xml настроен так, что я могу использовать JAASLoginService, который я тоже хочу использовать.
Проблема в том, что я хочу использовать как базовую, так и аутентификацию форм:
- Все соответствующие /ui/* должны использовать аутентификацию формы
- Все, что соответствует /rest/* должно использовать базовую аутентификацию
Я очень старался, но даже не нашел точки, с которой мог бы начать. Я думаю, что можно настроить каждый сервлет, но я хочу сделать это глобально.
Есть идеи?
1 ответ
Вы должны немного дифференцироваться здесь. Если вы используете WebApplicationBundle (WAB) для развертывания ваших сервлетов, у вас есть все обычные элементы веб-приложения. Включая базовую или блочную аутентификацию.
Поскольку вы используете OSGi способ регистрации сервлетов, вы можете сделать это только с помощью HttpContext. Приведенный ниже пример взят из Pax Web Samples, он использует базовую аутентификацию.
public class AuthHttpContext implements HttpContext {
public boolean handleSecurity(HttpServletRequest req,
HttpServletResponse res) throws IOException {
if (req.getHeader("Authorization") == null) {
res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
if (authenticated(req)) {
return true;
} else {
res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
}
protected boolean authenticated(HttpServletRequest request) {
request.setAttribute(AUTHENTICATION_TYPE, HttpServletRequest.BASIC_AUTH);
String authzHeader = request.getHeader("Authorization");
String usernameAndPassword = new String(Base64.decodeBase64(authzHeader.substring(6).getBytes()));
int userNameIndex = usernameAndPassword.indexOf(":");
String username = usernameAndPassword.substring(0, userNameIndex);
String password = usernameAndPassword.substring(userNameIndex + 1);
// Here I will do lame hard coded credential check. HIGHLY NOT RECOMMENDED!
boolean success = ((username.equals("admin") && password
.equals("admin")));
if (success)
request.setAttribute(REMOTE_USER, "admin");
return success;
}
...
}
Для форм на основе вам понадобится дополнительный HttpContext. Для каждого подходящего пути необходимо убедиться, что зарегистрирован правильный HttpContext, следующий код также можно найти в Pax Web Samples.
public final class Activator implements BundleActivator {
...
public void start(BundleContext bc) throws Exception {
httpServiceRef = bc.getServiceReference(HttpService.class);
if (httpServiceRef != null) {
httpService = (HttpService) bc.getService(httpServiceRef);
...
httpService.registerServlet("/status-with-auth",
new StatusServlet(), null, new AuthHttpContext());
}
}
...
}