2011-05-11 48 views
8

Me gustaría personalizar Spring security 3.0.5 y cambiar la URL de inicio de sesión para ser/iniciar sesión en lugar de/j_spring_security_check.Spring Security filtro personalizado

Lo que tengo que hacer es permitir el inicio de sesión en el directorio "/" y asegurar la página "/admin/report.html".

En primer lugar me crear mi propio filtro usando tutorial y la primavera de Seguridad código fuente:

public class MyFilter extends AbstractAuthenticationProcessingFilter { 
    private static final String DEFAULT_FILTER_PROCESSES_URL = "/login"; 
    private static final String POST = "POST"; 
    public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username"; 
    public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password"; 
    public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME"; 

    private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY; 
    private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY; 

    protected MyFilter() { 
     super(DEFAULT_FILTER_PROCESSES_URL); 
    } 

    @Override 
    public Authentication attemptAuthentication(HttpServletRequest request, 
               HttpServletResponse response) 
          throws AuthenticationException, IOException, ServletException { 
     String username = obtainUsername(request); 
     String password = obtainPassword(request); 

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

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

     username = username.trim(); 
     UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); 
     HttpSession session = request.getSession(false); 
     if (session != null || getAllowSessionCreation()) { 
      request.getSession().setAttribute(SPRING_SECURITY_LAST_USERNAME_KEY, TextEscapeUtils.escapeEntities(username)); 
     } 
     setDetails(request, authRequest); 

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

    protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) { 
     authRequest.setDetails(authenticationDetailsSource.buildDetails(request)); 
    } 

    @Override 
    public void doFilter(ServletRequest req, ServletResponse res, 
         FilterChain chain) throws IOException, ServletException { 
     final HttpServletRequest request = (HttpServletRequest) req; 
     final HttpServletResponse response = (HttpServletResponse) res; 
     if (request.getMethod().equals(POST)) { 
      // If the incoming request is a POST, then we send it up 
      // to the AbstractAuthenticationProcessingFilter. 
      super.doFilter(request, response, chain); 
     } else { 
      // If it's a GET, we ignore this request and send it 
      // to the next filter in the chain. In this case, that 
      // pretty much means the request will hit the /login 
      // controller which will process the request to show the 
      // login page. 
      chain.doFilter(request, response); 
     } 
    } 

    protected String obtainUsername(HttpServletRequest request) { 
     return request.getParameter(usernameParameter); 
    } 

    protected String obtainPassword(HttpServletRequest request) { 
     return request.getParameter(passwordParameter); 
    } 
} 

después de que yo estoy haciendo los siguientes cambios en XML

<security:http auto-config="true"> 
     <!--<session-management session-fixation-protection="none"/>--> 
     <security:custom-filter ref="myFilter" before="FORM_LOGIN_FILTER"/> 
     <security:intercept-url pattern="/admin/login.jsp*" filters="none"/> 
     <security:intercept-url pattern="/admin/report.html" access="ROLE_ADMIN"/> 
     <security:form-login login-page="/admin/login.jsp" login-processing-url="/login" always-use-default-target="true"/> 
     <security:logout logout-url="/logout" logout-success-url="/login.jsp" invalidate-session="true"/> 
    </security:http> 
<security:authentication-manager alias="authenticationManager"> 
    <security:authentication-provider> 
    <security:password-encoder hash="md5" /> 
    <security:user-service> 
    <!-- peter/opal --> 
     <security:user name="peter" password="22b5c9accc6e1ba628cedc63a72d57f8" authorities="ROLE_ADMIN" /> 
    </security:user-service> 
    </security:authentication-provider> 
</security:authentication-manager> 
<bean id="myFilter" class="com.vanilla.springMVC.controllers.MyFilter"> 
<property name="authenticationManager" ref="authenticationManager"/> 
</bean> 

y luego tengo JSP con mi código

<form action="../login" method="post"> 
    <label for="j_username">Username</label> 
    <input type="text" name="j_username" id="j_username" /> 
    <br/> 
    <label for="j_password">Password</label> 
    <input type="password" name="j_password" id="j_password"/> 
    <br/> 
    <input type='checkbox' name='_spring_security_remember_me'/> Remember me on this computer. 
    <br/> 
    <input type="submit" value="Login"/> 
</form> 

cuando se trata de navegar a /admin/report.html estoy redirigido a la página de acceso. pero después de enviar las credenciales que estoy recibiendo:

HTTP Status 404 - /SpringMVC/login/ 

type Status report 

message /SpringMVC/login/ 

description The requested resource (/SpringMVC/login/) is not available. 

Parece que tengo un problema en la configuración, pero no puedo averiguarlo lo que causa esto. ¿Puedes ayudar?

+0

** 'action =" ../ login "' **? – lschin

+0

es correcto, ../login porque de lo contrario obtendré/admin/login y necesito la carpeta principal. –

+0

La raíz de su aplicación es '/ SpringMVC'? '/ SpringMVC/login /' es correcto/debería estar disponible? – lschin

Respuesta

0

Creo que @Ischin tiene razón al preguntarse acerca de la url de acción de formulario. Trata de poner en el camino completo y ve si eso funciona. Si lo hace, puedes trabajar desde allí para descubrir lo que no coincide.

La otra cosa en la que puedo pensar es en el mapeo de filtros en su web.xml. Como está accediendo a la página de inicio de sesión, tiene esta configuración, pero yo verificaría que no solo esté interceptando URL con extensiones específicas, etc.

También, como un fyi, si desea la solicitud (una vez el formulario de inicio de sesión autentica al usuario) para ir al recurso protegido (/admin/report.html en este caso), entonces debe eliminar el formulario: login always-use-default-target = "true". Si configura este indicador como verdadero, la solicitud siempre irá a la URL de destino predeterminada, que generalmente no es la que desea. De los spring security docs:

Mapas a la propiedad defaultTargetUrl de UsernamePasswordAuthenticationFilter. Si no se establece, el valor predeterminado es "/" (la raíz de la aplicación). Un usuario será llevado a esta URL después de iniciar sesión, , siempre que no se le solicite que inicie sesión en al intentar acceder a un recurso seguro , cuando se llevarán a la URL solicitada originalmente.

+0

Consulte la respuesta a continuación para obtener más información sobre el voto a favor –

10

Tengo alrededor de 12 meses de retraso en esto, pero para personalizar la URL de inicio de sesión del formulario de Spring Security no es necesario que cree su propio filtro. Uno de los atributos de la etiqueta form-login le permite establecer una URL personalizada. De hecho, también puede cambiar los nombres de campo j_username y j_password predeterminados mediante los atributos de la etiqueta form-login. Aquí hay un ejemplo:

<form-login login-page="/login" login-processing-url="/login.do" default-target-url="/" always-use-default-target="true" authentication-failure-url="/login?error=1" username-parameter="username" password-parameter="password"/> 
Cuestiones relacionadas