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

Spring Security 的 Web 应用和指纹登录实践(2)

Spring Security 的 Web 应用和指纹登录实践(2)

Spring                                Security 在 Web 中的设计Spring Security 的一个常见应用场景就是 Web。下面讨论 Spring Security 在 Web 中的使用方式。
Spring                                Security 最简登录实例Spring Security 在 Web 中的使用相对要复杂一点,会涉及到很多组件。现在给出自定义登录的伪代码,如清单 6 所示。您可以 ,查看完整的代码。
清单 6. Web                                登录伪代码
1
2
3
4
5
6
7
8
9
10
11
12
@Controller
public class UserController {

       @PostMapping(“/login”)
       public void login(String name, String password){
              matchNameAndPassword(name, password);
              User user = getUser(name);
              Authentication auth = new CustomAuthentication(user, password);
              auth.setAuthenticated(true);
              SecurityContextHolder.getContext.setAuthentication(auth);
       }
}




观察代码会发现,如果用 Spring Security 来集成已存在的登录逻辑,真正和 Spring Security 关联的代码只有短短 3                                行。验证逻辑可以不经过 AuthenticationManager,真正需要做的就是把经过验证的用户信息注入到                                Authentication 中,并将 Authentication 填充到 SecurityContext                                中。在实际情况中,登录逻辑的确可以这样写,尤其是已经存在登录逻辑的时候,通常会这样写。这样写虽然方便,但是不符合 Spring                                Security 在 Web 中的架构设计。
下面视频中会介绍已存在的项目如何与 Spring Security 进行集成,要求对已存在的登录验证逻辑不变,但可以使用 Spring Security 的优秀特性和功能。


Spring Security 在 Web 中的核心组件下面介绍在 Web 环境中 Spring Security 的核心组件。
FilterChainProxyFilterChaniProxy 是 FilterChain 代理。FilterChain 维护了一个 Filter 队列,这些 Filter 为                                Spring Security 提供了强大的功能。一个很常见的问题是:Spring Security 在 Web 中的入口是哪里?答案是                                Filter。Spring Security 在 Filter 中创建 Authentication 对象,并调用                                AuthenticationManager 进行校验。Spring Security 选择 Filter,而没有采用上文中                                Controller 的方式有以下优点。Spring Security 依赖 J2EE 标准,无需依赖特定的 MVC 框架。另一方面                                Spring MVC 通过 Servlet 做请求转发,如果 Spring Security 采用 Servlet,那么 Spring                                Security 和 Spring MVC 的集成会存在问题。FilterChain 维护了很多 Filter,每个 Filter                                都有自己的功能,因此在 Spring Security 中添加新功能时,推荐通过 Filter 的方式来实现。
ProviderManagerProviderManager 是 AuthenticationManager 的实现类。ProviderManager 并没有实现对                                Authentication 的校验功能,而是采用代理模式将校验功能交给 AuthenticationProvider                                去实现。这样设计是因为在 Web                                环境中可能会支持多种不同的验证方式,比如用户名密码登录、短信登录、指纹登录等等,如果每种验证方式的代码都写在                                ProviderManager 中,想想都是灾难。因此为每种验证方式提供对应的                                AuthenticationProvider,ProviderManager 将验证任务代理给对应的                                AuthenticationProvider,这是一种不错的解决方案。在 ProviderManager 中可以找到以下代码,如清单 7                                所示:
清单 7.                                        ProviderManager                                代码片段
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private List<AuthenticationProvider> providers;
public Authentication authenticate(Authentication authentication)
                      throws AuthenticationException {
       ......
       for (AuthenticationProvider provider : getProviders()) {
              if (!provider.supports(toTest)) {
                      continue;
              }
              try {
                      result = provider.authenticate(authentication);
                      if (result != null) {
                             copyDetails(authentication, result);
                             break;
                      }
              }
       }
}




ProviderManager 维护了一个 AuthenticationProvider 队列。当 Authentication                                传递进来时,ProviderManager 通过 supports 函数查找支持校验的                                AuthenticationProvider。如果没有找到支持的 AuthenticationProvider 将抛出                                        ProviderNotFoundException 异常。
AuthenticationProviderAuthenticationProvider 是在 Web 环境中真正对 Authentication 进行校验的组件。其接口签名如清单 8                                所示:
清单 8.                                        AuthenticationProvider                                的接口签名
1
2
3
4
5
public interface AuthenticationProvider {
       Authentication authenticate(Authentication authentication)
                      throws AuthenticationException;
       boolean supports(Class<?> authentication);
}




其中,authenticate 函数用于校验 Authentication 对象;supports 函数用于判断 provider 是否支持校验                                Authentication 对象。
当应用添加新的验证方式时,验证逻辑需要写在对应 AuthenticationProvider 中的 authenticate                                函数中。验证通过返回一个重新注入的 Authentication,验证失败抛出                                        AuthenticationException 异常。
返回列表