首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

使用 Spring Security 保护 Web 应用的安全(3)

使用 Spring Security 保护 Web 应用的安全(3)

SecurityContext 和 Authentication 对象下面开始讨论几个 Spring Security 里面的核心对象。org.springframework.security.core.context.SecurityContext接口表示的是当前应用的安全上下文。通过此接口可以获取和设置当前的认证对象。org.springframework.security.core.Authentication接口用来表示此认证对象。通过认证对象的方法可以判断当前用户是否已经通过认证,以及获取当前认证用户的相关信息,包括用户名、密码和权限等。要使用此认证对象,首先需要获取到 SecurityContext 对象。通过 org.springframework.security.core.context.SecurityContextHolder 类提供的静态方法 getContext() 就可以获取。再通过 SecurityContext对象的 getAuthentication()就可以得到认证对象。通过认证对象的 getPrincipal() 方法就可以获得当前的认证主体,通常是 UserDetails 接口的实现。联系到上一节介绍的 UserDetailsService,典型的认证过程就是当用户输入了用户名和密码之后,UserDetailsService通过用户名找到对应的 UserDetails 对象,接着比较密码是否匹配。如果不匹配,则返回出错信息;如果匹配的话,说明用户认证成功,就创建一个实现了 Authentication接口的对象,如 org.springframework.security. authentication.UsernamePasswordAuthenticationToken 类的对象。再通过 SecurityContext的 setAuthentication() 方法来设置此认证对象。
给出了使用 SecurityContext 和 Authentication的一个示例,用来获取当前认证用户的用户名。
清单 4. 获取当前认证用户的用户名
1
2
3
4
5
6
7
8
9
10
11
public static String getAuthenticatedUsername() {
   String username = null;
   Object principal = SecurityContextHolder.getContext()
       .getAuthentication().getPrincipal();
   if (principal instanceof UserDetails) {
       username = ((UserDetails) principal).getUsername();
   } else {
       username = principal.toString();
   }
   return username;
}




默认情况下,SecurityContextHolder使用 ThreadLocal来保存 SecurityContext对象。因此,SecurityContext对象对于当前线程上所有方法都是可见的。这种实现对于 Web 应用来说是合适的。不过在有些情况下,如桌面应用,这种实现方式就不适用了。Spring Security 允许开发人员对此进行定制。开发人员只需要实现接口 org.springframework.security.core.context.SecurityContextHolderStrategy并通过 SecurityContextHolder的 setStrategyName(String)方法让 Spring Security 使用此实现即可。另外一种设置方式是使用系统属性。除此之外,Spring Security 默认提供了另外两种实现方式:MODE_GLOBAL表示当前应用共享唯一的 SecurityContextHolder;MODE_INHERITABLETHREADLOCAL表示子线程继承父线程的 SecurityContextHolder。给出了使用全局唯一的 SecurityContextHolder的示例。
清单 5. 使用全局唯一的 SecurityContextHolder
1
2
3
public void useGlobalSecurityContextHolder() {
   SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_GLOBAL);
}




在介绍完 Spring Security 中的 SecurityContext和 Authentication之后,下面介绍如何保护服务层的方法。
返回列表