У меня есть веб-приложение, в котором мне нужно войти в систему, используя три поля: пользователь, пароль и отдел.

Когда я пытаюсь запустить это, логин работает, но настраиваемый фильтр не вызывается и, следовательно, нет отдела.

Я пытался добавить настраиваемый фильтр имени пользователя и пароля, передавая строку, которую я смогу проанализировать позже. У меня не было никакого успеха, и это сводит меня с ума.

SecurityConfig расширяет WebSecurityConfigurerAdapter

@Override
protected void configure(HttpSecurity http) throws Exception {

    http
        .addFilterBefore(authenticationFilter(), 
                UsernamePasswordAuthenticationFilter.class);

    // Authentication control
    http
        .authorizeRequests()
        .antMatchers("/login.xhtml").permitAll() // All everyone to see login page
        .antMatchers("/javax.faces.resource/**").permitAll() // All everyone to see resources
        .antMatchers("/resources/**").permitAll() // All everyone to see resources
        .anyRequest().authenticated(); // Ensure any request to application is authenticated

    // Login control
    http
        .formLogin()
            .loginPage("/login.xhtml")
            .usernameParameter("userInput")
            .passwordParameter("passwordInput")
            .defaultSuccessUrl("/home.xhtml", true)
            .failureUrl("/login.xhtml?error=true");

    // logout
    http
        .logout()
            .logoutUrl("/logout")
            .invalidateHttpSession(true)
            .logoutSuccessUrl("/login.xhtml");

    // not needed as JSF 2.2 is implicitly protected against CSRF
    http
        .csrf().disable();
} 

public CustomAuthenticationFilter authenticationFilter() throws Exception {
    CustomAuthenticationFilter filter = new CustomAuthenticationFilter();
    filter.setAuthenticationManager(authenticationManagerBean());
    filter.setAuthenticationFailureHandler(failureHandler());
    return filter;
}

public SimpleUrlAuthenticationFailureHandler failureHandler() {
    return new SimpleUrlAuthenticationFailureHandler("/login?error=true");
}

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(authProvider());
}   

@Bean
public DaoAuthenticationProvider authProvider() {
    DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
    authProvider.setUserDetailsService(userDetailsService);
    authProvider.setPasswordEncoder(new EncryptionConfig());
    return authProvider;
}

}

Просмотр входа

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:p="http://primefaces.org/ui"
    xmlns:ui="http://java.sun.com/jsf/facelets">

    <h:head>
        <f:facet name="first">
            <meta http-equiv="X-UA-Compatible" content="IE=edge" />
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
            <meta name="apple-mobile-web-app-capable" content="yes" />
        </f:facet>

        <title>Login</title>

        <h:outputScript name="js/ripple.js" library="ultima-layout" />
        <h:outputScript name="js/layout.js" library="ultima-layout" />
    </h:head>

    <h:body styleClass="login-body">
        <h:form prependId="false" >
            <div class="card login-panel ui-fluid">
                <div class="ui-g">
                    <div class="ui-g-12">
                        <p:graphicImage name="images/logo.png" />
                    </div>
                    <div class="ui-g-12">
                        <h:panelGroup styleClass="md-inputfield">
                            <p:inputText id="userInput" />
                            <label>Username</label>
                        </h:panelGroup>
                    </div>
                    <div class="ui-g-12">
                        <h:panelGroup styleClass="md-inputfield">
                            <p:password id="passwordInput" />
                            <label>Password</label>
                        </h:panelGroup>
                    </div>
                    <div class="ui-g-12">
                        <h:panelGroup styleClass="md-inputfield">
                            <p:selectOneMenu id="departmentInput" value="#{loginController.selectedDepartmentId}">
                                <f:selectItem itemLabel="---" itemValue="" />
                                <f:selectItems 
                                    value="#{loginController.allDepartments}" 
                                    var="dept"
                                    itemLabel="#{dept.departmentName}"
                                    itemValue="#{dept.departmentId}" />
                            </p:selectOneMenu>
                        </h:panelGroup>
                    </div>
                    <div class="ui-g-12">
                        <p:commandButton value="Sign In" icon="ui-icon-person" ajax="false" />
                    </div>
                </div>
            </div>

            <div class="login-footer"></div>
        </h:form>

        <h:outputStylesheet name="css/ripple.css" library="ultima-layout" />
        <h:outputStylesheet name="css/layout-blue-grey.css" library="ultima-layout" />
        <h:outputStylesheet name="css/custom_login.css" />
    </h:body>
</html>

UsernamePasswordAuthenticationFilter

public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    public static final String SPRING_SECURITY_DEPARTMENT_KEY = "department";

  @Override
  public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {

      CustomAuthenticationToken authRequest = getAuthRequest(request);
      setDetails(request, authRequest);

      return this.getAuthenticationManager().authenticate(authRequest);
  }

  private CustomAuthenticationToken getAuthRequest(HttpServletRequest request) {

      String username = obtainUsername(request);
      String password = obtainPassword(request);
      String department = obtainDepartment(request);

      if (username == null) {
          username = "";
      }
      if (password == null) {
          password = "";
      }
      if (department == null) {
          department = "";
      }

      //(username)(separator)(department)
      String usernameDomain = String.format("%s%s%s", 
              username.trim(), 
              String.valueOf(Character.LINE_SEPARATOR), 
              department);

      return new CustomAuthenticationToken(usernameDomain, password, department);
  }

  private String obtainDepartment(HttpServletRequest request) {
      return request.getParameter(SPRING_SECURITY_DEPARTMENT_KEY);
  }
}

Изменить

Первая проблема, которую я выяснил, - действие формы при входе в систему, необходимое для указания на действие / login. Я сделал это и теперь перехожу к фильтру. Тем не менее, имя пользователя равно нулю, а пароль по-прежнему равен нулю.

Изменить 2

Изменен passwordInput на пароль и usernameInput на имя пользователя. Я удалил настройки usernameParameter и passwordParameter в SecurityConfig. Я исправил свой токен и теперь получаю его в пользовательских UserDetails.

Моя безопасность BCrypt проверяется и возвращает "true".

Я все еще получаю следующую трассировку стека:

    11:02:58.626 [http-nio-8080-exec-3] DEBUG com.xfact.config.CustomAuthenticationFilter - 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:174)
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:512)
    at com.xfact.config.CustomAuthenticationFilter.attemptAuthentication(CustomAuthenticationFilter.java:20)
    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:66)
    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.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)
0
StaticMaine 23 Сен 2018 в 16:48

1 ответ

Лучший ответ

Для вашего CustomAuthenticationFilter вы не установили имена параметров формы, которые отличаются от Spring по умолчанию username и password.

1
briarheart 23 Сен 2018 в 14:45