Spring Безопасность - Сохранение параметров URL для перенаправления на логин
ОК.
говорит, что у меня есть защищенный шаблон URL
/secure/link-profile
необязательно, могут быть добавлены параметрические параметры URL.
/secure/link-profile?firstName=Bob&secondName=Smith&membershipNumber=1234
как я могу сделать так, чтобы эти параметры URL были перенесены на страницу входа?
/login?firstName=Bob&secondName=Smith&membershipNumber=1234
Основная предпосылка заключается в том, что мы предлагаем интеграцию вознаграждений с третьей стороной, которая отправит своих пользователей к нам. Они будут отправлены на страницу, чтобы связать свою стороннюю учетную запись/профиль с их/нашим пользователем веб-сайта. Если, однако, у них нет существующей учетной записи у нас, а затем на странице входа в систему они перейдут на страницу регистрации, и тогда мы хотели бы предварительно разобраться с некоторыми из своих деталей, которые третья сторона передала нам.
заблаговременно
spring безопасность 2.0.7.RELEASE
spring framework 3.1.1.RELEASE
Ответы
Ответ 1
См. метод buildRedirectUrlToLoginPage(HttpServletRequest request, ...)
в LoginUrlAuthenticationEntryPoint
.
Если я правильно понял, чего вы хотите достичь, я думаю, этого должно быть достаточно, чтобы переопределить этот метод в sublclass, скопировать исходный метод, но дополнительно вызвать
urlBuilder.setQuery(request.getQueryString())
при создании URL-адреса.
Затем вам нужно только настроить ExceptionTranslationFilter
с помощью этой настраиваемой точки входа.
Ответ 2
в соответствии с ответом @zagyi Я просто переопределил метод в моем существующем расширении AuthenticationProcessingFilterEntryPoint
метод переопределения - это protected String determineUrlToUseForThisRequest(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception)
, который вызывается buildRedirectUrlToLoginPage(..
@Override
protected String determineUrlToUseForThisRequest(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) {
String url = super.determineUrlToUseForThisRequest(request, response, exception);
return url + "?" + request.getQueryString();
}
очевидно, что можно было бы улучшить, чтобы также использовать построитель сортов, поддерживая существующую строку запроса на URL-адресе, но в настоящее время я знаю, что мой URL-адрес для входа всегда /login/
, поэтому это хорошо для моих целей
Ответ 3
В другой статье объясняется, как переопределение не работает. Мне нужно было переопределить commence. Возможно, это может быть новая вещь, которая была введена в более поздних версиях безопасности spring.
public class SecurityConfig extends WebSecurityConfigurerAdapter {
protected void configure(final HttpSecurity httpSecurity) throws Exception {
httpSecurity.
formLogin().loginPage("/signIn").permitAll().
and().
authorizeRequests().
antMatchers(managementContextPath + "/**").permitAll().
anyRequest().authenticated().withObjectPostProcessor(objectPostProcessor).
and().
csrf().disable().
contentTypeOptions().
xssProtection().
cacheControl().
httpStrictTransportSecurity().
and().
requestCache().requestCache(new RedisRequestCache(savedRequestRedisTemplate())).
and().
sessionManagement().sessionAuthenticationStrategy(sessionAuthenticationStrategy).
and().
exceptionHandling().authenticationEntryPoint(new AuthenticationProcessingFilterEntryPoint("/signIn"));
}
}
public class AuthenticationProcessingFilterEntryPoint extends LoginUrlAuthenticationEntryPoint {
public AuthenticationProcessingFilterEntryPoint(String loginFormUrl) {
super(loginFormUrl);
}
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
redirectStrategy.sendRedirect(request, response, getLoginFormUrl() + "?" + request.getQueryString());
}
}
Rizier123, еще раз спасибо за ваши указатели.
Ответ 4
Привет kabal -
У меня очень схожие требования, и я следил за вашими и zagyi и лев, но Я по-прежнему теряю исходный параметр запроса на странице /login.
Вот что у меня есть:
public class AuthenticationProcessingFilterEntryPoint extends LoginUrlAuthenticationEntryPoint {
@Override
protected String determineUrlToUseForThisRequest(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) {
String url = super.determineUrlToUseForThisRequest(request, response, exception);
return url + "?" + request.getQueryString();
}
}
protected void configure(final HttpSecurity httpSecurity) throws Exception {
httpSecurity.
formLogin().loginPage("/signIn").permitAll().
and().
authorizeRequests().
antMatchers(managementContextPath + "/**").permitAll().
anyRequest().authenticated().withObjectPostProcessor(objectPostProcessor).
and().
csrf().disable().
contentTypeOptions().
xssProtection().
cacheControl().
httpStrictTransportSecurity().
and().
requestCache().requestCache(new RedisRequestCache(savedRequestRedisTemplate())).
and().
sessionManagement().sessionAuthenticationStrategy(sessionAuthenticationStrategy).
and().
addFilter(new ExceptionTranslationFilter(new AuthenticationProcessingFilterEntryPoint()));
}
Я вижу, что AuthenticationProcessingFilterEntryPoint развернут, но он не попадает в точку останова.
Основываясь на документации, похоже, что это произойдет только тогда, когда есть AuthenticationException или AccessDeniedException. В приведенной выше конфигурации я не уверен, что spring внутренне выбрасывает такое исключение, когда это происходит.
Кроме того, я хотел бы сохранить параметр запроса на целевой странице, независимо от того, прошла ли проверка подлинности или нет.
Я добавил успешный и отказоустойчивый обработчик, но никто не ввел бы в действие.
protected void configure(final HttpSecurity httpSecurity) throws Exception {
httpSecurity.
formLogin().
successHandler(new PropogateQueryStringAuthenticationSuccessHandlerImpl()).
failureHandler(new SimpleUrlAuthenticationFailureHandlerImpl(new QueryStringPropagateRedirectStrategy())).
and().
authorizeRequests().
antMatchers(managementContextPath + "/**").permitAll().
anyRequest().authenticated().withObjectPostProcessor(objectPostProcessor).
and().
csrf().disable().
contentTypeOptions().
xssProtection().
cacheControl().
httpStrictTransportSecurity().
and().
requestCache().requestCache(new RedisRequestCache(savedRequestRedisTemplate())).
and().
sessionManagement().sessionAuthenticationStrategy(sessionAuthenticationStrategy);
}
Я использую spring -security 3.2.4.RELEASE на spring boot 1.1.6.RELEASE(который, в свою очередь, использует spring framework 4.0.7.RELEASE)
Спасибо,
Сан -