相信大家在开始时经常会分不清spring security和spring oauth2的区别,对于spring security都知道是鉴权,授权服务。而oauth2的提出是为了解决第三方软件登入时的授权问题,所以oauth2可以理解为资源授权服务。例如我们在打开王者荣耀游戏时,这时候系统会提醒我们使用qq还是微信登入,这时就是王者荣耀这个第三方软件申请qq或者微信的授权来登入对应的账号。
上面就是Oauth2中授权中最严谨的授权码模式流程,这篇文章主要是想分享一下客户端(也就是王者荣耀)在得到token后调用对应的资源服务器(也就是qq,微信平台)时,资源服务器是如何判断token的原理。
识别传入的是token,那qq平台上是需要根据这个token来找到对应的用户信息,这个重担应该在何时做呢?oauth给出的答案就是在请求时spring的过滤器中 *** 作。(啥是过滤器呢?在spring mvc请求时,可以再请求达到处理方法前做加强处理,具体过滤器的适用场景可以戳这篇)
过滤器在ouath2中需要对token进行判断,所用到的类是OAuth2AuthenticationProcessingFilter。要用到这个过滤器,就要将这个过滤器加载到spring的过滤器链中,那首先的问题就是oauth2是如何将这个过滤器加载进去的呢,以及过滤器是如何生成的呢?大家可以戳一下这篇文章。
看完文章后想必大家一定对过滤器有一定的了解了,Oauth2为了将OAuth2AuthenticationProcessingFilter加入到过滤器中也是一样,他创建了ResourceServerConfiguration继承自WebSecurityConfigurerAdapter,这样的话,只要程序中使用了@EnableWebSecurity注解,就可以执行到ResourceServerConfiguration的config函数
到这里大家可能会问,这里还是没有讲到如何将OAuth2AuthenticationProcessingFilter注册进去呀。其实这里只是将注册OAuth2AuthenticationProcessingFilter的配置类ResourceServerSecurityConfigurer添加到configs列表中,就是截图中代码的http.apply(resources)
而ResourceServerSecurityConfigurer类的configure函数就会在上面的configure中触发
所以最后实际会走到ResourceServerSecurityConfigurer中的configur函数
看到没,这里就是插入OAuth2AuthenticationProcessingFilter的地方了。从上面我们可以学到如何新加入一个过滤器,Oauth2可能因为框架,写的比较复杂,我们工作中使用只需要写一个配置类继承自SecurityConfigurerAdapter,Spring系统会自动扫描到这个配置类,然后将过滤器加入到过滤链中。
我们在得到一个token后,request请求会携带当前的token,在调用request的接口前首先需要判断当前token的合法性,所以如何根据一个token去判断他的有效性呢?我们来一起看下Oauth2中提供的解决方案。
这个函数就是OAuth2AuthenticationProcessingFilter中的doFilter函数,是请求在达到接口前一定会经过的地方。
这边的写法也透露这很好的面向对象编程,对于提取token的功能,单独提供了一个提取功能类,返回也不仅仅只是一个String类型的token,因为这个token还会附带一些相关的 *** 作,例如校验 *** 作,是否已经校验过的功能函数,还有token对应的用户身份信息,这些功能点聚拢,所以产生了一个包含token值的新对象Authentication。
根据token来获取对应的信息是依靠tokenService服务实现的,目前tokenService主要有本地的默认实现和远程实现,理解起来就是本地处理token还是远程token服务来处理返回结果。而tokenService服务还需要将数据存储下来,是依靠了tokenStore服务,例如上面图中例举的这两种实现。
实际上tokenService处理token时先是根据这个token获取到OAuth2AccessToken对象,在根据这个对象去获取到OAuth2Authentication的结果。
对应到代码上就是:
进入到tokenService的loadAuthentication函数中
而tokenService更多的是数据的存储服务,可以放在内存中,也可以放在数据库中,当然更加通用的便是把数据放在redis上,因为在redis上非常容易实现数据的有效时间,这个对于token的有效期十分对应。
上面我们一起总结了Oauth2中是如何处理请求体中传过来的token的,首先Oauth2新增加了一个过滤器,使程序在过滤期间可以将token获取到,然后根据这个token获取到对应的鉴权信息(OAuth2Authentication对象,下同),这个token和其对应的鉴权信息存储在Oauth2的TokenStore服务对象中。这个对象可以是将数据放在当前服务内存中,数据库中,redis中等等。而根据token去获取对应鉴权信息时也会有以下这几种情况
- 根据token没有找到对应的鉴权信息,抛出Invalid access token
- 根据token查找到对应的鉴权信息,但是这个鉴权信息过期了,抛出Access token expired
- 根据token查找到对应的鉴权信息,但是这个鉴权信息中rescourceIds中没有包含oauth2-resource信息,抛出异常Invalid token does not contain resource id
- 根据token查找到对应的鉴权信息,但是根据这个鉴权信息的clientId获取client信息时发生异常,则抛出Invalid token contains invalid client,同时如果请求的requst的scope不符合client中允许的scope,也会报出Invalid token contains disallowed scope for this client异常
- 如果都没有异常,则token校验通过,可以继续下一步的filter,直到达到接口
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)