5

当我尝试在 Spring Security 中使用自定义登录表单时,无论我是否输入了正确的凭据,它都会不断将我返回到 /admin/login 页面。当我使用空<form-login />时,安全检查工作正常。但是,一旦我添加了一个自定义,<form-login login-page="/admin/login" />我就会一直返回到同一页面。我尝试添加一个default-target-url="admin/forSale" />,但我仍然返回到登录页面。在提供正确的凭据并返回登录页面后,我尝试访问受保护的 url,然后再次返回登录页面,因此我 99% 确定根本没有执行安全检查。

action="<c:url value='j_spring_security_check' />"我的 jsp 中创建了一个指向http://localhost:8080/sharleepark/admin/j_spring_security_check. 我认为过滤器仍然应该选择它并相应地处理安全性?

我确信我的控制器或 JSP 中存在一个我没有发现的简单错误。我也在使用 Tiles2 模板,这可能是问题的一部分吗?我在这上面花了几天时间,并尝试了所有我能找到的春季安全教程,但都无济于事,非常感谢您的帮助。

spring-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd  
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd ">

    <!-- Scans packages to auto declare the beans we require -->
    <context:component-scan base-package="au.com.sharleepark.controller" />
    <context:component-scan base-package="au.com.sharleepark.service" />
    <context:component-scan base-package="au.com.sharleepark.hibernate" />
    <context:component-scan base-package="au.com.sharleepark.helper" />

    <mvc:annotation-driven /> 
    <tx:annotation-driven />

    <!-- Map our static resources to a friendly URL -->
    <mvc:resources location="/static/" mapping="/static/**" />

    <!-- Specify the view resolver that we wish to use -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView" />
    </bean>

    <!-- Tell the tiles configurator where our tiles configuration files are located -->
    <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
        <property name="definitions">
            <list>
                    <value>/WEB-INF/tiles.xml</value>
            </list>
        </property>
    </bean>

    <!-- Our datasource -->
    <!-- Defines our connection to the database -->
    <bean id="dataSource"
    class="org.springframework.jdbc.datasource.SingleConnectionDataSource"
    destroy-method="destroy">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://blah blah" />
        <property name="username" value="" />
        <property name="password" value="" />
        <property name="suppressClose" value="true" />
        <property name="autoCommit" value="true" />
    </bean>

    <!-- Session Factory -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="au.com.sharleepark.domain" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.hbm2ddl.auto">validate</prop>
                <prop key="show_sql">true</prop>
            </props>
        </property>
    </bean>

    <!-- Data Access Objects -->
    <!-- <bean id="hibernateDAO" class="au.com.sharleepark.hibernate.HibernateDaoImpl">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean> -->

    <!-- Transaction management -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <!-- Spring exception translation post processor for the DAO layer -->
    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

</beans>

弹簧安全.xml

<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
                http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                http://www.springframework.org/schema/security 
                http://www.springframework.org/schema/security/spring-security-3.1.xsd">

    <http pattern="/static/**" security="none" />

    <http use-expressions="true">
        <intercept-url pattern="/admin/login" access="permitAll" />
        <intercept-url pattern="/admin/**" access="isAuthenticated()" />
        <intercept-url pattern="/**" access="permitAll" />
        <form-login login-page="/admin/login" />
        <logout /> <!-- Not there is currently a logout link anyway -->
    </http>

    <authentication-manager>
        <authentication-provider>
            <user-service>
                <user name="rod" password="koala" authorities="supervisor, teller, user" />
            </user-service>
        </authentication-provider>
    </authentication-manager>
</beans:beans>

web.xml

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

    <display-name>Sharlee Park</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring-security.xml
            /WEB-INF/spring-servlet.xml
        </param-value>
    </context-param>

    <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>

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

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

adminLoginController.java(控制器)

package au.com.sharleepark.controller.admin;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

/**
 * Controller class for the administration login
 * @author Steve 
 * @version 1.00
 * 
 * Change History
 * 08/11/12 - Created
 */
@Controller
@RequestMapping(value="admin")
public class AdminLoginController {

    private static final Logger logger = Logger.getLogger(AdminLoginController.class);

    @RequestMapping(value="/login")
    public ModelAndView doView(@RequestParam(value="error", required=false) boolean error) {
        logger.info("processing Login");

        ModelAndView mav = new ModelAndView();
        mav.setViewName("admin/login");

        if (error) {
            logger.error("Invalid Credentials");
            mav.addObject("error", "Invalid login credentials");
        }
        return mav;
    }
}

adminLogin.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<div id="login">
    <div id="loginContent">
        <div class="error">${error}</div>
        <form name='sharleeParkLoginForm' action="<c:url value='j_spring_security_check' />" method='POST'>
            <fieldset>
                <ul class="fieldUL">
                    <li>
                        <label class="inputLabel" for="j_username">Username</label>
                        <span> 
                            <input class="inputField" type="text" tabindex="1" id="j_username" name="j_username" size="25" maxlength="25">
                        </span>
                    </li>
                </ul>
                <ul class="fieldUL">
                    <li>
                        <label class="inputLabel" for="spPassword">Password</label>
                        <span> 
                            <input class="inputField" type="password" tabindex="2" id="j_password" name="j_password" size="25" maxlength="25">
                        </span>
                    </li>
                </ul>
                <ul class="fieldUL">
                    <li><input name="submit" type="submit" value="Login"></li>
                </ul>
            </fieldset>
        </form>
        </div>
</div>

瓷砖.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE tiles-definitions PUBLIC
   "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
   "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">

<tiles-definitions>
    <definition name="base.definition" template="/WEB-INF/jsp/layout.jsp">
        <put-attribute name="title" value="" />
        <put-attribute name="header" value="/WEB-INF/jsp/header.jsp" />
        <put-attribute name="body" value="" />
    </definition>

....

    <!-- ADMIN PAGES -->
    <definition name="admin/login" extends="base.definition">
        <put-attribute name="title" value="Administration Login" />
        <put-attribute name="body" value="/WEB-INF/jsp/admin/adminLogin.jsp" />
    </definition>
....

</tiles-definitions>
4

4 回答 4

8

尝试使用<http auto-config="true" use-expressions="true">.

从有关http auto-config属性的文档中:

自动注册登录表单、BASIC 身份验证、匿名身份验证、注销服务、remember-me 和 servlet-api-integration。如果设置为“true”,则会添加所有这些功能(尽管您仍然可以通过提供相应的元素来自定义每个功能的配置)。如果未指定,则默认为“false”。

于 2012-11-14T18:19:09.570 回答
0

我敢打赌你的安全配置有问题。

为什么在 http 声明中使用use-expressions="true" ?我没有看到您使用 Spring-EL 表达式...尝试将其删除并查看是否有变化。

于 2012-11-14T16:45:33.383 回答
0

通常我们不处理/login控制器中的映射。Spring security 处理登录身份验证并指向成功的 Url。您可以像这样在 spring-config.xml 中指定登录页面的视图名称。

<mvc:view-controller path="/login" view-name="login"/>

您可以在控制器类中处理成功的 url 映射。在这种情况下,如果您指定default-target-url="admin/forSale"然后编写一个方法来处理/forSale映射。

我认为因为您正在处理控制器中的“/登录”映射,所以它被定向到登录页面以获得成功和失败。

ModelAndView mav = new ModelAndView();
mav.setViewName("admin/login");

但相反,如果没有错误,那么视图应该不同mav.setViewName("admin/forSale")

于 2012-11-14T18:27:54.127 回答
0

我已经解决了。解决问题的方法是将login-processing-url="/admin/j_spring_security_check"属性添加到<form-login>标签中。我之前没有使用过 Spring Security,我想我只是假设过滤器会神奇地找到j_spring_security_check并相应地处理。j_spring_security_check如果来自应用程序的根 URI(即 /sharleepark/j_spring_security_check),过滤器可能会选择它?我从来没有看到需要login-processing-url在我一直在看的任何教程中指定。再次感谢大家的意见。

于 2012-11-15T18:22:29.120 回答