2015-04-16 5 views
1

pals. Я использую Spring-web, -mvc и т. Д. Версии 4.1.x и Spring-secure версии 4.0.0, и у меня странная проблема.Spring-security/login redirecting

У меня есть LoginController.java с @RequestMapping ("/ login"), возвращающий «login», сопоставление с login.jsp. Также у меня есть безопасность config.xml файл со следующими параметрами

<security:authentication-manager> 
    <security:authentication-provider> 
     <security:user-service> 
      <security:user name="John" authorities="admin" 
          password="letmein" /> 
      <security:user name="Zog" authorities="admin" 
          password="iamzog" /> 
     </security:user-service> 
    </security:authentication-provider> 
</security:authentication-manager> 

<security:http use-expressions="true"> 
    <security:csrf disabled="true"></security:csrf> 
    <security:intercept-url pattern="/createoffer" access="isAuthenticated()" /> 
    <security:intercept-url pattern="/docreate" access="isAuthenticated()" /> 
    <security:intercept-url pattern="/offercreated" access="isAuthenticated()" /> 
    <security:intercept-url pattern="/" access="permitAll" /> 
    <security:intercept-url pattern="/login" access="permitAll" /> 
    <security:intercept-url pattern="/static/**" access="permitAll" /> 
    <security:intercept-url pattern="/offers" access="permitAll" /> 
    <security:intercept-url pattern="/**" access="denyAll" /> 

    <security:form-login login-page="/login" 
         login-processing-url="/login" 
         username-parameter="username" 
         password-parameter="password" 
         default-target-url="/" 
         authentication-failure-url="/login?error=true"/> 
</security:http> 

Когда я пытаюсь открыть/вход весной показывает форму входа по умолчанию и метод моего LoginController является не выполнить. Но когда я вводил неверные данные в эту форму для входа, весна перенаправляет меня на/login? Error = true, а LoginController ловит это и перенаправляет на мой login.jsp. Итак, весна ловит/регистрируется перед моим контроллером, но pass/login? Error = true для контроллера, и моя пользовательская форма входа работает неправильно.

Мой файл web.xml выглядит следующим образом

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns="http://java.sun.com/xml/ns/javaee" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
      version="3.0"> 

    <description>MySQL Test App</description> 

    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value> 
      classpath:spring-security-config.xml 
      classpath:dao-context.xml 
      classpath:service-context.xml 
     </param-value> 
    </context-param> 

    <listener> 
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 




    <filter> 
     <filter-name>springSecurityFilterChain</filter-name> 
     <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
    </filter> 

    <filter-mapping> 
     <filter-name>springSecurityFilterChain</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 

    <servlet> 
     <servlet-name>offers</servlet-name> 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 
    <servlet-mapping> 
     <servlet-name>offers</servlet-name> 
     <url-pattern>/</url-pattern> 
    </servlet-mapping> 


    <resource-ref> 
     <description>DB Connection</description> 
     <res-ref-name>jdbc/spring</res-ref-name> 
     <res-type>javax.sql.DataSource</res-type> 
     <res-auth>Container</res-auth> 
    </resource-ref> 

</web-app> 

Люди с сайта с пружинным конечно спрашивает тот же вопрос, но единственный ответ был «использование 3.x.x весна-безопасности». Я не хочу использовать 3-кратную безопасность, но хочу понять, где магия пружины сломана. Заранее благодарю.

ответ

1

Это ошибка в Spring Security 4 и зарегистрирована как SEC-2919. Он будет исправлен в Spring Security 4.0.1, который должен выйти на следующей неделе.

Обходные

Ниже несколько обходных путей. Вы можете удалить обходной путь после выпуска версии 4.0.1 (ожидается примерно через неделю).

Используйте разные URL

Самый простой обходной путь заключается в использовании URL, кроме "/ вход". Например, вы можете использовать «/ authenticate».

<http ...> 
    <form-login login-page="/authenticate" ... /> 
</http> 

Используйте BeanPostProcessor

В качестве альтернативы, следующий BeanDefinitionRegistryPostProcessor будет решить проблему путем удаления DefaultLoginPageGeneratingFilter. Чтобы использовать его, просто убедитесь, что зарегистрировали BeanDefinitionRegistryPostProcessor в качестве компонента.

Например создать класс, который выглядит следующим образом:

package sample; 

import java.util.Iterator; 
import java.util.List; 

import org.springframework.beans.BeansException; 
import org.springframework.beans.factory.config.BeanDefinition; 
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; 
import org.springframework.beans.factory.support.BeanDefinitionRegistry; 
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; 
import org.springframework.security.web.DefaultSecurityFilterChain; 
import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter; 

public class Sec2919PostProcessor implements BeanDefinitionRegistryPostProcessor { 
    @Override 
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) 
      throws BeansException { 
     String[] beanDefinitionNames = registry.getBeanDefinitionNames(); 
     for(String name : beanDefinitionNames) { 
      BeanDefinition beanDefinition = registry.getBeanDefinition(name); 
      if(beanDefinition.getBeanClassName().equals(DefaultSecurityFilterChain.class.getName())) { 
       List<Object> filters = (List<Object>) beanDefinition.getConstructorArgumentValues().getArgumentValue(1, List.class).getValue(); 
       Iterator<Object> iFilters = filters.iterator(); 
       while(iFilters.hasNext()) { 
        Object f = iFilters.next(); 
        if(f instanceof BeanDefinition) { 
         BeanDefinition bean = (BeanDefinition) f; 
         if(bean.getBeanClassName().equals(DefaultLoginPageGeneratingFilter.class.getName())) { 
          iFilters.remove(); 
         } 
        } 
       } 
      } 
     } 
    } 

    @Override 
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) 
      throws BeansException { 
    } 
} 

Затем добавьте определение бина:

<bean class="sample.Sec2919PostProcessor"/> 
+0

Использование другой URL действительно помогает, спасибо! Я просто переименовываю все ссылки на/auth (и/auth? Error = true, конечно) и переименует файл login.js в auth.js, и теперь он работает. В любом случае, надеюсь, что весна 4.0.1 тоже будет в порядке – finnetrolle