SpringSecurity学习(一)

由于是刚搬到广州找工作,所以对公司的选择要求并不是很高。进了一家技术并不那么新的公司,其他的都懂,就是公司使用的SpringSecurity框架实在没有使用过,所以从官方文档开始读起,并开始做一些笔记.(由于SpringSecurity4的变动比较大,这里使用的版本是SpringSecurity3)

这里是概念部分,暂时不会有任何代码

二、SpringSecurity起步

安全的核心概念(这是springSecuriy工作的最重要两个部分,记住名词概念)

1.认证
1)凭证:                     系统用于鉴别当前使用者是否是合法用户的资料
2)两要素认证:            要求输入帐号和密码的认证过程
3)硬件认证                 比如钥匙和打火装置
4)已认证安全实体     认证过的实体(principal)
2.授权:

授权的两方面:已认证安全实体拥有的权限和访问资源所需要的权限的映射关系
所以,在授权过程中,必须检查访问资源所需要的权限和已认证安全实体拥有的权限是否有交集

简单地说, 检查用户是否有权限访问这个资源

  ====================================================================================================
使用SpringSecurity的最低要求
1.springSecurity.xml        使用xml形式配置springSecurity(在web.xml中配置读取该资源文件)
2.web.xml                    配置拦截器org.springframework.web.filter.DelegatingFilterProxy拦截所有资源

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

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:SpringSecurity.xml,classpath:beans.xml</param-value>
  </context-param>

注意:1)如果在SpringSecurity.xml使用了<http config="auto">,那么就会启用springSecurity的25个拦截器
            2)springSecurityFilterChain这个名字必须配对DelegatingFilterProxy,这样DelagatingFilterProxy才能找到SpringSecurity配置的拦截器
===============================================================================================================================
用户是怎样认证的?
有三个主要的组件负责这项重要的事情
1)AbstractAuthenticationProcessingFilter:它会判断凭证的来源和来源的合法性,凭证合法性将由AuthenticationManager来执行
2)AuthenticationManager:并不直接检验凭证的合法性,它只负责检验凭证合法性后的操作(包括凭证合法或者错误)。合法将会往Authentication中添加权限信息
3)AuthenticationProvider:校验凭证的合法性
注意:Filter会产生一个Authentication对象,交给Manager来进行校验,并进行最后的处理
抽象:    AbstractAuthenticationProcessingFilter:项目经理:只要项目合法,就拿回来做
        AuthenticationManager:技术经理:我不负责项目的具体执行,但我要保证项目中发生的一切事项我都可以处理
        AuthenticationProvider:程序员:项目的具体执行(每个项目只能由多个程序员中适合该项目的一个来完成)
SpringSecurity学习(一)
Authentication接口可以实现的方法
方法签名                                    描述
Object getPrincipal()                        返回安全实体的唯一标识
Object getCredentials()                        返回安全实体的凭证信息
List<GrantedAuthority> getAuthorities        得到安全实体的权限集合,根据认证信息的存储决定的
Object getDetails()                            返回一个跟认证提供者相关的安全实体细节信息

spring_security_login是什么?
spring_security_login是springSecurity默认的登录页面,可以通过属性来配置(一定要配置,不然会暴露使用springSecurity的事实)

关于登录时提交表单的地址j_spring_security_check
这个url并没有实际的资源地址,不过可以被UsernamePasswordAuthenticationFilter监视到并处理

Anthentication和UserDetails的区别
Anthentication:它存储安全实体的标志(用户名)、密码以及认证请求的上下文。可能包含一个UserDeils事例,通常不被扩展
UserDetail:为了存储一个安全实体的概况信息,(包括不限于)帐号的权限等其他信息。SpringSecurity学习(一)

============================================================================================================================
校验中的异常
1.所有认证相关的异常都继承自AuthenticationException基类
2.异常的异常都包括两个属性(1.anthentication(认证过程中使用的凭证对象),2.extraInformation(额外的错误信息))
============================================================================================================================
请求是如何被授权的?(授权默认有三种voter,由于anthenticationVoter实在是过于没用,这里只讨论roleVoter和WebExpressionVoter)
1.会被FilterSecurityInteceptor拦截到,交给AccessDesicionManager(默认的实现类是AffirnativeBased)处理
2.AccessDecisionManager根据support()方法判断实现类是否支持该请求的授权,然后根据decide方法决定请求是否有权限访问该资源。如果没有,就会报错
3.decide其实是遍历所属的AccessDecisionVoter来对请求进行投票,voter需要评估4个内容
    1)请求的上下文
    2)经过认证的凭证
    3)要试图访问的受保护资源
    4)系统的配置以及资源本身的配置
  voter会根据上面的评估可能的出三个结果
    1)ACCESS_GRANTED        通过
    2)ACCESS_DENIED        拒绝
    3)ACCESS_ABSTRAIN        弃权
SpringSecurity学习(一)
AccessDecisionManager和Voter
1)默认的AccessDecisionManager和Voter是:AffirnativeBased和roleVoter
2)AccessDecisionManager的配置
beans.xml
<bean id="unanimousBased" class="org.springframework.security.access.vote.UnanimousBased">
    <property name="decisionVoter">
        <list>
            <ref name="roleVoter">
            <ref name="anthenticatedVoter">
        </list>
    </property>
</bean>
<bean id="roleVoter" class="org.springframework.security.access.voter.RoleVoter"/>
<bean id="anthenticatedVoter" class="org.springframework.security.access.vote.anthenticatedVoter"/>

springSecurity.xml
<http auto-config="true" access-desicion-manager-ref="unanimousBased"/>
================================================================================================================================
SpEL(SpringExpressionLanguage)(WebExpressionVoter)
1)SpringSecurity默认打开use-expressions。而user-expressions生效会让roleVoter失效
2)运行流程:
                1.选中WebExpressionVoter
                2.使用WebSecurityExpressionHandler解析资源对应的access的spEL,获取对应的授权方法名
                3.调用WebSecurityExpressionRoot中对应spEL解析出的方法名,返回Boolean值
                4.Voter根据Boolean值来返回授权结果
3)伪属性在springSecurity中的体现
WebExpressionRoot类中的hasXXX,isXXX,getXXX中的方法并不是类中的属性,而是从anthentication中提取出来的属性。

4)常用授权方法
表达式                        功能描述
hasIpAddress(ipAddress)        用于匹配一个请求的IP地址
hasRole(role)                用于匹配一个使用GrantedAuthority的角色
hasAnyRole(role1,role2...)    用于匹配一个使用GrantedAuthority的角色。用户匹配其中的任何一个均可放行
permitAll                    任何用户均可访问
denyAll                        任何用户均不可访问
anonymous                    匿名用户可访问
authenticated                检查用户是否认真过
rememberMe                    检查用户是否通过remember me 功能认证
fullyAuthenticated            检查用户是否通过提供完整的凭证信息来认证

SpringSecurity学习(一)