您的位置:首页 > 编程语言 > Java开发

说说 spring-secuirty

2017-06-03 00:38 197 查看
安全无处不在, 掌握其原理,深入了解其调用链。

在我们的日常开发中,我们都会接触到系统的 用户体系 , 系统的用户系统是一个产品的基石,在做用户体系的时候,我们往往会考虑使用一套安全框架,目前比较主流的安全框架有 spring-security 和shiro,个人更喜欢spring全家桶系列。

spring-security 的核心主要是围绕着 认证(Authentication)——身份验证 和 授权(Authorization)—— 访问控制 , 这两部分来进行。

架构与实现

一旦你熟悉了设置和运行一些基于命名空间配置的应用程序,你可能希望开发更多的框架去理解命名空间门面后面实际上是如何运转。类似大部分软件, Spring Security有一定的中央接口,以及通常在整个框架中使用的概念抽象类。在参考指南的这一部分,我们将看看其中的一些,看看它们如何协同工作去支持Spring Security中的身份验证和访问控制

技术概述

核心组件

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

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

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

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

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

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

UserDetailsService, 创建一个UserDetails,传递一个 String类型的用户名(或者证书ID或其他).

SecurityContextHolder, SecurityContext和Authentication 对象

最根本的对象是SecurityContextHolder。我们把当前应用程序的当前安全环境的细节存储到它里边了, 它也包含了应用当前使用的主体细节。

我们可以通过 SecurityContextHolder 来获取用户信息。

Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
String username = ((UserDetails)principal).getUsername();
} else {
String username = principal.toString();
}


通过调用getContext()返回的对象是SecurityContext接口的实例。这是保存在线程本地存储中的对象。我们将在下面看到,大多数的认证机制以Spring Security返回UserDetails实例为主。

The UserDetailsService

从上面的代码片段中还可以看出一件事,就是你可以从Authentication对象中获得安全主体。这个安全主体就是一个Object。大多数情况下,可以强制转换成UserDetails对象 。 UserDetails是一个Spring Security的核心接口。它代表一个主体,是扩展的,而且是为特定程序服务的。 想一下UserDetails章节,在你自己的用户数据库和如何把Spring Security需要的数据放到SecurityContextHolder里。为了让你自己的用户数据库起作用,我们常常把UserDetails转换成你系统提供的类,这样你就可以直接调用业务相关的方法了(比如 getEmail(), getEmployeeNumber()等等)。

现在,你可能想知道,我应该什么时候提供这个UserDetails对象呢?我怎么做呢?我想你说这个东西是声明式的,我不需要写任何代码,怎么办?简单的回答是,这里有一个特殊的接口叫UserDetailsService。这个接口里的唯一的一个方法,接收String类型的用户名参数,返回UserDetails:

UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;

这是Spring Security用户加载信息的最常用的方法并且每当需对用户的信息时你会看到它使用的整个框架。

成功认证后,UserDetails用于构建存储在SecurityContextHolder(详见 以下)的Authentication对象。好消息是,我们提供了一些UserDetailsService的实现,包括一个使用内存映射(InMemoryDaoImpl)而另一个使用JDBC(JdbcDaoImpl)。大多数用户倾向于写自己的,常常放到已有的数据访问对象(DAO)上使用这些实现,表示他们的雇员,客户或其他企业应用中的用户。记住这个优势,无论你用UserDetailsService返回的什么数据都可以通过SecurityContextHolder获得,就像上面的代码片段讲的一样。

关于UserDetailsService常常有一些混乱。它纯粹是用于用户数据的DAO并没有其它功能,除了提供该数据到其他组件的框架内。特别是,它不会对用户进行身份验证,这是由AuthenticationManager完成。在许多情况下,如果你需要自定义身份验证过程,直接实现 AuthenticationProvider更有意义 。

GrantedAuthority

除了主体,另一个Authentication提供的重要方法是getAuthorities()。这个方法提供了GrantedAuthority对象数组。毫无疑问,GrantedAuthority是赋予到主体的权限。这些权限通常使用角色表示,比如ROLE_ADMINISTRATOR或ROLE_HR_SUPERVISOR。这些角色会在后面,对web验证,方法验证和领域对象验证进行配置。Spring Security的其他部分用来拦截这些权限,期望他们被表现出现。GrantedAuthority对象通常是使用UserDetailsService读取的。

通常情况下,GrantedAuthority对象是应用程序范围下的授权。它们不会特意分配给一个特定的领域对象。因此,你不能设置一个GrantedAuthority,让他有权限展示编号54的Employee对象,因为如果有成千上万的这种授权,你会很快用光内存(或者,至少,导致程序花费大量时间去验证一个用户)。当然,Spring Security被明确设计成处理常见的需求,但是你最好别因为这个目的使用项目领域模型安全功能。

验证

Spring Security可以在很多不同的认证环境下使用。虽然我们推荐人们使用Spring Security,不与已存在的容器管理认证系统结合,但它也是支持的-使用你自己的属性验证系统进行整合。

参考:

https://www.springcloud.cc/spring-security-zhcn.html#overall-architecture
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring spring-security