Acegi framework introduced

    Outline
    For any complete application system, improve the authentication and authorization mechanisms are essential. Acegi Security (hereinafter referred to as Acegi) is able to provide a powerful and flexible secure access to enterprise applications for the Spring-based control solutions framework, Acegi Spring has become an official sub-project, it is also known as Spring Security. It By configuring a set Bean Spring container, and full use of the Spring IoC AOP function providing function declarative security access control. Although it can also be applied to non-Acegi Spring applications, but using Acegi Spring is in the most natural way.
Acegi can implement secure access to the business object method level granularity of control, which provides security for the following applications in three areas:

? URL access control to resources
    such as all users (including users) can access the login page index.jsp, and only authorized users can access /user/addUser.jsp page. Acegi allows regular expressions or Ant-style path expression defined URL patterns, allowing authorized users to access the corresponding URL resource at a URL pattern matching.

? Access to business class method of control
    methods all Bean Spring container can be Acegi management, such as all users can call BbtForum # getRefinedTopicCount () method, and that only authorized users can call BbtForum # addTopic () method.

? Domain object access control
    Business class method represents a specific business operations, such as change, delete, and other approvals, business class access control method to solve if the user has permission to invoke some operations, but not to objects (domain object) operation control. For our forums applications, users can call BbtForum # updateUser (User user) method to change the user registration information, but should be limited to change your user information, that call BbtForum # updateUser () User objects in this area must be operated It is limited.

    Acegi via Servlet filters for a number of different uses of URL resources protection, before requesting a protected resource URL, Acegi of Servlet filters to determine whether the user is authorized to access the target resources, open access is authorized, but not unauthorized It will be blocked outside the gate.
    Acegi intercepts vessel Bean controlled way through Spring AOP, when the user requests call triggered a controlled method of Bean, Acegi's interceptor method to work, to prevent unauthorized persons to call. 
    
    Access to domain objects control method is based on the protection of the Bean, Bean before the final goal of an open method of execution, Acegi checks the user's ACL (Aeccess Control List: Access Control List) contains the domain objects about to operate only when authorized domain object, user domain object can only be processed using a method Bean. Further, Acegi can also filter the results Bean method returns, the object is not within the areas of the current user access range of weed out - i.e., the visual field range of a conventional control data. In general, the use of non-visible region control data Acegi non-ideal choice, by contrast tend to be more simple conventional dynamic SQL solution.

    In essence characteristic is, Servlet Filter is the most primitive of the original ecological AOP, so we can say Acegi not only for business class methods, object access field control using the AOP technology solutions for the URL Resource Access Control also uses the AOP technology Program. AOP framework using technology program is exciting, which means that developers can function in the application business development is completed easily by the application Acegi to wear safety protection "cocoon."

    Acegi architecture
    needs through security, passengers must provide identification before flying to verify its identity. After entering the departure lounge through security, Air China, Hainan Airlines, China Southern Airlines and other aircraft of different airlines arriving, but you can only board the flight on the ticket corresponding to the aircraft. After boarding, can only sit on the ticket corresponding seat - you can not grab other people's seat, you can not be taken lettering on the seat, you can not ask a flight attendant open the window ......

    flew process can best embody the security controls process, we can find authentication, resource access control, security control of the domain object counterpart: the corresponding security authentication, check the corresponding resource access control and press the corresponding number is seated object security control.
    Acegi complete safety by the above object processing two components: the AuthenticationManager (authentication manager), the AccessDecisionManager (Access Control Manager) shown in Figure 1:


1 Acegi Architecture FIG.

    SecurityContextHolder permission information is framework-level container that holds all user association and SecurityContext instance, SecurityContext carries user (also known as certification body) identity information, AuthenticationManager, AccessDecisionManager will accordingly secure access control.
   
    Information security certification body SecurityContext between multiple calls to a HTTP request thread is shared (via ThreadLocal), but it can not remain shared between multiple requests. To solve this problem, Acegi authentication cache security information subject to the HttpSession, when a user requests a restricted resource, Acegi authentication by HttpSessionContextIntegrationFilter subject information is loaded from the HttpSession to SecurityContext example, associated certification body SecurityContext instance stored in Acegi container level of the SecurityContextHolder. When the end request, performs the reverse operation of HttpSessionContextIntegrationFilter, authentication security information SecurityContext body in the HttpSession re-dump, and then clear the corresponding instance SecurityContext from the SecurityContextHolder. HttpSession dump mechanism by the user's security information can be shared among a plurality of HTTP requests, while ensuring that only the current stored in SecurityContextHolder useful user security information, the overall process is shown in Figure 2:


FIG 2 SecurityContext transmitted between the process and the requesting thread HttpSession


    When a user requests a restricted resource, AuthenticationManager first started working, it is like a security entrance, the user identity verification, the user must provide authentication credentials (usually a username / password). During authentication, AuthenticationManager the identity of the work entrusted to more AuthenticationProvider. Because in a specific system, the user identity may be different users of information security systems (such as databases, CA center, LDAP server), different user information security systems require different AuthenticationProvider perform functions such as user information query, the user identity of the judge, user storage authorized access to information and so on. As long as there is a AuthenticationProvider can identify the user's identity, AuthenticationManager it through user authentication and user authorization information placed into the SecurityContext.

   When the user through the authentication, the program tries to access a restricted resource, AccessDecisionManager work. AccessDecisionManager adopt democratic decision-making mechanism to determine whether the user has access to the target program resources, which includes more than AccessDecisionVoter. When the access decision AccessDecisionVoter each have the right to vote, AccessDecisionManager statistical voting results and decide whether to end-user open access to these restricted resources in accordance with the voting results in some decision-making.

    Describes an important component class
    have some core concepts of each frame, these concepts are cured classes and interfaces, an important component class of the frame. Management framework, action class are operated on the basis of the classes of these components. Before entering the Acegi framework of specific learning, it is necessary to know in advance how these components class carries important concepts Acegi framework.
    First, we want the contact is UserDetails interface that represents the user of an application system, the interface defines the user security-related information, such as username / password, the user is valid and other information, you can be relevant information in accordance with the following interface methods to obtain :
    String getUsername (): obtain a user name; 
     String getPassword (): Gets the password; 
     boolean isAccountNonExpired (): user account has expired; 
     boolean isAccountNonLocked (): user account is locked; 
     boolean isCredentialsNonExpired (): user credentials are expired; 
     boolean isEnabled (): whether the user is active.
    When any of the above methods of determining the user state returns false, the user is considered invalid credentials.
    UserDetails also defines a method for obtaining authority information of the user: GrantedAuthority [] getAuthorities (), GrantedAuthority behalf of the user rights information that defines a description acquiring rights (as a string, such as PRIV_COMMON) method: String getAuthority ().


3 users and permissions

    在未使用Acegi之前,我们可能通过类似User、Customer等领域对象表示用户的概念,并在程序中编写相应的用户认证的逻辑。现在,你要做的一 个调整是让原先这些代表用户概念的领域类实现UserDetails接口,这样,Acegi就可以通过UserDetails接口访问到用户的信息了。 

    UserDetails可能从数据库、LDAP等用户信息资源中返回,这要求有一种机制来完成这项工作,UserDetailsService正是充当这 一角色的接口。UserDetailsService接口很简单,仅有一个方法:UserDetails loadUserByUsername(String username) ,这个方法通过用户名获取整个UserDetails对象。
Authentication 代表一个和应用程序交互的待认证用户,Acegi从类似于登录页面、Cookie等处获取待认证的用户信息(一般是用户名密码)自动构造 Authentication实例。


图 4 Acegi的认证用户

    Authentication可以通过Object getPrincipal()获取一个代表用户的对象,这个对象一般可以转换为UserDetails,从中可以取得用户名/密码等信息。在 Authentication被AuthenticationManager认证之前,没有任何权限的信息。在通过认证之后,Acegi通过 UserDetails将用户对应的权限信息加载到Authentication中。Authentication拥有一个 GrantedAuthority[] getAuthorities()方法,通过该方法可以得到用户对应的权限信息。
    Authentication和UserDetails很容易被混淆,因为两者都有用户名/密码及权限的信息,接口方法也很类似。其实 Authentication是Acegi进行安全访问控制真正使用的用户安全信息的对象,它拥有两个状态:未认证和已认证。UserDetails是代 表一个从用户安全信息源(数据库、LDAP服务器、CA中心)返回的真正用户,Acegi需要将未认证的Authentication和代表真实用户的 UserDetails进行匹配比较,通过匹配比较(简单的情况下是用户名/密码是否一致)后,Acegi将UserDetails中的其它安全信息(如 权限、ACL等)拷贝到Authentication中。这样,Acegi安全控制组件在后续的安全访问控制中只和Authentication进行交 互。

    由于Acegi对程序资源进行访问安全控制时,一定要事先获取和请求用户对应的Authentication,Acegi框架必须为 Authentication提供一个“寓所”,以便在需要时直接从“寓所”把它请出来,作为各种安全管理器决策的依据。

    SecurityContextHolder就是Authentication容身的“寓所”,你可以通过 SecurityContextHolder.getContext().getAuthenication()代码获取Authentication。 细心观察一下这句代码,你会发现在SecurityContextHolder和Authentication之间存在一个getContext()中 介,这个方法返回SecurityContext对象。SecurityContext这个半路杀出来的程咬金有什么特殊的用途呢?我们知道 Authentication是用户安全相关的信息,请求线程其它信息(如登录验证码等)则放置在SecurityContext中,构成了一个完整的安 全信息上下文。SecurityContext接口提供了获取和设置Authentication的方法:
 Authentication getAuthentication()
 void setAuthentication(Authentication authentication)


图 5 认证用户信息存储器

    SecurityContextHolder是Acegi框架级的对象,它在内部通过ThreadLocal为请求线程提供线程绑定的 SecurityContext对象。这样,任何参与当前请求线程的Acegi安全管理组件、业务服务对象等都可以直接通过 SecurityContextHolder.getContext()获取线程绑定的SecurityContext,避免通过方法入参的方式获取用户 相关的SecurityContext。

    线程绑定模式对于大多数应用来说是适合的,但是应用本身会创建其它的线程,那么只有主线程可以获得线程绑定SecurityContext,而主线程衍生 出的新线程则无法得到线程绑定的SecurityContext。Acegi考虑到了这些不同应用情况,提供了三种绑定SecurityContext的 模式:
 SecurityContextHolder.MODE_THREADLOCAL:SecurityContext绑定到主线程,这是默认的模式;
 SecurityContextHolder.MODE_GLOBAL:SecurityContext绑定到JVM中,所有线程都使用同一个 SecurityContext;
 SecurityContextHolder.MODE_INHERITABLETHREADLOCAL::SecurityContext绑定到主线程 及由主线程衍生的线程中。
    你可以通过SecurityContextHolder.setStrategyName(String strategyName)方法指定SecurityContext的绑定模式。

    用户认证过程
Acegi支持多种方式的用户认证:如典型的基于数据库的认证、基于LDAP的认 证、基于Yale中心认证等方式。不同的认证环境拥有不同的用户认证方式,现在我们先抛开这些具体的细节,考察一下Acegi对受限资源进行访问控制的典 型过程:
    1.你点击一个链接访问一个网页;
    2.浏览器发送一个请求到服务器,服务器判断出你正在访问一个受保护的资源;
    3.如果此时你并未通过身份认证,服务器发回一个响应提示你进行认证——这个响应可能是一个HTTP响应代码,抑或重定向到一个指定页面;
    4.根据系统使用认证机制的不同,浏览器或者重定向到一个登录页面中,或者由浏览器通过一些其它的方式获取你的身份信息(如通过BASIC认证对话框、一 个Cookie或一个X509证书);
    5.浏览器再次将用户身份信息发送到服务器上(可能是一个用户登录表单的HTTP POST信息、也可能是包含认证信息的HTTP报文头);
    6.服务器判断用户认证信息是否有效,如果无效,一般情况下,浏览器会要求你继续尝试,这意味着返回第3步。如果有效,则到达下一步;
    7.服务器重新响应第2步所提交的原始请求,并判断该请求所访问的程序资源是否在你的权限范围内,如果你有权访问,请求将得到正确的执行并返回结果。否 则,你将收到一个HTTP 403错误,这意味着你被禁止访问。
    在Acegi框架里,你可以找到对应以上大多数步骤的类,其中ExceptionTranslationFilter、 AuthenticationEntryPoint、AuthenticationProvider以及Acegi的认证机制是其中的代表者。

    ExceptionTranslationFilter是一个Acegi的Servlet过滤器,它负责探测抛出的安全异常。当一个未认证用户访问服务器 时,Acegi将引发一个Java异常。Java异常本身对HTTP请求以及如何认证用户是一无所知 的,ExceptionTranslationFilter适时登场,对这个异常进行处理,启动用户认证的步骤(第3步)。如果已认证用户越权访问一个资 源,Acegi也将引发一个Java异常,ExceptionTranslationFilter则将这个异常转换为HTTP 403响应码(第7步)。可见,Acegi通过异常进行通讯,
ExceptionTranslationFilter接收这些异常并作出相应的动 作。

    当ExceptionTranslationFilter通过Java异常发现用户还未认证时,它到底会将请求重定向哪个页面以要求用户提供认证信息呢? 这通过咨询AuthenticationEntryPoint来达到目的——Acegi通过AuthenticationEntryPoint描述登录页 面。

    当你的浏览器通过HTTP表单或HTTP报文头向服务器提供用户认证信息时,Acegi需要将这些信息收集到Authentication中,Acegi 用“认证机制”描述这一过程。此时,这个新生成Authentication只包含用户提供的认证信息,但并未通过认证。
AuthenticationProvider 负责对Authentication进行认证。AuthenticationProvider究竟如何完成这一过程呢?请回忆一下上节我们所介绍的 UserDetails和UserDetailsService,大多数AuthenticationProvider通过 UserDetailsService获取和未认证的Authentication对应的UserDetails并进行匹配比较来完成这一任务。当用户认 证信息匹配时,Authentication被认为是有效的,AuthenticationProvider进一步将UserDetails中权限、 ACL等信息拷贝到Authentication。
当Acegi通过认证机制收集到用户认证信息并填充好Authentication 后,Authentication将被保存到SecurityContextHolder中并处理用户的原始请求(第7步)。

    你完全可以抛开Acegi的安全机制,编写自己的Servlet过滤器,使用自己的方案构建Authentication对象并将其放置到 SecurityContextHolder中。也许你使用了CMA(Container
Managed Authentication:容器管理认证),CMA允许你从ThreadLocal或JNDI中获取用户认证信息,这时你只要获取这些信息并将其转换 为Authentication就可以了。

    安全对象访问控制
    Acegi称受保护的应用资源为“安全对象”,这包括URL资源和业务类方法。我们知道在Spring AOP中有前置增强、后置增强、异常增强和环绕增强,其中环绕增强的功能最为强大——它不但可以在目标方法被访问前拦截调用,还可以在调用返回前改变返回 的结果,甚至抛出异常。Acegi使用环绕增强对安全对象进行保护。
    Acegi通过AbstractSecurityInterceptor为安全对象访问提供一致的工作模型,它按照以下流程进行工作:
    1. 从SecurityContext中取出已经认证过的Authentication(包括权限信息);
    2. 通过反射机制,根据目标安全对象和“配置属性”得到访问目标安全对象所需的权限;
    3. AccessDecisionManager根据Authentication的授权信息和目标安全对象所需权限做出是否有权访问的判断。如果无权访 问,Acegi将抛出AccessDeniedException异常,否则到下一步;
4. 访问安全对象并获取结果(返回值或HTTP响应);
5. AbstractSecurityInterceptor可以在结果返回前进行处理:更改结果或抛出异常。     Acegi称受保护的应用资源为“安全对象”,这包括URL资源和业务类方法。我们知道在Spring AOP中有前置增强、后置增强、异常增强和环绕增强,其中环绕增强的功能最为强大——它不但可以在目标方法被访问前拦截调用,还可以在调用返回前改变返回 的结果,甚至抛出异常。Acegi使用环绕增强对安全对象进行保护。     Acegi通过AbstractSecurityInterceptor为安全对象访问提供一致的工作模型,它按照以下流程进行工作:     1. 从SecurityContext中取出已经认证过的Authentication(包括权限信息);     2. 通过反射机制,根据目标安全对象和“配置属性”得到访问目标安全对象所需的权限;     3. AccessDecisionManager根据Authentication的授权信息和目标安全对象所需权限做出是否有权访问的判断。如果无权访 问,Acegi将抛出AccessDeniedException异常,否则到下一步; 4. 访问安全对象并获取结果(返回值或HTTP响应); 5. AbstractSecurityInterceptor可以在结果返回前进行处理:更改结果或抛出异常。


图 6 AbstractSecurityInterceptor工作流程

    安全对象和一般对象的区别在于前者通过Acegi的“配置属性”进行了描述,如“/view.jsp=PRIV_COMMON”配置属性就将“ /view.jsp”这个URL资源标识为安全对象,它表示用户在访问/view.jsp时,必须拥有PRIV_COMMON这个权限。配置属性通过 XML配置文件,注解、数据库等方式提供。安全对象通过配置属性表示为一个权限,这样,Acegi就可以根据Authentication的权限信息获知 用户可以访问的哪些安全对象。
    根据安全对象的性质以及具体实现技术,AbstractSecurityInterceptor拥有以下三个实现类:
 FilterSecurityInterceptor:对URL资源的安全对象进行调用时,通过该拦截器实施环绕切面。该拦截器使用Servlet过滤器 实现AOP切面,它本身就是一个Servlet过滤器;
 MethodSecurityInterceptor:当调用业务类方法的安全对象时,可通过该拦截器类实施环绕切面;
 AspectJSecurityInterceptor:和MethodSecurityInterceptor类似,它是针对业务类方法的拦截器,只不 过它通过AspectJ实施AOP切面。

    Acegi版本升级的一些重大变化 
    Acegi项目开始于2003年,Acegi团队在发布新版本时非常谨慎,在本书写作之时,Acegi最新版本为1.0.3。在此之前Acegi已经发布 了10多个预览版本,由于Acegi框架优异的表现,许多大型应用早在Acegi 1.0正式版本发布之前(2006年5月),就已经采用Acegi框架作为其安全访问控制的解决方案。

    在Acegi社区里,来自世界各地众多优秀的安全领域专家对Acegi的改进和发展献计献策,Acegi团队广泛听取并吸收各种有益的建议,将它们融入到 Acegi的框架中,使Acegi成为构建在Spring基础上企业应用的首选安全控制框架。
Acegi 1.0.3版本相比于早期预览版本发生了很大的变化,对于需要进行Acegi版本的项目来说,了解这一变化特别重要。下面,我们列出Acegi的一些重大 的升级更新:
 包名的更新:在0.9.0及之前的版本中,Acegi采用net.sf.acegisecurity包名前缀,在1.0.0版本之后更改为 org.acegisecurity(Hibernate也走过相同的道路,好在Acegi在正式版本发布之时就完成了这种转变);

 ACL模块的调整:ACL模块发生了重大的调整,Acegi团队接收了社区大量关于ACL模块的反馈意见,重新设计了ACL模块的底层结构,在性能、封装 性、灵活性上得到了质的提升。事实上,Acegi使用org.acegisecurity.acls包代替了原来的 org.acegisecurity.acl包,后者将在后期的版本中删除,由于这种伤筋动骨的变化,将很难兼容原来ACL模块。不过,目前基于新框架的 ACL模块还没有进行充分的测试,Acegi承诺在1.1.0版本发布时提供最终的实现;

 删除了ContextHolder及其相关类:在Acegi 0.9版本中,ContextHolder及其相关类被彻底从Acegi项目中删除。ContextHolder可以在多个HTTP请求中共享同一个 ThreadLocal,这和Spring提倡的ThreadLocal只应在同一线程中共享相悖。现在,Acegi使用 SecurityContextHolder替换ContextHolder,它的生命周期是一个HTTP 请求;

 使用FilterChainProxy同时代理多个过滤器:在早期的版本中,Acegi通过FilterToBeanProxy将web.xml中的 Servlet过滤器定义转移到Spring容器中。这比直接在web.xml中配置Servlet过滤器要方便一些,但是Acegi框架往往需要定义多 个Servlet过滤器,使web.xml配置文件变得冗长难看。在Acegi 0.8版本中提供FilterChainProxy,它可以同时代理多个Servlet过滤器并保证过滤器的顺序。因此在新版本 中,FilterChainProxy成为推荐的选择。

    小结
    Acegi是Spring项目下一个成熟的安全访问控制框架,它允许利用了Spring IoC的AOP的功能完成安全对象的访问控制。在Acegi框架中,SecurityContextHolder处于非常核心的位置,它是存放认证管理器 用户安全信息SecurityContext的“容器”,SecurityContext保存着用户安全访问控制所需的信息,直接被访问决策管理器使用。 HttpSessionContextIntegrationFilter通过在SecurityContextHolder和HttpSession中 摆渡SecurityContext,使多个请求线程可以共享同一个SecurityContext。

Original Address: https: //www.oschina.net/question/12_8396

Guess you like

Origin www.cnblogs.com/jpfss/p/11022522.html