Отправка формы вызывает запрос на публикацию, который вызывает UsernamePasswordAuthenticationFilter на странице входа - PullRequest
0 голосов
/ 03 мая 2019

Я использую Spring Boot 2.1.4. Выпуск, Primefaces 6.2, Java 8.

Я использую Spring Security для входа через страницу "login.xhtml".Все страницы моего приложения содержат компонент меню (Menu.xhtml).Компонент меню имеет такие функции, как выход из системы, настройки локали и т. Д. Другими словами, локаль страниц задается из Menu.xhtml.

Проблема в том, что настройки локали изменяются на странице входа в систему.выполняется запрос «POST /login.xhtml», который завершается проверкой подлинности UsernamePasswordAuthenticationFilter.Однако я хочу остаться на странице входа в систему после обновления настроек локали.Что мне интересно, так это как избежать этого почтового запроса.

Вот связанные части реализации WebSecurity:



@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final UserDetailServiceImp userDetailsService;

    @Autowired
    public SecurityConfig(UserDetailServiceImp userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // require all requests to be authenticated except for the resources
        http.authorizeRequests()
                .antMatchers("/user/**").hasAuthority(MediaJuryConstants.USER_ROLE)
                .antMatchers("/javax.faces.resource/**").permitAll()
                .antMatchers("/favicon.ico").permitAll()
                .anyRequest().authenticated()
               .and().authorizeRequests().antMatchers("/").anonymous();

        // login
        http.formLogin()
                .loginPage("/login" + MediaJuryConstants.PREFIX)
                .usernameParameter("loginForm:username")
                .passwordParameter("loginForm:password")
                .successHandler(myAuthenticationSuccessHandler())
                .permitAll()
                .failureUrl("/error" + MediaJuryConstants.PREFIX);
        // logout
        http.logout().logoutSuccessUrl("/login" + MediaJuryConstants.PREFIX);
        http.csrf().disable();
    }

...
}

Вот реализация p: selectOneMenu, используемая для выбора локали в Menu.xhtml:


<h:body>

    <h:form id="langForm" styleClass="language-form">
        <p:selectOneMenu value="#{language.localeCode}"  valueChangeListener="#{languageChangeController.valueChanged}"
        onchange="submit()">
            <f:selectItems value="#{language.languageUtils.locales}" var="locale"
                           itemValue="#{locale}" itemLabel="#{msg['layout.'.concat(locale)]}"/>
        </p:selectOneMenu>
    </h:form>
</h:body>

У меня есть собственный layout.xhtml, который устанавливает глобальный компонент для всех страниц.Вот часть, где находится Menu.xhtml:

<h:body>
    <div class="wrap">
        <div class="header">
            <div class="content ui-widget-content">
                <ui:include src="tiles/Menu.xhtml" />
            </div>
        </div>
    </div>
</h:body>

Я не предоставляю login.xhtml или LanguageController, так как не думаю, что это полезно.Но если потребуется, я могу.

Вот мой журнал.В этом случае поля имени пользователя и пароля являются пустыми:

17:49:34.368 [http-nio-8080-exec-10] DEBUG o.s.s.w.FilterChainProxy - /login.xhtml at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
17:49:34.368 [http-nio-8080-exec-10] DEBUG o.s.s.w.FilterChainProxy - /login.xhtml at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
17:49:34.368 [http-nio-8080-exec-10] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - HttpSession returned null object for SPRING_SECURITY_CONTEXT
17:49:34.368 [http-nio-8080-exec-10] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@797fe12e. A new one will be created.
17:49:34.368 [http-nio-8080-exec-10] DEBUG o.s.s.w.FilterChainProxy - /login.xhtml at position 3 of 11 in additional filter chain; firing Filter: 'HeaderWriterFilter'
17:49:34.368 [http-nio-8080-exec-10] DEBUG o.s.s.w.FilterChainProxy - /login.xhtml at position 4 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
17:49:34.368 [http-nio-8080-exec-10] DEBUG o.s.s.w.u.m.OrRequestMatcher - Trying to match using Ant [pattern='/logout', GET]
17:49:34.368 [http-nio-8080-exec-10] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Request 'POST /login.xhtml' doesn't match 'GET /logout'
17:49:34.368 [http-nio-8080-exec-10] DEBUG o.s.s.w.u.m.OrRequestMatcher - Trying to match using Ant [pattern='/logout', POST]
17:49:34.368 [http-nio-8080-exec-10] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/login.xhtml'; against '/logout'
17:49:34.368 [http-nio-8080-exec-10] DEBUG o.s.s.w.u.m.OrRequestMatcher - Trying to match using Ant [pattern='/logout', PUT]
17:49:34.368 [http-nio-8080-exec-10] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Request 'POST /login.xhtml' doesn't match 'PUT /logout'
17:49:34.368 [http-nio-8080-exec-10] DEBUG o.s.s.w.u.m.OrRequestMatcher - Trying to match using Ant [pattern='/logout', DELETE]
17:49:34.368 [http-nio-8080-exec-10] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Request 'POST /login.xhtml' doesn't match 'DELETE /logout'
17:49:34.368 [http-nio-8080-exec-10] DEBUG o.s.s.w.u.m.OrRequestMatcher - No matches found
17:49:34.368 [http-nio-8080-exec-10] DEBUG o.s.s.w.FilterChainProxy - /login.xhtml at position 5 of 11 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
17:49:34.368 [http-nio-8080-exec-10] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/login.xhtml'; against '/login.xhtml'
17:49:34.368 [http-nio-8080-exec-10] DEBUG o.s.s.w.a.UsernamePasswordAuthenticationFilter - Request is to process authentication
17:49:34.368 [http-nio-8080-exec-10] DEBUG o.s.s.a.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
17:49:34.368 [http-nio-8080-exec-10] DEBUG o.s.o.j.JpaTransactionManager - Creating new transaction with name [net.comerge.mediajury.service.UserService.findByEmail]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
17:49:34.369 [http-nio-8080-exec-10] DEBUG o.s.o.j.JpaTransactionManager - Opened new EntityManager [SessionImpl(1298794356<open>)] for JPA transaction
17:49:34.369 [http-nio-8080-exec-10] DEBUG o.h.e.t.i.TransactionImpl - On TransactionImpl creation, JpaCompliance#isJpaTransactionComplianceEnabled == false
17:49:34.369 [http-nio-8080-exec-10] DEBUG o.h.e.t.i.TransactionImpl - begin
17:49:34.369 [http-nio-8080-exec-10] DEBUG o.s.o.j.JpaTransactionManager - Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@773cf27f]
17:49:34.369 [http-nio-8080-exec-10] DEBUG o.h.q.c.i.CriteriaQueryImpl - Rendered criteria query -> select generatedAlias0 from User as generatedAlias0 where generatedAlias0.email=:param0
17:49:34.370 [http-nio-8080-exec-10] DEBUG o.h.SQL - select user0_.id as id1_11_, user0_.email as email2_11_, user0_.locale as locale3_11_, user0_.password as password4_11_, user0_.state as state5_11_, user0_.verification_key as verifica6_11_ from user user0_ where user0_.email=?
17:49:34.371 [http-nio-8080-exec-10] DEBUG o.s.o.j.JpaTransactionManager - Initiating transaction commit
17:49:34.371 [http-nio-8080-exec-10] DEBUG o.s.o.j.JpaTransactionManager - Committing JPA transaction on EntityManager [SessionImpl(1298794356<open>)]
17:49:34.371 [http-nio-8080-exec-10] DEBUG o.h.e.t.i.TransactionImpl - committing
17:49:34.371 [http-nio-8080-exec-10] DEBUG o.s.o.j.JpaTransactionManager - Closing JPA EntityManager [SessionImpl(1298794356<open>)] after transaction
17:49:34.371 [http-nio-8080-exec-10] DEBUG o.s.s.a.d.DaoAuthenticationProvider - User '' not found
17:49:34.371 [http-nio-8080-exec-10] DEBUG o.s.s.w.a.UsernamePasswordAuthenticationFilter - Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
org.springframework.security.authentication.BadCredentialsException: Bad credentials
    at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:151)
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:175)
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:200)
    at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
17:49:34.372 [http-nio-8080-exec-10] DEBUG o.s.s.w.a.UsernamePasswordAuthenticationFilter - Updated SecurityContextHolder to contain null Authentication
17:49:34.372 [http-nio-8080-exec-10] DEBUG o.s.s.w.a.UsernamePasswordAuthenticationFilter - Delegating to authentication failure handler org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler@1599e2f9
17:49:34.372 [http-nio-8080-exec-10] DEBUG o.s.s.w.a.SimpleUrlAuthenticationFailureHandler - Redirecting to /error.xhtml
17:49:34.372 [http-nio-8080-exec-10] DEBUG o.s.s.w.DefaultRedirectStrategy - Redirecting to '/error.xhtml'

Когда язык изменяется с помощью selectOneMenu на странице входа в систему, создается запрос POST /login.xhtml, который перехватывается Spring Security и интерпретируется какпопытка входаЯ хотел спросить, где именно выполняется этот запрос POST и есть ли способ избежать метода POST и сделать метод GET.К вашему сведению, код не вводит valueChangeListener в описанном случае.

Буду очень признателен за совет.Заранее спасибо!

1 Ответ

0 голосов
/ 14 мая 2019

Я не смог найти решение на основе xhtml, но, как Кукельтье предложил пользовательскую реализацию UsernamePasswordAuthenticationFilter, решает проблему.

Компонент формы такой, как задано,

  <h:form method="get" id="langForm" styleClass="language-form">
        <p:selectOneMenu value="#{languageController.localeCode}"  valueChangeListener="#{languageChangeController.valueChanged}"
        onchange="submit()">
            <f:selectItems value="#{languageController.languageUtils.locales}" var="locale"
                           itemValue="#{locale}" itemLabel="#{msg['layout.'.concat(locale)]}"/>
        </p:selectOneMenu>
    </h:form>

Выборэлемент приводит к запросу POST текущей страницы, на которой мы находимся в login.xhtml: POST /login.xhtml.Этот запрос поступает в doFilter файла UsernamePasswordAuthenticationFilter.Метод выполняет проверку подлинности, если метод requiresAuthentication возвращает значение true.Таким образом, достаточно переопределить этот метод.

public class CustomUsernamePasswordFilter extends UsernamePasswordAuthenticationFilter {

    @Override
    protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
        if (request.getParameter("langForm") != null) {
            return false;
        }
        return super.requiresAuthentication(request, response);
    }
}

langForm - это идентификатор формы, введенной в xhtml.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...