`
whp0731
  • 浏览: 176814 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

spring security 配置文件小结(逐步深化到url级别)

阅读更多

 

一 、方式一:用户名密码都在配置文件中。
<?xml version="1.0" encoding="UTF-8"?>
<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-2.0.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">

    <http auto-config='true'>
        <intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" />
        <intercept-url pattern="/**" access="ROLE_USER" />
    </http>

    <authentication-provider>
        <user-service>
            <user name="admin" password="admin" authorities="ROLE_USER, ROLE_ADMIN" />
            <user name="user" password="user" authorities="ROLE_USER" />
        </user-service>
    </authentication-provider>

</beans:beans>


二、方式二:运用spring security 提供的默认表结构,authentication部分修改如下:
    <authentication-provider>
        <jdbc-user-service data-source-ref="dataSource"/>
    </authentication-provider>

    <beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <beans:property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
        <beans:property name="url" value="jdbc:hsqldb:res:/hsqldb/test"/>
        <beans:property name="username" value="sa"/>
        <beans:property name="password" value=""/>
    </beans:bean>
	
	
三、方式三:运用原先本地的数据库,authentication修改如下:
    <authentication-provider>
        <jdbc-user-service data-source-ref="dataSource"
            users-by-username-query="select username,password,status as enabled
                                         from user
                                        where username=?"
            authorities-by-username-query="select u.username,r.name as authority
                                             from user u
                                             join user_role ur
                                               on u.id=ur.user_id
                                             join role r
                                               on r.id=ur.role_id
                                            where u.username=?"/>
    </authentication-provider>
            
 注:
 users-by-username-query为根据用户名查找用户,系统通过传入的用户名查询当前用户的登录名,密码和是否被禁用这一状态。
 authorities-by-username-query为根据用户名查找权限,系统通过传入的用户名查询当前用户已被授予的所有权限。
 
四、方式四;在方式三的基础上,修改登录页面
在xml中的http标签中添加一个form-login标签。

<http auto-config='true'>
    <intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />[1]
    <intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" />
    <intercept-url pattern="/**" access="ROLE_USER" />
    <form-login login-page="/login.jsp"[2]
                authentication-failure-url="/login.jsp?error=true"[3]
                default-target-url="/" />[4]
</http>
        
 
1、让没登陆的用户也可以访问login.jsp。[1]

这是因为配置文件中的“/**”配置,要求用户访问任意一个系统资源时,必须拥有ROLE_USER角色,/login.jsp也不例外,如果我们不为/login.jsp单独配置访问权限,会造成用户连登陆的权限都没有,这是不正确的。
 
 2、login-page表示用户登陆时显示我们自定义的login.jsp。[2]

这时我们访问系统显示的登陆页面将是我们上面创建的login.jsp。
 
 3、authentication-failure-url表示用户登陆失败时,跳转到哪个页面。[3]

当用户输入的登录名和密码不正确时,系统将再次跳转到/login.jsp,并添加一个error=true参数作为登陆失败的标示。
 
 
 4、default-target-url表示登陆成功时,跳转到哪个页面。[4]
 
 五、方式五:使用数据配置角色可以访问的资源(控制到URL级别)(可以参见工程005)
<!--从配置文件上可以看到,Spring Security所需的数据应该是一系列URL网址和访问这些网址所需的权限:

<intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" />
<intercept-url pattern="/**" access="ROLE_USER" />
            
SpringSecurity所做的就是在系统初始化时,将以上XML中的信息转换为特定的数据格式,而框架中其他组件可以利用这些特定格式的数据,用于控制之后的验证操作。现在这些资源信息都保存在数据库中了,从数据库中取出数据,然后让它等同于从xml文件中取出,需要做以下几步。
-->
 1、实现一个符合该功能的类,主要参看该类中1-5步骤,了解即可。
 <!--

public class JdbcFilterInvocationDefinitionSourceFactoryBean
    extends JdbcDaoSupport implements FactoryBean {
    private String resourceQuery;

    public boolean isSingleton() {
        return true;
    }

    public Class getObjectType() {
        return FilterInvocationDefinitionSource.class;
    }
    //4、 使用urlMatcher和requestMap创建DefaultFilterInvocationDefinitionSource。
    public Object getObject() {
        return new DefaultFilterInvocationDefinitionSource(this
            .getUrlMatcher(), this.buildRequestMap());
    }
    //2、这样我们可以执行它的execute()方法获得所有资源信息。并把它封装到map中。
 
    protected Map<String, String> findResources() {
        ResourceMapping resourceMapping = new ResourceMapping(getDataSource(),
                resourceQuery);

        Map<String, String> resourceMap = new LinkedHashMap<String, String>();

        for (Resource resource : (List<Resource>) resourceMapping.execute()) {
            String url = resource.getUrl();
            String role = resource.getRole();

            if (resourceMap.containsKey(url)) {
                String value = resourceMap.get(url);
                resourceMap.put(url, value + "," + role);
            } else {
                resourceMap.put(url, role);
            }
        }

        return resourceMap;
    }
    
    
/*    <intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" />
    <intercept-url pattern="/**" access="ROLE_USER" />*/

    //3、使用获得的资源信息组装requestMap。再把第二步封装到map中的方法进一步加工,使它等价于“如spring从上面模式的配置文件中读取一样”
    protected LinkedHashMap<RequestKey, ConfigAttributeDefinition> buildRequestMap() {
        LinkedHashMap<RequestKey, ConfigAttributeDefinition> requestMap = null;
        requestMap = new LinkedHashMap<RequestKey, ConfigAttributeDefinition>();

        ConfigAttributeEditor editor = new ConfigAttributeEditor();

        Map<String, String> resourceMap = this.findResources();

        for (Map.Entry<String, String> entry : resourceMap.entrySet()) {
            RequestKey key = new RequestKey(entry.getKey(), null);
            editor.setAsText(entry.getValue());
            requestMap.put(key,
                (ConfigAttributeDefinition) editor.getValue());
        }

        return requestMap;
    }

    protected UrlMatcher getUrlMatcher() {
        return new AntUrlPathMatcher();
    }

    public void setResourceQuery(String resourceQuery) {
        this.resourceQuery = resourceQuery;
    }

    private class Resource {
        private String url;
        private String role;

        public Resource(String url, String role) {
            this.url = url;
            this.role = role;
        }

        public String getUrl() {
            return url;
        }

        public String getRole() {
            return role;
        }
    }
    //1、我们通过定义一个MappingSqlQuery实现数据库操作。
    private class ResourceMapping extends MappingSqlQuery {
        protected ResourceMapping(DataSource dataSource,
            String resourceQuery) {
            super(dataSource, resourceQuery);
            compile();
        }

        protected Object mapRow(ResultSet rs, int rownum)
            throws SQLException {
            String url = rs.getString(1);
            String role = rs.getString(2);
            Resource resource = new Resource(url, role);

            return resource;
        }
    }
}

 -->
 2、替换原有功能的切入点
 在spring中配置我们编写的代码。

<beans:bean id="filterInvocationDefinitionSource"
    class="com.family168.springsecuritybook.ch005.JdbcFilterInvocationDefinitionSourceFactoryBean">
    <beans:property name="dataSource" ref="dataSource"/>
    <beans:property name="resourceQuery" value="
        select re.res_string,r.name
          from role r
          join resc_role rr
            on r.id=rr.role_id
          join resc re
            on re.id=rr.resc_id
      order by priority
    "/>
</beans:bean>
            
下一步使用这个filterInvocationDefinitionSource创建filterSecurityInterceptor,并使用它替换系统原来创建的那个过滤器。

<beans:bean id="filterSecurityInterceptor"
    class="org.springframework.security.intercept.web.FilterSecurityInterceptor" autowire="byType">
    <custom-filter before="FILTER_SECURITY_INTERCEPTOR" />
    <beans:property name="objectDefinitionSource" ref="filterInvocationDefinitionSource" />
</beans:bean>
            
注意这个custom-filter标签,它表示将filterSecurityInterceptor放在框架原来的FILTER_SECURITY_INTERCEPTOR过滤器之前,这样我们的过滤器会先于原来的过滤器执行,因为它的功能与老过滤器完全一样,所以这就等于把原来的过滤器替换掉了。
 
 3、完整的配置文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<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-2.0.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">

    <http auto-config="true"/>

    <authentication-provider>
        <jdbc-user-service data-source-ref="dataSource"
            users-by-username-query="select username,password,status as enabled
                                       from user
                                      where username=?"
            authorities-by-username-query="select u.username,r.name as authority
                                             from user u
                                             join user_role ur
                                               on u.id=ur.user_id
                                             join role r
                                               on r.id=ur.role_id
                                            where u.username=?"/>
    </authentication-provider>

    <beans:bean id="filterSecurityInterceptor"
        class="org.springframework.security.intercept.web.FilterSecurityInterceptor" autowire="byType">
        <custom-filter before="FILTER_SECURITY_INTERCEPTOR" />
        <beans:property name="objectDefinitionSource" ref="filterInvocationDefinitionSource" />
    </beans:bean>

    <beans:bean id="filterInvocationDefinitionSource"
        class="com.family168.springsecuritybook.ch05.JdbcFilterInvocationDefinitionSourceFactoryBean">
        <beans:property name="dataSource" ref="dataSource"/>
        <beans:property name="resourceQuery" value="
            select re.res_string,r.name
              from role r
              join resc_role rr
                on r.id=rr.role_id
              join resc re
                on re.id=rr.resc_id
          order by priority
        "/>
    </beans:bean>

    <beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <beans:property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
        <beans:property name="url" value="jdbc:hsqldb:res:/hsqldb/test"/>
        <beans:property name="username" value="sa"/>
        <beans:property name="password" value=""/>
    </beans:bean>
</beans:beans>


 4、允许动态增加某个用户权限。
 目前存在的问题是,系统会在初始化时一次将所有资源加载到内存中,即使在数据库中修改了资源信息,系统也不会再次去从数据库中读取资源信息。这就造成了每次修改完数据库后,都需要重启系统才能时资源配置生效。

解决方案是,如果数据库中的资源出现的变化,需要刷新内存中已加载的资源信息时,使用下面代码:

<%@page import="org.springframework.context.ApplicationContext"%>
<%@page import="org.springframework.web.context.support.WebApplicationContextUtils"%>
<%@page import="org.springframework.beans.factory.FactoryBean"%>
<%@page import="org.springframework.security.intercept.web.FilterSecurityInterceptor"%>
<%@page import="org.springframework.security.intercept.web.FilterInvocationDefinitionSource"%>
<%
    ApplicationContext ctx =  WebApplicationContextUtils.getWebApplicationContext(application);
    FactoryBean factoryBean = (FactoryBean) ctx.getBean("&filterInvocationDefinitionSource");
    FilterInvocationDefinitionSource fids = (FilterInvocationDefinitionSource) factoryBean.getObject();
    FilterSecurityInterceptor filter = (FilterSecurityInterceptor) ctx.getBean("filterSecurityInterceptor");
    filter.setObjectDefinitionSource(fids);
%>
<jsp:forward page="/"/>
参考资料www.family168.com    

 
 


 

分享到:
评论
1 楼 fooky 2010-05-23  
你好,今天在配置spring secutiry3,想让系统先从数据库中保存的权限信息优先于xml中配置的s:intercept-url权限,配置如下:
<beans:bean id="filterSecurityInterceptor"
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor"
autowire="byType">
<s:custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref=""/>
<beans:property name="objectDefinitionSource" ref="filterInvocationDefinitionSource"/>
</beans:bean>
注意红色的那行,我看你的文章,都没有配置ref的,我不配置ref时tomcat启动时报错:
Caused by: org.xml.sax.SAXParseException: cvc-complex-type.4: Attribute 'ref' must appear on element 's:custom-filter'.
但是如果需要配置的话,这个ref要写什么呢?我随便写,或者写成ref=""则报如下错:
Configuration problem: Security namespace does not support decoration of element [custom-filter]

帮忙看下,谢谢。

相关推荐

    SpringSecurity 3配置文件

    在本文中,我们将深入探讨Spring Security 3的配置文件,以及如何理解和使用这些配置来增强应用的安全性。 首先,Spring Security的配置通常位于一个或多个XML文件中,这些文件通过`&lt;beans&gt;`标签定义了安全相关的...

    springsecurity使用配置详解

    在提供的压缩包`springsecurity配置demo`中,你将找到示例代码和详细说明,这将帮助你更好地理解和实践上述概念。通过学习和实践这些示例,你将能够为自己的Spring应用程序构建强大的安全防护。

    Spring Security 配置实例XML文件

    Spring Security 配置实例XML文件

    spring security配置实例

    3. **Spring Security配置文件 (`applicationContext-security.xml`)**: - 在这个文件中,开发者可以通过定义过滤器链、认证管理器、授权决策机制等来实现具体的安全策略。 - 可以指定不同的URL路径所对应的访问...

    spring security3配置和使用实例+教程

    教程文档`教你使用_SpringSecurity_3.0_52页.pdf`会详细指导你如何一步步配置和使用Spring Security。它应该包含了配置文件的示例、如何集成到Spring应用中、如何创建自定义认证逻辑以及如何进行授权设置等内容。...

    Spring Security如何使用URL地址进行权限控制

    Spring Security如何使用URL地址进行权限控制 Spring Security是一个功能强大且广泛应用的Java安全框架,它提供了许多功能,包括身份验证、授权、加密等。其中,权限控制是Spring Security的一个重要组件,它允许...

    spring security2配置

    在这个"Spring Security2配置"的主题中,我们将深入探讨如何配置Spring Security来保护我们的应用程序,以及它的一些核心概念。 首先,让我们理解Spring Security的基本组件。`Users.java`、`Roles.java`暗示了用户...

    spring-security多登录页面配置

    从给定的部分内容来看,我们可以看到这是一个Spring Security的配置文件,使用了Spring Security的XML命名空间。下面是一个示例性的配置片段: ```xml &lt;!-- 允许访问登录页面 --&gt; &lt;intercept-url pattern="/...

    Spring Security in Action

    Spring Security 的配置主要通过 security.xml 文件实现。security.xml 文件中定义了身份验证、授权和访问控制等配置项。 六、Spring Security 的架构 Spring Security 的架构主要包括以下几层: * Presentation ...

    spring cloud2.0 eureka server spring security配置

    在Spring Cloud 2.0版本中,Eureka Server的配置相比1.x版本确实有了一些显著的变化,尤其是在结合Spring Security进行安全设置时。Spring Cloud Eureka是Netflix Eureka的Spring Boot实现,它为微服务架构提供了...

    SpringSecurity笔记,编程不良人笔记

    在`SpringSecurity.md`和`SpringSecurity.pdf`文档中,可能包含SpringSecurity配置、自定义用户服务、授权策略等方面的代码示例。`codes`目录可能包含实际运行的项目代码,方便读者实践和理解。 8. **图笔记.draw...

    spring-security3 配置和使用

    首先,需要从 Spring Security 官网下载最新的 jar 文件,然后将其拷贝到项目的 lib 目录下。这样便可以使用 Spring Security 3 框架来保护我们的应用程序。 配置 Spring Security 3 在 classpath 下添加 security...

    spring security 项目配置源码

    - **测试**:访问项目中的不同URL,观察Spring Security的访问控制效果,例如未登录用户尝试访问受保护的页面时应被重定向到登录页面。 5. **学习资源** - 通过源码分析,了解Spring Security的拦截器如何工作,...

    spring security 2 配置说明

    `web.xml`文件是Web应用程序的部署描述符,其中的`&lt;filter&gt;`和`&lt;filter-mapping&gt;`配置是Spring Security的关键部分。通过注册`DelegatingFilterProxy`,确保了Spring Security Filter Chain能够在每个HTTP请求上运行...

    spring security 完整项目实例

    Spring Security 是一个强大的安全框架,用于为Java应用提供身份验证和授权服务。在这个完整的项目实例中,我们将深入探讨Spring Security的核心概念以及如何将其应用于实际的Web应用程序开发。 首先,我们从用户、...

    Restful风格服务端应用的Spring Boot + Spring Security配置

    在`pom.xml`文件中,我们需要引入`spring-boot-starter-security`和`spring-boot-starter-web`,这将为我们提供安全服务和Web支持。 ```xml &lt;groupId&gt;org.springframework.boot &lt;artifactId&gt;spring-boot-starter...

    SpringSecurity.pdf

    Spring Security的配置灵活,可以通过XML配置文件、Java配置类或者注解来定制安全策略。它还提供了大量的扩展点,允许开发者根据自己的业务需求进行定制和扩展。 Spring Security的学习过程可以分为入门、进阶和...

    spring security xml方式配置

    总结来说,Spring Security XML配置涉及到的主要知识点包括:`&lt;http&gt;`元素的设置、拦截URL的配置、`&lt;authentication-manager&gt;`和`&lt;authentication-provider&gt;`的使用、自定义登录表单的实现以及Spring MVC和Bootstrap...

    Spring Security 3.1 配置实例,有URL 方法拦截,都存数据库 maven

    **Spring Security 3.1配置实例** Spring Security是一款强大的安全框架,用于保护基于Java的Web应用程序。在3.1版本中,它提供了丰富的功能来管理应用程序的安全性,包括URL访问控制、用户认证、授权以及方法级别...

Global site tag (gtag.js) - Google Analytics