前言
Spring Security OAuth开发App认证框架
基于session实现的保存用户登录信息:
- 我们现在用户登录成功之后,用户信息都是存在后端Session的,用户通过浏览器每次去访问的时候,每一次服务器都会去检查浏览器的cookie里面是否存在JSESSIONID,不存在jsessionid,我们就会去服务器创建一个session,然后把新创建的sessionid传回到浏览器cookie中。这样每次用户通过浏览器发请求的时候,我们会根据JSESSIONID找到session,然后找到对应的用户信息。
前后端分离架构:
- 移动互联网到来后,新的访问渠道出现了:APP,除了这种访问渠道外,应用的部署方式也在不断演进。现在比较流行的方式就是前后端分离。 前后端分离时候,前端资源不跟后端资源在同一个服务器。而是单独部署到一个Web Server上(比如:node.js)。 采用这种前后端分离架构的时候,用户访问的是WebServer。页面渲染和ajax处理都是这个Web Server来处理的。 用户请求发送到Web Server时候,Web Server再将这个请求转发到Application Server上面。
新架构变化带来的问题:
- 用户不是直接通过浏览器访问我们的Application Server应用,而是通过App第三方应用,或者Web Server;访问我们的内部应用,不是浏览器了,而是其他第三方应用。使用我们的cookie和session就会出现问题。
- 这种架构下:能不能用session和cookie的方式呢?答案是可以的。只要App和Web Server允许你去操作cookie,Session,那么就可以用上面这种方式的。但是在这种架构下cookie和session会有一些问题:
a.开发繁琐(针对于cookie这种功能是浏览器已经内建好的,我们不需要针对cookie写很多代码;但是针对于新架构:App在关闭打开时候,需要在代码里面去实例化这种http客户端,然后发送请求,里面的cookie都是空的,都是初始化的一种状态。这个时候,你就要自己去维护一个cookie的存储)
b.安全性和客户体验差:因为基于cookie和session这种方式,实际上他的这种验证工作都是服务器自己做的。其实也没有说很么验证工作,就是你传过来的cookie里有sessionid,那么我直接就从session里面拿东西。就认为你登录了,没有再去验证 其他东西,那么这种情况下就会导致:比如你的jsessionid被别人知道了,那么他用这个jsessionid放到cookie里面就可以获取用户信息;可能有些人为了解决这种情况;想把session时间设置短一些。然后让其尽快失效掉。那么就会带来另一个问题:session频繁失效就意味着你用户需要频繁去登录。就会带来用户体验差,如果设置长,丢了,用户信息就很可能丢失。
c.有些前端技术不支持cookie,如:小程序。
所以当程序访问者不再是浏览器,而是一些应用时候,我们应该用另一种方式去存储用户信息。这种方式就是我们常说的方式token,原理和session差不多 都是给用户返回一个信息。session方式下是往浏览器里面cookie里面去写一个jsessionid,而用令牌的方式,我是直接发送一个token,用户每次访问的时候,也是带着这个token,用户信息不再存储在session里面,而是根据用户每次请求的令牌来判断:用户是谁?用户有什么权限?用户能干啥。用户认证和授权不再基于session了,而是token令牌。令牌会让我们前面说的问题得到解决。
a.开发繁琐(用户每次请求时候携带的是token,是存放在http的参数;和携带其他参数一样就是一个字符串,token不需要像cookie那样专门做一个复杂开发)
b.安全性和客户体验差:(session这种方式是服务器自己完成的,我们没法干预,但是针对于token这种方式:他怎样生成?里面包含了什么信息?我们怎样校验,都是我们自己可以控制的;安全性:我们可以设置token的过期时间短一些,可以使用token刷新方式,变换token;用户体验:使用token刷新方式,变换token,让用户在没有感知情况下刷新令牌,避免让用户重新重复登录;保证token安全性)。
c.有些前端技术不支持cookie,如:小程序。
上面那种方式就是前面说的oauth协议,我们把App和Web Server当做是应用第三方。每次校验都是通过token实现。
内容
1.1 SpringSocial和SpringSecurityOauth区别
- Spring Social是客户端封装,Spring Security Oauth是服务端封装
- Spring Social开发第三方登录时候,实际上封装了第三方应用也就是client他所要做的大部分事情。拿着Spring Social我们可以很快开发一个第三方应用角色去连接我们服务提供商。
Spring Security Oauth则是封装了服务提供商需要完成的绝大部分的行为;使用Spring Security OAuth,我们就能很快搭建一个服务提供商的程序来。然后往外发送令牌、验收令牌。
1.2 SpringSecurityOauth简介
上面绿色的快都是SpringSecurity给我们实现好了的,红色的快是我们需要自己实现的 ;我们实现的这块:资源是标准的服务是不用改的。我们要改的是自定义的认证方式
- 要实现Spring Security Oauth服务提供商的内容,其实就是需要实现两个服务器;也就是我们之前介绍的认证服务器(Authorization Server)和 资源服务器(Resource Server)
- 在认证服务器里面要做的就是4种授权模式;通过这4种模式来区分用户的身份,以及他所拥有的权限。Spring Security Oauth其实已经把这种模式帮我们实现了。这4种模式实现后,通过用户名/密码.我们知道用户信息之后,我们第二步要做的就是根据我们的这些信息生成Token令牌 即Token的生成存储。后面会根据这个令牌拿去用户信息做检验,所以Token不但生成也得存储。
- 资源服务器就是要保障我们的资源:资源其实就是我们在应用里面写的这些rest服务,怎样来保护这些服务呢?按照目前模式我们使用的是Spring Security过滤器链。他是在我们资源之前加一个过滤器链?那么Spring Security OAuth如何实现资源服务器这样一个功能的呢?他就是在SpringSecurity过滤器链上面添加一个新的过滤器:OAuth2AuthenticationProcessingFilter(从请求中拿到你发送出去的token,然后根据你配置的存储策略去存储里面找到用户对应信息,根据这个用户信息是否存在?是否有权限等一系列判断来决定他是否能访问到你决定的资源,从而实现了资源服务器的功能)
- 我们其实不希望让用户走这4种标准的授权模式的。比如手机号和短信验证码的登录方式。其实跟我们标准的这4中授权模式是搭不上的。标准的这4中授权模式是没有让你输入手机号、输入短信的。然后我们就发一个token给你。我们需要做自定义的认证方式,让这种自定义的认证方式也可以嫁接到认证服务器上去。用户通过这种自定义的认证方式:用户名/密码、手机号、短信、还有第三方的认证之后调用token机制生成token发送到用户。
1.3 接下来需要做的是
- 实现一个标准的OAuth2协议中Provider角色的主要功能:自定义认证
- 重构之前的3种认证方式代码,使其支持token
- 高级特性(JWT,单点登录)
https://segmentfault.com/a/1190000022059608