常见Javaweb后台认证⽅式总结
⼏种常⽤的认证机制
HTTP Basic Auth
HTTP Basic Auth简单点说明就是每次请求API时都提供⽤户的username和password,简⾔之,Basic Auth是配合RESTful API 使⽤的最简单的认证⽅式,只需提供⽤户名密码即可,但由于有把⽤户名密码暴露给第三⽅客户端的风险,在⽣产环境下被使⽤的越来越少。因此,在开发对外开放的RESTful API时,尽量避免采⽤HTTP Basic Auth
OAuth
OAuth(开放授权)是⼀个开放的授权标准,允许⽤户让第三⽅应⽤访问该⽤户在某⼀web服务上存储的私密的资源(如照⽚,视频,联系⼈列表),⽽⽆需将⽤户名和密码提供给第三⽅应⽤。
OAuth允许⽤户提供⼀个令牌,⽽不是⽤户名和密码来访问他们存放在特定服务提供者的数据。每⼀个令牌授权⼀个特定的第三⽅系统(例如,视频编辑⽹站)在特定的时段(例如,接下来的2⼩时内)内访问特定的资源(例如仅仅是某⼀相册中的视频)。这样,OAuth让⽤户可以授权第三⽅⽹站访问他们存储在另外服务提供者的某些特定信息,⽽⾮所有内容
下⾯是OAuth2.0的流程:
这种基于OAuth的认证机制适⽤于个⼈消费者类的互联⽹产品,如社交类APP等应⽤,但是不太适合拥有⾃有认证权限管理的企业应⽤;
Cookie Auth
Cookie认证机制就是为⼀次请求认证在服务端创建⼀个Session对象,同时在客户端的浏览器端创建了⼀个Cookie对象;通过客户端带上来Cookie对象来与服务器端的session对象匹配来实现状态管理的。默认的,当我们关闭浏览器的时候,cookie会被删除。但可以通过修改cookie 的expire time使cookie在⼀定时间内有效;
Token Auth
Token Auth的优点
Token机制相对于Cookie机制⼜有什么好处呢?
⽀持跨域访问: Cookie是不允许垮域访问的,这⼀点对Token机制是不存在的,前提是传输的⽤户认证
信息通过HTTP头传输.
⽆状态(也称:服务端可扩展⾏):Token机制在服务端不需要存储session信息,因为Token ⾃⾝包含了所有登录⽤户的信息,只需要在客户端的cookie或本地介质存储状态信息.
更适⽤CDN: 可以通过内容分发⽹络请求你服务端的所有资料(如:javascript,HTML,图⽚等),⽽你的服务端只要提供API即可.
去耦: 不需要绑定到⼀个特定的⾝份验证⽅案。Token可以在任何地⽅⽣成,只要在你的API被调⽤的时候,你可以进⾏Token⽣成调⽤即可.
更适⽤于移动应⽤: 当你的客户端是⼀个原⽣平台(iOS, Android,Windows 8等)时,Cookie是不被⽀持的(你需要通过Cookie容器进⾏处理),这时采⽤Token认证机制就会简单得多。
CSRF:因为不再依赖于Cookie,所以你就不需要考虑对CSRF(跨站请求伪造)的防范。
性能: ⼀次⽹络往返时间(通过数据库查询session信息)总⽐做⼀次HMACSHA256计算 的Token验证和解析要费时得多.
不需要为登录页⾯做特殊处理: 如果你使⽤Protractor 做功能测试的时候,不再需要为登录页⾯做特殊处理.
基于标准化:你的API可以采⽤标准化的 JSON Web Token (JWT). 这个标准已经存在多个后端库(.NET, Ruby, Java,Python, PHP)和多家公司的⽀持(如:Firebase,Google, Microsoft).
基于JWT的Token认证机制实现
JSON Web Token(JWT)是⼀个⾮常轻巧的规范。这个规范允许我们使⽤JWT在⽤户和服务器之间传递安全可靠的信息。其
JWT的组成
⼀个JWT实际上就是⼀个字符串,它由三部分组成,头部、载荷与签名。
载荷(Payload)
web后端是指什么{ "iss": "Online JWT Builder",
"iat": 1416797419,
"exp": 1448333419,
"aud": "ample",
"sub": "jrocket@example",
"GivenName": "Johnny",
"Surname": "Rocket",
"Email": "jrocket@example",
"Role": [ "Manager", "Project Administrator" ]
}
iss: 该JWT的签发者,是否使⽤是可选的;
sub: 该JWT所⾯向的⽤户,是否使⽤是可选的;
aud: 接收该JWT的⼀⽅,是否使⽤是可选的;
exp(expires): 什么时候过期,这⾥是⼀个Unix时间戳,是否使⽤是可选的;
iat(issued at): 在什么时候签发的(UNIX时间),是否使⽤是可选的;
其他还有:
nbf (Not Before):如果当前时间在nbf⾥的时间之前,则Token不被接受;⼀般都会留⼀些余地,⽐如⼏分钟;,是否使⽤是可选的;
将上⾯的JSON对象进⾏[base64编码]可以得到下⾯的字符串。这个字符串我们将它称作JWT的Payload(载荷)。
eyJpc3MiOiJKb2huIFd1IEpXVCIsImlhdCI6MTQ0MTU5MzUwMiwiZXhwIjoxNDQxNTk0NzIyLCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJqcm9ja2V0
⼩知识:Base64是⼀种基于64个可打印字符来表⽰⼆进制数据的表⽰⽅法。由于2的6次⽅等于64,所以每6个⽐特为⼀个单元,对应某
个可打印字符。三个字节有24个⽐特,对应于4个Base64单元,即3个字节需要⽤4个可打印字符来表⽰。JDK 中提供了⾮常⽅便
的 BASE64Encoder 和 BASE64Decoder,⽤它们可以⾮常⽅便的完成基于 BASE64 的编码和解码
头部(Header)
JWT还需要⼀个头部,头部⽤于描述关于该JWT的最基本的信息,例如其类型以及签名所⽤的算法等。这也可以被表⽰成⼀个JSON对象。
{
"typ": "JWT",
"alg": "HS256"
}
在头部指明了签名算法是HS256算法。
当然头部也要进⾏BASE64编码,编码后的字符串如下:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
签名(Signature)
将上⾯的两个编码后的字符串都⽤句号.连接在⼀起(头部在前),就形成了:
最后,我们将上⾯拼接完的字符串⽤HS256算法进⾏加密。在加密的时候,我们还需要提供⼀个密钥(secret)。如果我们⽤mystar作为密钥的话,那么就可以得到我们加密后的内容:
rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM
最后将这⼀部分签名也拼接在被签名的字符串后⾯,我们就得到了完整的JWT:
即加密秘钥编码+描述JWT基本信息的头部编码+JWT⾃⾝携带的信息编码
your.awesome-app/make-friend/?Jmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0.rSWa 认证过程
下⾯我们从⼀个实例来看如何运⽤JWT机制实现认证:
登录
第⼀次认证:第⼀次登录,⽤户从浏览器输⼊⽤户名/密码,提交后到服务器的登录处理的Action层(Login Action);
Login Action调⽤认证服务进⾏⽤户名密码认证,如果认证通过,Login Action层调⽤⽤户信息服务获取⽤户信息(包括完整的⽤户信息及对应权限信息);
返回⽤户信息后,Login Action从配置⽂件中获取Token签名⽣成的秘钥信息,进⾏Token的⽣成;
⽣成Token的过程中可以调⽤第三⽅的JWT Lib⽣成签名后的JWT数据;
完成JWT数据签名后,将其设置到COOKIE对象中,并重定向到⾸页,完成登录过程;
请求认证
基于Token的认证机制会在每⼀次请求中都带上完成签名的Token信息,这个Token信息可能在COOKIE
中,也可能在HTTP的Authorization头中;
客户端(APP客户端或浏览器)通过GET或POST请求访问资源(页⾯或调⽤API);
认证服务作为⼀个Middleware HOOK 对请求进⾏拦截,⾸先在cookie中查Token信息,如果没有到,则在HTTP Authorization Head中查;
如果到Token信息,则根据配置⽂件中的签名加密秘钥,调⽤JWT Lib对Token信息进⾏解密和解码;
完成解码并验证签名通过后,对Token中的exp、nbf、aud等信息进⾏验证;
全部通过后,根据获取的⽤户的⾓⾊权限信息,进⾏对请求的资源的权限逻辑判断;
如果权限逻辑判断通过则通过Response对象返回;否则则返回HTTP 401;
对Token认证的五点认识

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。