Подтвердить что ты не робот

Как передать дополнительный параметр с помощью spring страницы входа в систему безопасности

Я пытаюсь установить имя базы данных в качестве параметра ввода запроса на странице входа в систему безопасности spring. В настоящее время я получаю только имя пользователя, которое было получено с помощью spring security SecurityContextHolder.getContext().getAuthentication().

Как получить доступ к дополнительному полю, которое было установлено на странице входа?

4b9b3361

Ответ 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")