Как передать дополнительный параметр с помощью spring страницы входа в систему безопасности
Я пытаюсь установить имя базы данных в качестве параметра ввода запроса на странице входа в систему безопасности spring. В настоящее время я получаю только имя пользователя, которое было получено с помощью spring security SecurityContextHolder.getContext().getAuthentication()
.
Как получить доступ к дополнительному полю, которое было установлено на странице входа?
Ответы
Ответ 1
Разработка комментария @Vacuum
Вот простой способ (непроверенный, но я считаю, что это сработает)
1) Создайте новый класс ExUsernamePasswordAuthenticationFilter, который расширит фильтр по умолчанию и захватит дополнительный параметр и сохранит его в сеансе. Он будет выглядеть примерно так:
public class ExUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
final String dbValue = request.getParameter("dbParam");
request.getSession().setAttribute("dbValue", dbValue);
return super.attemptAuthentication(request, response);
}
}
2) В вашей реализации UserDetailsService измените свою реализацию:
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException;
чтобы захватить переменную сеанса, выбранную фильтром с шага 1).
3) в настройке безопасности <http />
, переопределите фильтр по умолчанию с помощью своего настраиваемого
<custom-filter ref="beanForYourCustomFilterFromStep1" position="FORM_LOGIN_FILTER"/>
Подробнее об пользовательских фильтрах читайте в этой части документации: http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#ns-custom-filters
Ответ 2
Существует несколько способов сделать это, но официальный способ сделать это - использовать пользовательские AuthenticationDetails
и AuthenticationDetailsSource
, подклассы Spring WebAuthenticationDetails
и WebAuthenticationDetailsSource
соответственно. Добавьте дополнительное поле в пользовательский WebAuthenticationDetails
и пользовательский WebAuthenticationDetailsSource
получит данные из запроса для заполнения поля.
В Spring Security 3.1 его легко настроить с помощью атрибута authentication-details-source-ref
элемента <form-login>
.
В 3.0 вы должны использовать BeanPostProcessor
. Пример в Spring FAQ по безопасности на с помощью BeanPostProcessor для настройки настраиваемого источника WebAuthenticationDetailsSource.
Как только это будет сделано, вы можете вызвать SecurityContextHolder.getContext(). getAuthentication(). getDetails(), чтобы получить доступ к вашему дополнительному полю.
Ответ 3
sourcedelica упоминается с помощью AuthenticationDetailsSource
и пользовательского AuthenticationDetails
.
Вот пример.
Добавьте атрибут authentication-details-source-ref
с bean id customWebAuthenticationDetailsSource
в form-login
:
<security:http>
<security:intercept-url pattern="/**" access="..." />
<security:form-login authentication-details-source-ref="customWebAuthenticationDetailsSource" login-page="..." />
<security:logout logout-success-url="..." />
</security:http>
Создайте новый класс customWebAuthenticationDetailsSource
:
package security;
import org.springframework.security.authentication.AuthenticationDetailsSource;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import javax.servlet.http.HttpServletRequest;
public class CustomWebAuthenticationDetailsSource implements AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> {
@Override
public WebAuthenticationDetails buildDetails(HttpServletRequest context) {
return new CustomWebAuthenticationDetails(context);
}
}
и связанный CustomWebAuthenticationDetails
:
package security;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import javax.servlet.http.HttpServletRequest;
public class CustomWebAuthenticationDetails extends WebAuthenticationDetails {
private final String yourParameter;
public CustomWebAuthenticationDetails(HttpServletRequest request) {
super(request);
yourParameter = request.getParameter("yourParameter");
}
public String getyourParameter() {
return yourParameter;
}
//TODO override hashCode, equals and toString to include yourParameter
@Override
public int hashCode() { /* collapsed */ }
@Override
public boolean equals(Object obj) { /* collapsed */ }
@Override
public String toString() { /* collapsed */ }
}
Ответ 4
@user1322340 не обеспечивает детализацию реализации для получения сеанса Атрибуты в функции loadUserByUsername:
Шаг 1: Следуйте всем шагам, предоставленным @user1322340
Шаг 2:
вам нужно добавить одну конфигурацию в web.xml следующим образом:
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
Шаг 3:
Используйте этот код для получения атрибутов:
RequestContextHolder.getRequestAttributes().getAttribute("yourAttributeName", RequestAttributes.SCOPE_SESSION);
Шаг 4: Зарегистрируйте свой фильтр в конфигурации безопасности spring.
Если вы получили сообщение об ошибке ", должен быть указан authenticationManager". после регистрации вашего фильтра в config. Вам необходимо установить authenticationManagerBean для расширенного фильтра и настроить его таким образом:
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public ExUsernamePasswordAuthenticationFilter exUsernamePasswordAuthenticationFilter()
throws Exception {
ExUsernamePasswordAuthenticationFilter exUsernamePasswordAuthenticationFilter = new ExUsernamePasswordAuthenticationFilter();
exUsernamePasswordAuthenticationFilter
.setAuthenticationManager(authenticationManagerBean());
return exUsernamePasswordAuthenticationFilter;
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
RequestMatcher requestMatcher = new RequestMatcher() {
@Override
public boolean matches(HttpServletRequest httpServletRequest) {
if (httpServletRequest.getRequestURI().indexOf("/api", 0) >= 0) {
return true;
}
return false;
}
};
http
.addFilterBefore(exUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
...
}
}
Ответ 5
Для spring безопасности 3.0 или выше, которая использует java-конфигурацию, следующие простые шаги работают хорошо.
-
Добавьте свой фильтр до
UserNameandPasswordAuthenticationFilter в объекте HttpSecurity в configure.
http.addFilterBefore(new YourFilter(), UsernamePasswordAuthenticationFilter.class);
-
Пусть фильтр имеет такую строку, чтобы получить необходимые поля в вашем
запрос на сеанс.
if(requestPath != null &&requestPath.equals("/login") ) {
session.setAttribute("yourParam",req.getParameter("yourParam"));
}
-
Позже вы можете получить значение параметра из сеанса в любом классе как:
String yourParam =(String)request.getSession().getAttribute("yourParam");
Ответ 6
Существует более простой способ, если вы используете пользовательский AuthenticationProvider
. Вы можете просто ввести HttpServletRequest
и получить дополнительный параметр:
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired(required = false)
private HttpServletRequest request;
@Autowired
private MyAccountService myAccountService;
@Override
public Authentication authenticate(Authentication authentication) {
System.out.println("request testing= " + request.getParameter("testing"));
.....
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
Ответ 7
Простой способ:
1) register RequestContextListener
@Bean
public RequestContextListener requestContextListener(){
return new RequestContextListener();
}
2) И к основному классу:
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.
currentRequestAttributes()).
getRequest();
3) После этого мы можем принимать параметры в пользовательских заголовках:
request.getHeader("OrganizationId")