При регистрации сервлета через службу OSGI HTTP он предоставляет вам возможность предоставить реализацию HTTPContext.
1
|
httpService.registerServlet(alias, new MyServlet(), initParams, null ); |
Когда мы реализуем интерфейс HTTPContext, мы можем реализовать три метода. Из этих трех (3) дескриптор handleSecurity будет вызван перед отправкой запроса ermmm… проверить безопасность.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
public class BasicAuthSecuredContext implements HttpContext{ @Override public boolean handleSecurity(HttpServletRequest request, HttpServletResponse response) throws IOException { return false ; } @Override public URL getResource(String s) { return null ; } @Override public String getMimeType(String s) { return null ; } } |
Поэтому при реализации этого я заимствую много контента из документации OSGI HTTPContext и спецификации HTTP-аутентификации . Они должны быть прочитаны, если вы хотите много узнать, углубиться в детали и т. Д., Или вы можете просто прочитать оставшуюся часть этого поста.
Во-первых, не нужно делать базовую аутентификацию, если не используется https. Если его там нет, мы сообщаем пользователю, что это запрещенная территория. Давайте продолжим и сделаем это.
1
2
3
4
|
if (!request.getScheme().equals( "https" )) { response.sendError(HttpServletResponse.SC_FORBIDDEN); return false ; } |
Далее, давайте проверим заголовок авторизации. Если этого нет, мы даем им знать, что им нужно это дерьмо, чтобы быть там. Или мы просто говорим, что они не авторизованы. Давайте сделаем это сейчас.
1
2
3
4
|
if (request.getHeader( "Authorization" ) == null ) { response.sendError(HttpServletResponse.SC_UNAUTHORIZED); return false ; } |
Хорошо, два теста пройдены. Теперь мы делаем настоящую работу. Давайте извлечем заголовок, расшифруем его и сделаем «не очень правильную» аутентификацию.
01
02
03
04
05
06
07
08
09
10
11
|
protected boolean authenticated(HttpServletRequest request) { 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 ); // Now, do the authentication against in the way you want, ex: ldap, db stored uname/pw // Here I will do lame hard coded credential check. HIGHLY NOT RECOMMENDED! return ((username.equals( "username" ) && password.equals( "password" )); } |
Давайте интегрируем этот метод в метод handleSecurity
. Обратите внимание, как значимое сообщение об ошибке устанавливается в ответ (строка 14) при сбое защиты. Это мешает пользователям угадать, и они знают, что именно пошло не так. По крайней мере, если они знают коды ошибок HTTP, они точно знают, что пошло не так.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
@Override public boolean handleSecurity(HttpServletRequest request, HttpServletResponse response) throws IOException { if (!request.getScheme().equals( "https" )) { response.sendError(HttpServletResponse.SC_FORBIDDEN); return false ; } if (request.getHeader( "Authorization" ) == null ) { response.sendError(HttpServletResponse.SC_UNAUTHORIZED); return false ; } if (authenticated(request)) { return true ; } else { response.sendError(HttpServletResponse.SC_UNAUTHORIZED); return false ; } } |
Вот и все. Теперь передайте этот объект при регистрации сервлета,
1
|
httpService.registerServlet(alias, new MyServlet(), initParams, new BasicAuthSecuredContext()); |
… И вот сила базового аутентификации в сервлетах OSGI!
Ссылка: Реализация Basic Auth для сервлета в среде OSGI от нашего партнера по JCG Макки Мэтью из блога dev_religion .