Spring - вызов провайдера нестандартной аутентификации с контроллера - PullRequest
6 голосов
/ 01 июля 2010

У меня есть пользовательский поставщик аутентификации, определенный в моей конфигурации Spring Security. Этот класс реализует AuthenticationProvider, и я могу успешно войти в систему, используя форму, определенную на моей странице. Проблема в том, что я хочу назвать этот класс не только на странице входа, но и на странице регистрации.

Страница регистрации использует другой класс команд и собирает больше информации, чем форма входа. Прямо сейчас, когда пользователь регистрируется, я вызываю соответствующий контроллер, добавляю запись в базу данных, и они могут затем войти в систему, но они не входят в систему автоматически. Поскольку они только что дали мне свое имя пользователя / пароль на странице регистрации, могу ли я передать их в пользовательский класс AuthenticationProvider, чтобы они также вошли в систему?

Я попытался создать класс org.springframework.security.Authentication в контроллере регистрации и вызвать метод authenticate в моем классе AuthenticationProvider моего клиента, и это не приводит к ошибке, но пользователь не вошел в систему. Мне нужно вызвать метод выше в цепочке фильтров Spring Security для этого? Должен ли я перенаправить контроллер на URL-адрес j_spring_security_check? Если так, как я передам имя пользователя / пароль?

Ответы [ 2 ]

3 голосов
/ 04 июля 2010

Проблема, с которой вы столкнулись, заключается в том, что, хотя вы успешно аутентифицировали пользователя, вы не сохранили результат этой аутентификации в SecurityContext пользователя. В веб-приложении это ThreadLocal объект , который SecurityContextPersistenceFilter будет использовать для хранения учетных данных пользователя в HTTPSession

Вам также следует избегать аутентификации напрямую с вашим провайдером аутентификации, если вы можете. Ваша конфигурация xml должна содержать AuthenticationManager, к которой подключен ваш пользовательский провайдер аутентификации. Например,

<bean id="customAuthenticationProvider" 
  class="com.foo.CustomAuthenticationProvider">
  <property name="accountService" ref="accountService"/>
</bean>
<security:authentication-manager alias="authenticationManager">
  <security:authentication-provider ref="customAuthenticationProvider"/>
</security:authentication-manager>

Если вы подключите authenticationManager к вашей службе регистрации и авторизуетесь, используя ее дополнительно,

Наша служба регистрации делает это следующим образом

final UsernamePasswordAuthenticationToken authRequest = new 
  UsernamePasswordAuthenticationToken(username, password);

final Authentication authentication = 
  authenticationManager.authenticate(authRequest);
SecurityContextHolder.getContext().setAuthentication(authentication);

Мы также можем при желании сохранить результат аутентификации на этом этапе в cookie-файле запомнить меня , используя onLoginSuccess() метод TokenBasedRememberMeServices.

1 голос
/ 01 июля 2010

Вам нужно поместить результат AuthenticationProvider.authenticate() в SecurityContext (полученный из SecurityContextHolder).

Также следует помнить о AuthenticationSuccessEvent - если ваше приложение полагается на это событие (некоторые функции Spring Security также могут использовать его), вы должны опубликовать его (вы можете получить значение по умолчанию AuthenticationEventPublisher через автоматическое подключение). Может быть полезно обернуть вашего провайдера аутентификации ProviderManager, он автоматически публикует событие с использованием данного издателя.

...