Spring Security验证流程剖析及自定义验证方法

时间:2022-09-22 20:36:16

spring security的本质

spring security 本质上是一连串的 filter , 然后又以一个独立的 filter 的形式插入到 filter chain 里,其名为 filterchainproxy 。 如图所示。

Spring Security验证流程剖析及自定义验证方法

实际上 filterchainproxy 下面可以有多条 filter chain ,来针对不同的url做验证,而 filter chain 中所拥有的 filter 则会根据定义的服务自动增减。所以无需要显示再定义这些 filter ,除非想要实现自己的逻辑。

Spring Security验证流程剖析及自定义验证方法

关键类

authentication

authentication 是一个接口,用来表示用户认证信息,在用户登录认证之前相关信息会封装为一个 authentication 具体实现类的对象,在登录认证成功之后又会生成一个信息更全面,包含用户权限等信息的 authentication 对象,然后把它保存在 securitycontextholder 所持有的 securitycontext 中,供后续的程序进行调用,如访问权限的鉴定等。

authenticationmanager

用来做验证的最主要的接口为 authenticationmanager ,这个接口只有一个方法:

?
1
2
3
4
public interface authenticationmanager {
 authentication authenticate(authentication authentication)
 throws authenticationexception;
}

其中 authenticate() 方法运行后可能会有三种情况:

验证成功,返回一个带有用户信息的 authentication 。

验证失败,抛出一个 authenticationexception 异常。

无法判断,返回 null 。

providermanager

providermanager 是上面的 authenticationmanager 最常见的实现,它不自己处理验证,而是将验证委托给其所配置的 authenticationprovider 列表,然后会依次调用每一个 authenticationprovider 进行认证,这个过程中只要有一个 authenticationprovider 验证成功,就不会再继续做更多验证,会直接以该认证结果作为 providermanager 的认证结果。

Spring Security验证流程剖析及自定义验证方法

认证过程

用户使用用户名和密码进行登录。

spring security 将获取到的用户名和密码封装成一个 authentication 接口的实现类,比如常用的 usernamepasswordauthenticationtoken 。

将上述产生的 authentication 对象传递给 authenticationmanager 的实现类 providermanager 进行认证。

providermanager 依次调用各个 authenticationprovider 进行认证,认证成功后返回一个封装了用户权限等信息的 authentication 对象。

将 authenticationmanager 返回的 authentication 对象赋予给当前的 securitycontext 。

自定义验证

有了以上的知识储备后就可以来自定义验证方法了。通过上面可以看出,实际上真正来做验证操作的是一个个的 authenticationprovider ,所以如果要自定义验证方法,只需要实现一个自己的 authenticationprovider 然后再将其添加进 providermanager 里就行了。

自定义authenticationprovider

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@component
public class customauthenticationprovider
 implements authenticationprovider {
 @override
 public authentication authenticate(authentication authentication)
 throws authenticationexception {
 string name = authentication.getname();
 string password = authentication.getcredentials().tostring();
 if (shouldauthenticateagainstthirdpartysystem()) {
  // use the credentials
  // and authenticate against the third-party system
  return new usernamepasswordauthenticationtoken(
  name, password, new arraylist<>());
 } else {
  return null;
 }
 }
 @override
 public boolean supports(class<?> authentication) {
 return authentication.equals(
  usernamepasswordauthenticationtoken.class);
 }
}

其中的 supports() 方法接受一个 authentication 参数,用来判断传进来的 authentication 是不是该 authenticationprovider 能够处理的类型。

注册authenticationprovider

现在再将刚创建的 authenticationprovider 在 与providermanager 里注册,所有操作就完成了。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@configuration
@enablewebsecurity
@componentscan("org.baeldung.security")
public class securityconfig extends websecurityconfigureradapter {
 @autowired
 private customauthenticationprovider authprovider;
 @override
 protected void configure(
 authenticationmanagerbuilder auth) throws exception {
 auth.authenticationprovider(authprovider);
 }
 @override
 protected void configure(httpsecurity http) throws exception {
 http.authorizerequests().anyrequest().authenticated()
  .and()
  .httpbasic();
 }
}

总结

以上所述是小编给大家介绍的spring security验证流程剖析及自定义验证方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!

原文链接:http://www.cnblogs.com/xz816111/p/8528896.html