Настроить аутентификацию для сервлетов в 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());
        }
    }
...
}
Другие вопросы по тегам