spring安全框架Security(一) 转

    现在很多企业和开发团队都使用了SSH2(Struts 2 +Spring 2.5 +Hibernate)框架来进行开发,  我们或许已经习惯了强大的Spring Framework 全局配置管理,不可否认,Sping是一个很优秀的开源框架,但是由于Spring3.0版本后强大的的注解式bean的诞生,Spring MVC框架这匹黑马正悄然杀起,但今天Spring MVC不是主角,今天我和大家分享一个同样隶属于SpringSource 的安全框架——Spring Security, 下面的基于Spring MVC给大家分享一下Spring Security  的使用。虽然对它的接触时间不长,参考了一些网上朋友的做法,但也按照我的理解把这个框架介绍介绍,不是很专业,还请大家不要介意 。   

     我们知道,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分。用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个资源来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。

     首先,我们看web.xml

    Java代码 

<?xml version="1.0" encoding="UTF-8"?>  
<web-app version="2.5" 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_2_5.xsd">  
    <!-- 编码统一最好放最上面,最先加载,防止乱码-->  
    <filter>  
        <filter-name>Set Character Encoding</filter-name>  
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  
        <init-param>  
            <param-name>encoding</param-name>  
            <param-value>UTF-8</param-value>  
        </init-param>  
        <init-param>  
            <param-name>forceEncoding</param-name>  
            <param-value>true</param-value><!-- 强制进行转码 -->  
        </init-param>  
    </filter>  
  
    <filter-mapping>  
        <filter-name>Set Character Encoding</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>  
    <!-- 然后接着是SpringSecurity必须的filter 优先配置,让SpringSecurity先加载,防止SpringSecurity拦截失效-->  
    <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>  
  
    <welcome-file-list>  
        <welcome-file>index.jsp</welcome-file>  
    </welcome-file-list>  
  
    <!--   
    spring需要加载的配置文件  
-->  
    <context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>   
    WEB-INF/classes/applicationContext.xml,  
    WEB-INF/spring3-servlet.xml,  
    WEB-INF/spring-security.xml   
        </param-value>  
    </context-param>  
  
    <listener>  
        <listener-class>  
            <!--     所以,要在web.xml下面配置好监听,让服务器启动时就初始化改类,可以得到request   -->  
            org.springframework.web.context.request.RequestContextListener  
        </listener-class>  
    </listener>  
    <listener>  
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    </listener>  
  
  
    <!--  
        默认所对应的配置文件是WEB-INF下的{servlet-name}-servlet.xml,这里便是:spring3-servlet.xml  
    -->  
    <servlet>  
        <servlet-name>spring3</servlet-name>  
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
        <load-on-startup>1</load-on-startup>  
  
    </servlet>  
  
    <servlet-mapping>  
        <servlet-name>spring3</servlet-name>  
        <!--  
            这里可以用 / 但不能用 /*  
            ,拦截了所有请求会导致静态资源无法访问,所以要在spring3-servlet.xml中配置mvc:resources  
        -->  
        <url-pattern>/</url-pattern>  
    </servlet-mapping>  
  
  
  
</web-app>

    注释已经写了挺多,还是稍微解释一下要注意的地方,一个是UTF-8编码转换,这个最好加在最前面,让它先生效,我在调试的时候就出过这种情况,web.xml里的其他配置都正常生效了,但是编码死活不行,一中文就乱码,郁闷了老半天,然后突发奇想,是不是web.xml里先声明的配置先生效,后声明的后生效?接着实践,果然不出我所料,把编码转换加在前面,一切正常。。。。我那个晕。。。

    关于Spirng MVC的就不说了,那些数据访问、业务和控制层那些的东东就自个研究去了吧。。这不是今天的重点。

    接着是spring-security.xml

    Java代码 

<?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:security="http://www.springframework.org/schema/security"  
    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.0.xsd">  
  
    <!--  Spring-Security 的配置 -->  
    <!--  
        注意use-expressions=true.表示开启表达式,否则表达式将不可用. see:http://www.family168.com/tutorial/springsecurity3/html/el-access.html  
    -->  
    <security:http auto-config="true" use-expressions="false" access-denied-page="/user/login_failure.html">  
        <!--允许所有人访问-->  
        <!--     <security:intercept-url pattern="/**" access="permitAll" />-->  
        <!--允许ROLE_ADMIN权限访问-->  
        <security:intercept-url pattern="/user/findAll.html" access="ROLE_ADMIN" />  
        <!--允许ROLE_ADMIN权限访问-->  
        <security:intercept-url pattern="/user/**" access="ROLE_ADMIN" />  
        <!--允许ROLE_USER权限访问-->  
        <security:intercept-url pattern="/success.jsp" access="ROLE_USER,ROLE_ADMIN" />  
        <!--允许IS_AUTHENTICATED_ANONYMOUSLY匿名访问-->  
        <security:intercept-url pattern="/anonymously.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />  
          
        <!-- filters="none"  不过滤这些资源-->  
        <security:intercept-url pattern="/js/**" filters="none" />  
        <security:intercept-url pattern="/index.jsp" filters="none" />  
  
        <!-- login-page:默认指定的登录页面. authentication-failure-url:出错后跳转页面. default-target-url:成功登陆后跳转页面 -->  
        <security:form-login login-page="/index.jsp" authentication-failure-url="/user/login_failure.html"  
            default-target-url="/success.jsp" />  
        <!--  
            invalidate-session:指定在退出系统时是否要销毁Session。logout-success-url:退出系统后转向的URL。logout-url:指定了用于响应退出系统请求的URL。其默认值为:/j_spring_security_logout。  
        -->  
        <security:logout invalidate-session="true" logout-success-url="/index.jsp" logout-url="/j_spring_security_logout" />  
        <!--  
            max-sessions:允许用户帐号登录的次数。范例限制用户只能登录一次。exception-if-maximum-exceeded:  
            默认为false,此值表示:用户第二次登录时,前一次的登录信息都被清空。当exception-if-maximum-exceeded="true"时系统会拒绝第二次登录。  
        -->  
  
        <security:session-management>  
            <security:concurrency-control error-if-maximum-exceeded="true" max-sessions="1" />  
        </security:session-management>  
  
    </security:http>  
    <!-- 指定一个自定义的authentication-manager :customUserDetailsService -->  
    <security:authentication-manager>  
        <security:authentication-provider user-service-ref="customUserDetailsService">  
            <security:password-encoder ref="passwordEncoder" />  
        </security:authentication-provider>  
    </security:authentication-manager>  
  
    <!-- 对密码进行MD5编码 -->  
    <bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />  
  
    <!--   
        通过 customUserDetailsService,Spring会控制用户的访问级别.  
        也可以理解成:以后我们和数据库操作就是通过customUserDetailsService来进行关联.  
     -->  
    <bean id="customUserDetailsService" class="org.yzsoft.springmvcdemo.util.CustomUserDetailsService" />  
    <!-- 自定义登陆错误提示,可以取出mymessages.properties的国际化消息-->  
    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">  
        <property name="basename" value="classpath:org/yzsoft/springmvcdemo/mymessages" />  
    </bean>  
    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver" />  
</beans>

    这个多解释一下,首先

    Java代码 

<security:intercept-url pattern="/findAll.html" access="hasRole('ROLE_ADMIN')" />  
<security:intercept-url pattern="/user/**" access="hasRole('ROLE_ADMIN')" />  
<security:intercept-url pattern="/anonymously.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />

    这个是权限控制,声明了拥有什么权限可以访问哪些资源,这个配置的是有ROLE_ADMIN权限的才可以访问/findAll.html,至于这个ROLE_ADMIN从哪来,呆会再解释。或者像第二句一样配置也可以:拥有ROLE_ADMIN权限的才可以访问/user/下的所有资源,否则都会抛出AccessDeniedException 。

IS_AUTHENTICATED_ANONYMOUSLY就是匿名访问的意思,这个相信都懂的。。。

    然后是登陆和安全退出

    Java代码  

<security:form-login login-page="/index.jsp" authentication-failure-url="/user/login_failure.html"default-target-url="/user/findAll.html" />  
<security:logout invalidate-session="true" logout-success-url="/index.jsp" logout-url="/user/login_failure.html" />

    解释下上面一句,相信看也能看出来了的,login-page:默认指定的登录页面. authentication-failure-url:出错后跳转页面(包括那些个啥用户名密码错误吖。。啥啥啥的。). default-target-url:成功登陆后跳转页面 (这里我直接跳到的控制器去查数据列表)。   

    接着:invalidate-session:指定在退出系统时是否要销毁Session。logout-success-url:退出系统后转向的URL。logout-url:指定了用于响应退出系统请求的URL。其默认值为:/j_spring_security_logout。

接下来是一个比较不错的功能:是否允许同一用户多处登陆

    Java代码 

<security:session-management>  
     <security:concurrency-control error-if-maximum-exceeded="true" max-sessions="1" />  
</security:session-management>

    exception-if-maximum-exceeded:        默认为false,此值表示:用户第二次登录时,前一次的登录信息都被清空。当error-if-maximum-exceeded="true"时系统会拒绝第二次登录。 

        max-sessions:允许用户帐号登录的次数,这里我们允许一次登陆。这里我们做个实验吧,看看是不是真的生效了,请看图

    这里我们看到,当同一个账号多处登陆时,就会报出Maximum sessions of 1 for this principal exceeded 的错误,当然,正式使用我们换成mymessages.properties里的我们自定义的国际化消息,这样人性化一点。    

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏FreeBuf

登录框的另类思考:来自客户端的欺骗

前几天刚见人发了《一个登录框引发的血案》,而常规的爆破有风控和各种变态验证码,或者大型的电商都会用SSO实现登录,密码找回逻辑看似天衣无缝,又或者采用第三方的O...

1280
来自专栏我是攻城师

浅谈Java项目打包方式

4118
来自专栏刘望舒

这一次彻底弄明白Gradle相关配置

7582
来自专栏小狼的世界

使用PHP脚本来写Daemon程序

这又是一个有趣的概念,daemon在英语中是"精灵"的意思,就像我们经常在迪斯尼动画里见到的那些,有些会飞,有些不会,经常围着动画片的主人公转来转去,啰里啰唆地...

1372
来自专栏EAWorld

Micronaut:面向未来的微服务和云原生应用框架

原题:MICRONAUT: A JAVA FRAMEWORK FOR THE FUTURE, NOW

3462
来自专栏纯洁的微笑

Eureka 虽然闭源了,但注册中心还有更多选择:Consul 使用详解

在上个月我们知道 Eureka 2.0 闭源了,但其实对国内的用户影响甚小,一方面国内大都使用的是 Eureka 1.X 系列,另一方面

5113
来自专栏Web项目聚集地

RESTful 接口实现简明指南

在我所见过的 RESTful 接口的实现中,以 GitHub 最让人惊叹。我第一次如此强烈得感受到 REST 接口的美妙,完全满足了我所期待的「接口的形式美感」...

781
来自专栏大数据架构师专家

namp 渗透测试-安装篇

nmap是一个网络连接端扫描软件,用来扫描网上电脑开放的网络连接端。确定哪些服务运行在哪些连接端,并且推断计算机运行哪个操作系统。

1033
来自专栏生信技能树

从黑暗走向光明:Python包安装进阶之路

想当初刚学习Python的时候,就会用书本里面自带的一些package,用sys,os也用得很开心。后来接触到biopython项目,发现原来Python有这么...

3187
来自专栏杂烩

SSM项目搭建之MyBatis 原

    MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了goog...

702

扫码关注云+社区