Я хочу аутентифицировать веб-сервисы либо с помощью ssl сертификата (нацеленного на автоматизацию), либо openid (нацеленного на людей, я использую auth0 в качестве провайдера). Веб-службы работают в контейнере Tomcat, который находится за веб-сервером Apache, используя jk. Веб-сервер уже аутентифицирует пользователя, используя auth0 (используя mod_auth_openidc) для других путей и доступный только через https. У меня также есть база данных, которая в настоящее время сопоставляет имена пользователей, предоставленные auth0, с ролями (используется для авторизации в apache).
Мне бы хотелось иметь следующие функции:
- выяснить имя пользователя
- , если apache уже вошел в систему пользователя, используйте имя пользователя
- , если в запросе используется сертификат клиента, используйте DN в качестве имени пользователя
- , если ничего из вышеперечисленного,затем перенаправить, чтобы apache выполнил аутентификацию
- и выяснил роль
- при поиске в базе данных на основе имени пользователя
Я понял, что мне, возможно, придется написать фильтр, и из прокси-документации jk кажется, что я могу получить сертификат и имя пользователя из запроса. Я написал следующий код:
package com.kodekonveyor.realm;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
public class KKAuthorizationFilter implements Filter {
private ServletContext context;
@Override
public void init(FilterConfig fConfig) throws ServletException {
this.context = fConfig.getServletContext();
this.context.log("KKAuthorizationFilter initialized");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String user = httpRequest.getRemoteUser();
Object cert = httpRequest.getAttribute("javax.servlet.request.X509Certificate");
this.context.log("user:"+user);
this.context.log("cert:"+cert);
chain.doFilter(request, response);
}
}
Однако, когда я пытаюсь связаться с сервлетом с пользователем, который в данный момент аутентифицирован, или с аутентификацией ssl клиента, и пользователь, и сертификат регистрируются как нулевые. Я подозреваю, что мне нужно сделать еще несколько настроек Apache, чтобы заставить его работать. Тестовый сервлет находится в / servlet / servlet в tomcat.
У меня есть следующая конфигурация apache (части для пивоварения не указаны)
DocumentRoot /var/www/repo
#correct OIDC configuration omitted
<VirtualHost myhost.mydomain.com:443>
ServerName myhost.mydomain.com
DBDriver pgsql
#other DBD configurations are omitted
JkMount /servlet* worker1
<Directory /var/www/repo/servlet>
DirectoryIndex off
RewriteEngine Off
AuthType openid-connect
AllowOverride None
AuthzDBDQuery "a correct database query"
Require dbd-group allrepo
LogLevel debug
</Directory>
<Directory /var/www/repo>
DirectoryIndex off
RewriteEngine Off
AllowOverride None
</Directory>
#correct letsencrypt configuration omitted
</VirtualHost>