Создать собственный HTTP-аутентификатор для Tomcat 9
Мне нужно интегрировать IBM Security Access Manger с Tomcat 9 для аутентификации пользователей. У меня правильно настроен Webseal (соединение) для части IBM SAM. Он принимает учетные данные пользователя, снова аутентифицирует сервер SAM, а затем в случае успеха перенаправляет на Tomcat при прохождении заголовков iv-user
, iv-group
, а также iv-creds
, Теперь мне нужно написать собственный Tomcat Valve, чтобы реализовать аутентификацию и разрешить доступ к приложениям на основе группы пользователей. Каков наилучший способ сделать это?
Моя текущая идея состоит в том, чтобы расширить org.apache.catalina.valves.AuthenticatorBase
так что я могу использовать следующую настройку в web.xml
моего заявления:
<security-constraint>
<web-resource-collection>
<web-resource-name>Application</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>POST</http-method>
<http-method>GET</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>MyRoleName</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
Заголовки из Webseal могут быть проанализированы и использованы для генерации org.apache.catalina.realm.GenericPrincipal
а затем используется для аутентификации в роли, добавленной к данной области (или записывается в tomcat-users.xml
).
Я немного неуверен в том, как на самом деле реализовать эту аутентификацию, поэтому любая помощь, независимо от того, насколько простой, будет высоко цениться.
1 ответ
Самое главное - убедиться, что Tomcat не устанавливает свой собственный Authenticator в ответ на указание BASIC в качестве схемы аутентификации. Расширение из AuthenticatorBase - отличная идея, и вы можете избежать стандартного аутентификатора Tomcat, настроив свой аутентификатор в файле META-INF/context.xml вашего приложения.
Далее вам потребуется реализовать два метода на AuthenticatorBase
:
boolean doAuthenticate(Request request, HttpServletResponse response)
String getAuthMethod()
Второе легко: верни все, что хочешь. Возможно, вы захотите, чтобы это имело какой-то смысл, например "IBMSAM"
,
Первый, конечно, где лежит мясо аутентификатора.
Если вы можете получить все необходимое от request
тогда это здорово: оно уже есть, так что вы можете получить то, что вам нужно. Ваш метод должен сделать две вещи:
- Установить
principal
запроса на соответствующее значение (например,request.setUserPrincipal(new GenericPrincipal(username, null, roles));
- Вернуть
true
Я думаю, как только вы добьетесь того, чтобы это работало в простой ситуации, вы сможете поиграть с крайними случаями оттуда.