2012-03-24 3 views
4

Мне нужно получить доступ к объекту из моего DaoAuthenticationProvider в режиме Spring.Доступ к HttpServletRequest во время DaoAuthenticationProvider аутентифицирован в Spring Security

Компонент безопасности расширяет DaoAuthenticationProvider, и мы переопределяем метод authenticate для выполнения некоторой пользовательской проверки подлинности/проверки подлинности. Дополнительная проверка необходима для проверки ip-адреса пользователя, который входит в URL-адрес запроса в качестве параметра строки запроса (пример: http://domain.com/context?ip=192.168.0.1).

Текущий подход, который я пытаюсь использовать, - использовать RequestContextHolder thread-local и получить http-запрос в моем обычном DAOAuthenticationProvider.

Некоторые другие решения, которые я читаю здесь и на весенних форумах, как представляется, предлагают ввести AuthenticationDetailsSource, использовать custom-filter и другие шаги, которые я не понимаю из-за того, что я новичок в весенней безопасности.

У нас будут разные веб-приложения, которые используют один и тот же компонент безопасности для выполнения аутентификации.

Может кто-нибудь указать мне в правильном направлении или помочь мне с любыми подходами, реализованными ранее?

+0

Какую версию Spring Security вы используете? – sourcedelica

+0

Spring Security 3.0.4. Если я использую RequestContextHolder во время проверки подлинности, будет ли он иметь тот же HTTP-запрос, который был получен в Spring Security, или может привести к забавным результатам, когда в моем RequestContextHolder есть другой экземпляр HTTP-запроса и тот, который используется в токене аутентификации, отличается? –

ответ

1

Вы можете добавить Весна RequestContextFilter в ваш web.xml. Таким образом, атрибуты будут сохраняться в текущем потоке при каждом запросе. Затем, вы можете получить оригинальный HtttpServletRequest:

ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); 
HttpServletRequest request = attributes.getRequest(); 
+0

Это то, что OP уже делает, нет? –

+0

@ LukeTaylor: Извините, что такое OP? – sinuhepop

+0

[OP] (http://en.wiktionary.org/wiki/OP) == Ankur в этом случае :-) –

3

Вы можете использовать RequestContextHolder и эффективно содержит тот же запрос, но Spring Security обычно завернуть входящий запрос, так что вы можете получить другую ссылку в зависимости от того, вы устанавливаете RequestContextFilter до или после цепи безопасности Spring (обратите внимание, что вы можете легко проверить это самостоятельно, сравнив значение, возвращаемое с RequestContextHolder с запросом в прикладном контроллере).

Это также относительно легко вводить пользовательский AuthenticationDetails как вы упомянули:

package com.mycompany; 

public class MyWebAuthenticationDetailsSource implements AuthenticationDetailsSource { 
    public Object buildDetails(Object context) { 
     return ((HttpServletRequest)context).getParameter("ip"); 
    } 
} 

Затем используйте

<bean id="ads" class="com.mycompany.MyWebAuthenticationDetailsSource /> 

<bean id="formLoginFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> 
    <property name="authenticationDetailsSource" ref="ads" /> 
    <property name="authenticationManager" ref="authenticationmanager" /> 
</bean> 

и добавить в качестве пользовательского фильтра, как описано в справочном руководстве. В 3.1 - пространство имен supports this directly in the form-login element. Authentication.getDetails() затем вернет значение вашего параметра «ip».

Обратите внимание, что вам, вероятно, не следует использовать 3.0.4, так как он обнаружил уязвимости системы безопасности.

Также вы можете объяснить, как устанавливается параметр «ip»?

+0

Спасибо за помощь в этом Luke, прокси-слой перезаписывает входящий URL-адрес, чтобы включить ip-адрес клиента как часть URL-адреса, поэтому мы можем извлечь его из параметров http-запроса. Я постараюсь добиться этого и сообщить о своем прогрессе! –

+1

Я реализовал ваше решение, и оно отлично работает. Я заметил некоторые незначительные икоты при использовании обычной проверки подлинности, фильтр UsernamePasswordAuthentication не вызывается. Вместо этого я использовал BasicAuthenticationFilter. Он позиционируется '_before_' BASIC_AUTH_FILTER. Я просто поражен возможностями Spring Security framework и с нетерпением ожидаю дальнейшего изучения! Спасибо за вашу помощь в этом. –

Смежные вопросы