Java 使用Spring 3.1对两个网页进行密码保护

Java 使用Spring 3.1对两个网页进行密码保护,java,spring,jsp,spring-mvc,spring-security,Java,Spring,Jsp,Spring Mvc,Spring Security,我一直在寻找与我的问题相近的问题,但似乎找不到我想要的确切答案。我猜我想做的事情的解决方案相当简单 我有一个带有默认页面(index.jsp)的网站。从索引页到管理页(admin.jsp)有一个链接。这个页面已经用Spring密码保护了很长时间,没有问题。以下是我一直在使用的安全上下文文件: <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http:/

我一直在寻找与我的问题相近的问题,但似乎找不到我想要的确切答案。我猜我想做的事情的解决方案相当简单

我有一个带有默认页面(index.jsp)的网站。从索引页到管理页(admin.jsp)有一个链接。这个页面已经用Spring密码保护了很长时间,没有问题。以下是我一直在使用的安全上下文文件:

<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.1.xsd
                    http://www.springframework.org/schema/security 
                    http://www.springframework.org/schema/security/spring-security-3.1.xsd">

    <global-method-security pre-post-annotations="enabled" secured-annotations="enabled"/>     

    <http use-expressions="true">
        <intercept-url pattern="/admin.jsp" access="hasRole('administrator')" />
        <intercept-url pattern="/**" access="permitAll" />
        <form-login login-page="/login.jsp" default-target-url="/admin.jsp" />
        <logout />
    </http>

    <authentication-manager>
        <authentication-provider>
            <user-service>
                <user name="${admin.username}" password="${admin.password}" authorities="administrator" />
            </user-service>
        </authentication-provider>
    </authentication-manager>
</beans:beans>   

我现在还需要对index.jsp进行密码保护。如果我复制元素的子元素(并且创建了单独的login.jsp文件,不确定是否有必要),如下所示:

<http use-expressions="true">
        <intercept-url pattern="/index.jsp" access="hasRole('user')" />
        <form-login login-page="/indexLogin.jsp" default-target-url="/index.jsp" />
        <logout />

        <intercept-url pattern="/admin.jsp" access="hasRole('administrator')" />
        <form-login login-page="/adminLogin.jsp" default-target-url="/admin.jsp" />
        <logout />
    </http>

    <authentication-manager>
        <authentication-provider>
            <user-service>
                <user name="${admin.username}" password="${admin.password}" authorities="administrator" />
                <user name="${user.username}" password="${user.password}" authorities="user" />
            </user-service>
        </authentication-provider>
    </authentication-manager>

然后index.jsp完全按照预期进行密码保护。但是,如果我单击在新选项卡中打开admin.jsp页面的按钮,我会得到一个403-Access is denied错误。我假设这是因为它会自动尝试使用管理员页面上的用户凭据

然后,我尝试创建两个单独的元素,每个元素针对不同的页面:

<http use-expressions="true">
        <intercept-url pattern="/index.jsp" access="hasRole('user')" />
        <form-login login-page="/indexLogin.jsp" default-target-url="/index.jsp" />
        <logout />
    </http>

    <http use-expressions="true">
        <intercept-url pattern="/admin.jsp" access="hasRole('administrator')" />
        <form-login login-page="/adminLogin.jsp" default-target-url="/admin.jsp" />
        <logout />
    </http>

然后我得到一个错误声明:

java.lang.IllegalArgumentException:在筛选器链中的其他模式之前定义了通用匹配模式('/**'),导致它们被忽略。请检查命名空间或FilterChainProxy bean配置中的顺序


有谁能给我一个指针,告诉我如何强制Spring在每次访问index.jsp或admin.jsp时提示输入凭据,而不是假设应该使用现有凭据?

尝试使用如下“拒绝访问处理程序”:

<http ...>
    ...
    <access-denied-handler error-page="the page you want to redirect to"/>
</http>

...

您可能不需要Spring Security“在每次访问
index.jsp
admin.jsp
时提示输入凭据”。 这将不是SpringSecurity的常见用例,即使您成功地做到了这一点,也会使事情变得更加复杂

相反,您可以在用户访问应用程序的任何网页时对其进行身份验证(即,您只需提示输入一次ligin和密码)。当用户试图访问
admin.jsp
时,您可以 使用已允许或拒绝访问此页面的用户凭据

您需要将原始代码中的
access=“permitAll”
替换为
access=“hasRole('user')”
。所以你的
标签应如下所示:

<http use-expressions="true">
    <intercept-url pattern="/admin.jsp" access="hasRole('administrator')" />
    <intercept-url pattern="/**" access="hasRole('user')" />
    <form-login login-page="/login.jsp" default-target-url="/admin.jsp" />
    <logout />
</http>
Spring Security按照规则的定义顺序匹配规则。首先,它将检查请求的页面是否与
/admin.jsp
模式匹配。如果是,则将使用
hasRole('administrator')
作为此页面的访问规则。所有其他页面将匹配
/**
模式。由于所有经过身份验证的用户(包括
管理员
)都属于
用户
角色,因此任何经过身份验证的用户都可以使用所有其他页面

内不能使用多个
标记。我还怀疑您能否在Spring配置中定义多个
部分

有关配置Spring安全性的更多详细信息,请参阅

更新


另外,将
default target url=“/admin.jsp”
替换为
default target url=“/index.jsp”
,因为您不希望普通(非管理员)用户被重定向到
admin.jsp

,所以我应该使用两个单独的元素,一个来定义每个需要安全保护的页面吗?如果是这样,我如何绕过“通用匹配模式…”例外?不,只有一个元素,现在,您将获得您配置的错误页面,而不是“403-访问被拒绝错误”。我理解您解释的概念,我喜欢它,但是,当我遵循您概述的内容时,我在浏览器中看到以下内容:“页面没有正确重定向。Firefox检测到服务器正在以一种永远不会完成的方式重定向对此地址的请求。“当我访问默认url时,我被重定向到欢迎文件(index.jsp),我可以在地址栏中看到我被重定向到login.jsp。这就是我在Firefox中看到错误的时候。只需更改以修复该问题!
<authentication-manager>
    <authentication-provider>
        <user-service>
            <user name="${admin.username}" password="${admin.password}" authorities="user,administrator" />
            <user name="${user.username}" password="${user.password}" authorities="user" />
        </user-service>
    </authentication-provider>
</authentication-manager>