spring_security_3.0.1中文参考文档PartII结构和实现

来源:互联网 发布:经济史专业知乎 编辑:程序博客网 时间:2024/06/02 09:49

PartII.结构和实现

chapter 5.技术概述

5.1 运行环境

5.2 核心组件

5.2.1 SecurityContextHolder,SecurityContext和Authentication对象

把当前应用程序的当前安全环境的细节存储到它里边了,它也包含了应用当前使用的主体细节。

5.2.1.1 获得当前用户的信息

把安全主体和系统交互的信息都保存在SecurityContextHolder中了。Spring Security使用一个Authentication对应来表现这些信息。

例子:获得已认证用户的名字:

<span style="font-size:18px;"><span style="font-size:18px;">Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();if (principal instanceof UserDetails) {String username = ((UserDetails)principal).getUsername();} else {String username = principal.toString();}</span></span>

调用getContext()返回的对象是一个SecurityContext提供的实例。

5.2.2 UserDetailsService

可以从Authentication对象中获得安全主体。这个安全主体就是一个对象。可以强制转换成UserDetails对象。

UserDetails是一个Spring Security的核心接口。它代表一个主体,是扩展的,而且是为特定程序服务的。

UserDetailsService有一个特殊的接口,有一个唯一的方法:

<span style="font-size:18px;">UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;</span>

5.2.3 GrantedAuthority

另一个Authentication提供的重要方法是getAuthorities()。这个方法提供了GrantedAuthority对象数组。

GrantedAuthority是赋予到主体的权限。这些权限通常使用角色表示,比如ROLE_ADMINISTRATOR。

5.2.4 小结

Spring Security主要由以下几个部分组成的:

1)SecurityContextHolder,提供几种访问SecurityContext的方式。

2)SecurityContext,保存Authentication信息,和请求对应的安全信息

3)HttpSessionContextIntegrationFilter,为了在不同请求使用,把SecurityContext保存到HttpSession里

4)Authentication,展示Spring Security特定的主体。

5)GrantedAuthority,反应在应用程序范围,你赋予主体的权限

6)UserDetails,通过你的应用DAO,提供必要的信息,构建Authentication对象

7)UserDetailsService,创建一个UserDetails,传递一个String类型的用户名

5.3 验证

5.3.1 什么是Spring Security的验证呢?

考验这种验证场景:

1)一个用户想使用一个账号和密码进行登录

2)系统(成功的)验证了密码对于这个用户名是正确的

3)这个用户对应的信息被获取(他们的角色列表以及等等)

4)为用户建立一个安全环境

5)用户会执行一些操作,这些都是潜在被权限控制机制所保护的,通过对操作的授权,使用当前的安全环境信息。

前三个项目执行了验证过程,我们可以看一下Spring Security的作用

1)用户名和密码被获得,并进行比对,在一个UsernamePasswordAuthenticationToken的实例中(它是Authentication接口的一个实例)。

2)这个标志被发送给一个AuthenticationManager的实例进行校验。

3)AuthenticationManager返回一个完全的Authentication实例,在成功校验后。

4)安全环境被建立,通过调用SecurityContextHolder.getContext().setAuthentication(...),传递到返回的验证对象中。

例子:

<span style="font-size:18px;">import org.springframework.security.authentication.*;import org.springframework.security.core.*;import org.springframework.security.core.authority.GrantedAuthorityImpl;import org.springframework.security.core.context.SecurityContextHolder;public class AuthenticationExample {private static AuthenticationManager am = new SampleAuthenticationManager();public static void main(String[] args) throws Exception {BufferedReader in = new BufferedReader(new InputStreamReader(System.in));while(true) {System.out.println("Please enter your username:");String name = in.readLine();System.out.println("Please enter your password:");String password = in.readLine();try {Authentication request = new UsernamePasswordAuthenticationToken(name, password);Authentication result = am.authenticate(request);SecurityContextHolder.getContext().setAuthentication(result);break;} catch(AuthenticationException e) {System.out.println("Authentication failed: " + e.getMessage());}}System.out.println("Successfully authenticated. Security context contains: " +SecurityContextHolder.getContext().getAuthentication());}}class SampleAuthenticationManager implements AuthenticationManager {static final List<GrantedAuthority> AUTHORITIES = new ArrayList<GrantedAuthority>();static {AUTHORITIES.add(new GrantedAuthorityImpl("ROLE_USER"));}public Authentication authenticate(Authentication auth) throws AuthenticationException {if (auth.getName().equals(auth.getCredentials())) {return new UsernamePasswordAuthenticationToken(auth.getName(),auth.getCredentials(), AUTHORITIES);}throw new BadCredentialsException("Bad Credentials");}}</span>
上述实现的AuthenticationManager会验证所有用户名和密码一样的用户,它为每个永固分配一个单独的角色。

5.3.2 直接设置SecurityContextHolder的内容

5.4 在web应用中验证

1. 你访问主页,点击链接。
2. 一个请求发送给服务器,服务器决定你是否在请求一个被保护的资源。
3. 如果你还没有授权,服务器发回一个相应,提示你必须登录。响应会是一个HTTP响应代码, 或重定向到特定的
web页面。
4. 基于验证机制,你的浏览器会重定向到特殊的web页面, 所以你可以填写表单,或者浏览器会验证你的身份 (通过
一个BASIC验证对话框,一个cookie,一个X.509 验证,等等)。
5. 浏览器会发送回一个响应到服务器。这会是一个HTTP POST 包含你填写的表单中的内容,或者一个HTTP头部包含
你的验证细节。
6. 下一步,服务器决定,当前证书是否有效。如果它们有效,下一步会执行。如果它们无效,通常你的浏览器会 被询
问再试一次(所以initial返回上两步)。
7. 你的原始请求会引发验证过程。希望你验证了获得了授予的权限来访问被保护的资源。 如果你完允许访问,请求会
成功。否则,你会收到一个HTTP错误代码403,意思是“拒绝访问”。

5.4.1 ExceptionTranslationFilter

ExceptionTranslationFilter是一个Spring Security 过滤器,负责检测任何一个Spring Security抛出的异常。

5.4.2 AuthenticationEntryPoint

每个主要的验证系统会I有它们自己的AuthenticationEntryPoint实现,典型的执行一个动作。描述在第三步。

5.4.3 验证机制

在验证机制获得完全的Authentication后,它会认为请求合法, 把Authentication放到 SecurityContextHolder里,然后让原始请
求重试(上面第七步)。如果,其他可能, AuthenticationManager拒绝了请求, 请求机制会让用户代理重试(上面第二
步)。

5.4.4 在请求之间保存SecurityContext

5.5 Spring Security中的访问控制(验证)

主要接口,负责访问控制的决定,在Spring Security中是AccessDecisionManager。它由一个decide方法,可以获得一个Authentication对象。展示主体的请求权限, 一个“secure object”(看下边)和一个安全元数据属性队列, 为对象提供了。

5.5.1 安全和AOP建议

5.5.2 安全对象和AbstractSecurityInterceptor

什么是“secure object”? Spring Security使用应用任何对象,可以被安全控制(比如一个验证决定)提供到它上
面。

Spring Security支持的每个安全对象类型都有它自己的类型,它们都是AbstractSecurityInterceptor的子类。

AbstractSecurityInterceptor提供了一套一致的工作流程,来处理对安全对象的请求,通常是:
1. 查找当前请求里分配的"配置属性"。
2. 把安全对象,当前的Authentication和配置属性,提交给AccessDecisionManager,来进行以此认证决定。
3. 有可能在调用的过程中,对Authentication 进行修改。
4. 允许安全对象进行处理(假设访问被允许了)。
5. 在调用返回的时候执行配置的AfterInvocationManager。

5.5.2.1  配置属性是什么

一个"配置属性"可以看做是一个字符串,它对于AbstractSecurityInterceptor使用的类是有特殊含义的。 它们通过框架中的
ConfigAttribute接口表现。

5.2.2 RunAsManager

假设AccessDecisionManager决定允许执行这个请求,AbstractSecurityInterceptor会正常执行这个请求。话虽如此,罕见情况
下,用户可能需要把SecurityContext的Authentication换成另一个Authentication,通过访问RunAsManager。

5.5.2.3 AfterInvocationManager

关键"secure object"模型


5.6 国际化

Spring Security支持异常信息的国际化

从spring-security-core-xx.jar中,你可以找到org.springframework.security包下,包含了一些 messages.properties文件,这应该引用
到你的ApplicationContext中,因为Spring Security的类都实现了spring的MessageSourceAware接口, 期待的信息处理器会
在application context启动的时候注入进来。通常所有你需要做的就是在你的application context中注册一个bean来引
用这些信息。下面是一个例子:

<bean id="messageSource"class="org.springframework.context.support.ReloadableResourceBundleMessageSource"><property name="basename" value="org/springframework/security/messages"/></bean>

0 0
原创粉丝点击