Spring Security 入门(一)

 接触Spring Security是因为在面试之前,面试官要我用Spring Boot+Spring Security实现用户登录校验的功能。在此之前接触过一些Spring Boot,对Spring Security则完全没有了解,只知道它是一个权限管理的框架。也好,借此机会写些文章记录下了解和使用Spring Security的过程。

  Spring Security是一套验证授权框架。Spring Security最重要的两个功能也就是验证(authentication)和授权(authorization)。搭建网站过程中以下需求十分常见:

  1. 网站分为首页、登录页、用户页面、管理员页面和报错页面;
  2. 首页和登录页访问无需权限;
  3. 进入用户页面需要USER权限,进入管理员页面需要ADMIN权限;
  4. 登录时需要用户名加密码,用户名或密码有错误时需要报错;
  5. 若用户未登录想直接访问首页或登录页以外的页面,则需要跳转登录页面进行登录。 

  不用Spring Security框架,常见的做法是先利用Filter拦截需要权限的页面,通过Session判断用户是否登录且拥有对应权限,若已登录且有权限就进行过滤,未登录或者没有权限则拦截、跳转登录页面,提示相关信息。我们知道要访问某个页面或者进行某个操作时,需要满足已登录和有权限两个条件,这就是Spring Security框架核心的两个功能:验证和授权。

  验证(authentication):指的是建立系统使用者信息( principal )的过程,使用者可以是一个设备、用户等;

  授权(authorization):指的是判断某个 principal 在我们的应用是否允许执行某个操作。在进行授权判断之前,要求所要使用到的规则必须在验证过程中已经建立好。

  一个标准的验证场景:

  1. 一个用户被提示使用用户名和密码登录;
  2. 系统成功的验证了用户名与密码是匹配的;
  3. 获取用户的上下文信息;
  4. 建立这个用户的安全上下文(security context );
  5. 当用户进行受访问控制机制保护的操作时,访问控制机制会依据当前安全上下文信息检查这个操作所需的权限。  

  接下来说说,Spring Security是如何实现这些流程的,主要是流程,不怎么涉及源码,源码太多看了我也晕啊!  

  首先是容器启动时通过SecurityMetadataSource (自定义拦截器中的属性)中的loadResourceDefine方法加载系统资源与权限列表resourceMap(一个Map结构,资源[url]为key,权限[auth]为value )。

  其次是WEB服务器启动,加载security内置的拦截器链:

  1. SecurityContextPersistenceFilter
  2. WebAsyncManagerIntegrationFilter
  3. HeaderWriterFilter
  4. CsrfFilter
  5. LogoutFilter
  6. UsernamePasswordAuthenticationFilter
  7. DefaultLoginPageGeneratingFilter
  8. BasicAuthenticationFilter
  9. RequestCacheAwareFilter
  10. SecurityContextHolderAwareRequestFilter
  11. AnonymousAuthenticationFilter
  12. SessionManagementFilter
  13. ExceptionTranslationFilter
  14. FilterSecurityInterceptor

  当然,我们需要自定义一个拦截器配置具体的要拦截信息,并指定它在拦截器链中生效的位置。这就是Spring Security中四个重要的类:

  AbstractSecurityInterceptor :继承此类定义一个拦截器,这个拦截器会加载在FILTER_SECURITY_INTERCEPTOR之前。

  AuthenticationManager:读取登录用户信息、权限。

  SecurityMetadataSource :加载资源与权限的全部对应关系的,并提供一个通过资源获取所有权限的方法。

  AccessDecisionManager:授权器,通过登录用户的权限信息、资源、获取资源所需的权限来根据不同的授权策略来判断用户是否有权限访问资源。

  在网上找的一个自定义拦截器的例子:

/**
 * 该拦截器用以添加资源拦截
 *
 * 添加一个拦截器,配置在 FILTER_SECURITY_INTERCEPTOR之前
 * 继承本来最后的 AbstractSecurityInterceptor以实现 登录过程
 *
 *
 * 过滤器依赖于 SecurityContext 和 Authentication 对象,来进行辨别用户的 GrantedAuthority。
 * 所以,我们要将这个过滤器的位置放在 FilterSecurityInterceptor 之前
 *
 */
public class AppFilterSecurityInterceptor extends AbstractSecurityInterceptor
        implements Filter {

    private FilterInvocationSecurityMetadataSource securityMetadataSource;
    //拦截器入口
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        FilterInvocation fi = new FilterInvocation(request, response, chain);
        invoke(fi);
    }
    /**
     * fi里面有一个被拦截的url
     * 调用MyInvocationSecurityMetadataSource的getAttributes(Object object)
     * 这个方法获取fi对应的所有权限
     * 再调用MyAccessDecisionManager的decide方法来校验用户的权限是否足够
     */
    public void invoke(FilterInvocation fi) throws IOException,
            ServletException {
        InterceptorStatusToken token = super.beforeInvocation(fi);
        try {
            // 执行下一个拦截器
            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
        } finally {
            super.afterInvocation(token, null);
        }
    }

    //实现接口的方法

    public Class<? extends Object> getSecureObjectClass() {
        return FilterInvocation.class;
    }

    public SecurityMetadataSource obtainSecurityMetadataSource() {
        return this.securityMetadataSource;
    }

    public void destroy() {

    }

    public void init(FilterConfig arg0) throws ServletException {

    }

    //用以注入securityMetadataSource
    public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
        return this.securityMetadataSource;
    }

    public void setSecurityMetadataSource(
            FilterInvocationSecurityMetadataSource newSource) {
        this.securityMetadataSource = newSource;  }

定义好拦截器之后,在xml文件中进行配置:

1.配置spring security的配置文件securityConfig.xml

<!--忽略http的其他配置,此处只用于说明如何配置Filter->
<http auto-config="true" use-expressions="true" >
    <custom-filter ref="appFilter" before="FILTER_SECURITY_INTERCEPTOR" />
</http>
<!--一个自定义的filter,必须包含 authenticationManager,accessDecisionManager,securityMetadataSource三个属性-->
<beans:bean id="appFilter"
    class="security.filter.AppFilterSecurityInterceptor">
    <beans:property name="authenticationManager" ref="appAuthenticationManager" />
    <beans:property name="accessDecisionManager" ref="appAccessDecisionManagerBean" />
    <beans:property name="securityMetadataSource" ref="appSecurityMetadataSource" />
</beans:bean><!--在java文件中对authenticationManager,accessDecisionManager,securityMetadataSource接口进行扩展,在xml文件中进行配置--><!--资源源数据定义,将所有的资源和权限对应关系建立起来,即定义某一资源可以被哪些角色访问--> 
<beans:bean id="appSecurityMetadataSource" class="security.filter.properties.AppInvocationSecurityMetadataSource" > <beans:constructor-arg name="resourcesDao" ref="securityResourcesDao"/> </beans:bean> <!--访问决策器,决定某个用户具有的角色,是否有足够的权限去访问某个资源 --> <beans:bean id="appAccessDecisionManagerBean" class="security.filter.properties.AppAccessDecisionManager"> </beans:bean> <!--在这个类中,你就可以从数据库中读入用户的密码,角色信息,是否锁定,账号是否过期等 --> <beans:bean id="appUserDetailService" class="security.service.impl.AppUserDetailService" />

2.web.xml文件中的配置

<?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">
     <!--加载Spring XML配置文件 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value> classpath:securityConfig.xml           </param-value>
    </context-param>
      <!-- Spring Secutiry3.1的过滤器链配置 -->
    <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>
       <!-- Spring 容器启动监听器 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
      <!--系统欢迎页面 -->
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>  

这是Spring Security与Spring的集成,与Spring Boot的集成当然更简便些,后面会写。

原文地址:https://www.cnblogs.com/linyukun/p/9862720.html

时间: 2024-11-05 00:11:42

Spring Security 入门(一)的相关文章

Spring Security入门

Spring Security入门: http://www.mossle.com/docs/auth/html/index.html Spring Security 默认的过滤器链 https://blog.csdn.net/u013421749/article/details/78626275 原文地址:https://www.cnblogs.com/aligege/p/9396278.html

Spring Security 入门(三)

在说完了Spring Security框架的功能和执行流程后,就到了写它Spring Boot的集成,先来看最简的配置: <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.6.RELEASE</version> </parent>

Spring Security 入门(二)

Spring Security 入门(一)中说到,Spring Security执行流程第一步是容器启动时加载系统资源与权限列表,第二步是WEB容器启动时加载拦截器链,并介绍了自定义拦截器的方法.接下来第三步步就是用户登录.介绍下用户登录的流程: 获取用户名和密码,并放入一个 UsernamePasswordAuthenticationToken 实例中(Authentication接口的一个实例); 这个token被传递到一个 AuthenticationManager 实例中进行验证; 若验

Spring Security 入门(1-3)Spring Security oauth2.0 指南

入门 这是支持OAuth2.0的用户指南.对于OAuth1.0,一切都是不同的,所以看它的用户指南. 本用户指南分为两个部分,第一部分是OAuth2.0提供端(OAuth 2.0 Provider),第二部分是OAuth2.0的客户端(OAuth 2.0 Client) OAuth2.0提供端 OAuth2.0的提供端的用途是负责将受保护的资源暴露出去.建立一个可以访问受保护的资源的客户端列表. 提供端是通过管理和验证可用于访问受保护的资源的OAuth 2令牌来做的. 在适当的地方,提供端必须为

Spring Security 入门原理及实战

参考博客: https://www.cnblogs.com/demingblog/p/10874753.html Spring Security 是spring项目之中的一个安全模块,可以非常方便与spring项目无缝集成. 特别是在spring boot项目中加入spring security更是十分简单, 这里就简单介绍一下入门案例和使用原理吧! 写一个简单的springboot测试例子: @Controller public class AppController { @RequestMa

Spring Security 入门(一)

当你看到这篇文章时,我猜你肯定是碰到令人苦恼的问题了,我希望本文能让你有所收获. 本人几个月前还是 Spring 小白,几个月走来,看了 Spring,Spring boot,到这次的 Spring Security. 为了避免大家踩坑,本人将入门的经验传授给那些和我一样正在学习 Spring Security 的小白. 我们从官方例子学习起: 1.我们先来创建一个 Spring Boot 的项目 HelloWorld: 我用的开发工具是 eclipse,如果没装 STS 的话,请点击 Help

Spring Security入门Demo

一.spring Security简介 SpringSecurity,这是一种基于Spring AOP和Servlet过滤器的安全框架.它提供全面的安全性解决方案,同时在Web请求级和方法调用级处理身份确认和授权.在Spring Framework基础上,Spring Security充分利用了依赖注入(DI,Dependency Injection)和面向切面技术. 二.建立工程 参考http://blog.csdn.net/haishu_zheng/article/details/51490

Spring Security 入门(1-14)Spring Security 开发指南(转)

开发指南:http://www.cnblogs.com/xingxueliao/p/5911292.html Spring OAuth2.0 提供者实现原理: Spring OAuth2.0提供者实际上分为: 授权服务 Authorization Service. 资源服务 Resource Service. 虽然这两个提供者有时候可能存在同一个应用程序中,但在Spring Security OAuth中你可以把 他它们各自放在不同的应用上,而且你可以有多个资源服务,它们共享同一个中央授权服 务

Spring Security 入门详解

序:本文主要参考 spring实战 对里面的知识做一个梳理 1.Spring Security介绍 Spring Security是基于spring的应用程序提供声明式安全保护的安全性框架,它提供了完整的安全性解决方案,能够在web请求级别和方法调用级别处理身份证验证和授权.它充分使用了依赖注入和面向切面的技术. Spring security主要是从两个方面解决安全性问题: web请求级别:使用servlet过滤器保护web请求并限制URL级别的访问 方法调用级别:使用Spring AOP保护

spring security入门教程 demo注解

http://www.mossle.com/docs/springsecurity3/html/ns-config.html#ns-minimal 这是3.0的中文文档,写的比较详细,还有<spring in action>最新版也有一章专门是讲这个的.在学习的过程下载了spring security的github上面的demo,其中tutorial-xml是最简单的demo了.在源码里我把里面的一些重要的地方都详细注解了,做个备忘. ps:demo的logout似乎不能用,有bug. 链接: