授权机制(OAuth2、JWT、Security)- @by_TWJ

授权机制(OAuth2、JWT、Security)

1、前言背景

  1. 目前主流的用户认证方法有:
  • 基于session
  • 基于token

JWT是用在前后端分离, 需要简单的对后台API进行保护时使用.(前后端分离无session, 频繁传用户密码不安全)

这里有具体的详情:session和jwt区别

  1. 第三方网站登录:
  • OAuth2用在使用第三方账号登录的情况(比如使用weibo, qq, github登录某个app)

参考文章:http://www.rfcreader.com/#rfc6750

2、OAuth2

参考文章:前言技术之Oauth2全方面介绍

2.1、OAuth2的四种角色,它们的关系

Oauth一共定义了四种角色:

  • 1.资源所有者(Resource Owner) :即代表用户本身

  • 2.资源服务器(Resource Server) :存储受保护的账号信息

  • 3.授权服务器(Authorization Server) :在成功验证用户身份,并获得授权后,给客户端派发访问资源令牌

  • 4.客户端(Client) :即代表你访问的第三方应用

参考文章:有图解有案例,我终于把OAuth2.0搞清楚了

A 客户端向资源拥有者发送授权申请;
B 资源拥有者同意客户端的授权,返回授权码;
C 客户端使用授权码向认证服务器申请令牌token;
D 认证服务器对客户端进行身份校验,认证通过后发放令牌;
E 客户端拿着认证服务器颁发的令牌去资源服务器请求资源;
F 资源服务器校验令牌的有效性,返回给客户端资源信息;

在这里插入图片描述

例子:
在这里插入图片描述

2.2、Oauth2四种认证方式/授权方式

  • 授权码:通过授权码,服务端通过 Ajax 把 access token 返回给客户端
  • 隐式:用于移动 APP 或 web 应用(应用运行在用户的设备上)
  • 用户密码凭证:同一个公司不同系统之间内部账户互联互通,比如国内某社区的代码托管系统通过社区的账户也可以登录。
  • 客户端凭证:第三方应用自身服务访问提供 OAuth2 服务提供的平台资源
2.2.1、流程图
2.2.1.1、授权码模式

在这里插入图片描述

2.2.1.2、隐式授权模式

在这里插入图片描述

2.2.1.3、密码模式

在这里插入图片描述

2.2.1.4、客户端模式

在这里插入图片描述

2.3、oauth2 模式是否需要前后端

在这里插入图片描述

2.4、oauth2 选型

在这里插入图片描述

参考文章:https://blog.youkuaiyun.com/fcclzydouble/article/details/124021146

2.5、请求参数说明

2.5.1、授权码模式
2.5.1.1、获取授权码
请求URL
https://authorization-server.com/auth
 ?response_type=code 
 &client_id=29352910282374239857
 &redirect_uri=https%3A%2F%2Fexample-app.com%2Fcallback
 &scope=create+delete
 &state=xcoiv98y3md22vwsuye3kch
请求参数说明:
参数是否必须说明
response_type值为code表示指定服务端返回授权码
client_id平台分配给第三方应用的 ID
redirect_uri回调 URL ,处理完后会直接重定向回调URL,并在回调URL后面加上?code=,例如:https://dropletbook.com/callback?code=AUTHORIZATION_CODE
scope请求权限类型,一个或多个空格分隔的字符串,指示应用程序恳求的权限。
state应用程序生成一个随机字符串并将其包括在恳求中。然后它应该查看在用户授权应用程序后是否回来相同的值。这用于避免 CSRF 攻击。
2.5.1.2、获取access_token
请求URL
https://cloud.digitalocean.com/v1/oauth/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=CALLBACK_URL
请求参数说明:
参数是否必须说明
client_id平台分配给第三方应用的 ID
client_secret平台分配给第三方应用的 密钥
grant_type授权类型,填写authorization_code,表示授权码模式
code授权码
redirect_uri一定和申请授权码时用的redirect_uri一致
2.5.2、隐式模式
2.5.2.1、获取access_token
请求URL
https://authorization-server.com/auth
 ?response_type=token
 &client_id=29352910282374239857
 &redirect_uri=https%3A%2F%2Fexample-app.com%2Fcallback
 &scope=create+delete
 &state=xcoiv98y3md22vwsuye3kch
请求参数说明:
参数是否必须说明
response_type值为token表示指定服务端返回token
client_id平台分配给第三方应用的 ID
redirect_uri回调 URL ,处理完后会直接重定向回调URL,并在回调URL后面加上?code=,例如:https://dropletbook.com/callback?code=AUTHORIZATION_CODE
scope请求权限类型,一个或多个空格分隔的字符串,指示应用程序恳求的权限。
state应用程序生成一个随机字符串并将其包括在恳求中。然后它应该查看在用户授权应用程序后是否回来相同的值。这用于避免 CSRF 攻击。
2.5.3、密码模式
2.5.3.1、获取access_token
请求URL
POST /oauth/token HTTP/1.1
Host: authorization-server.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic Y2xpZW50OnNlY3JldA==

grant_type=password&username=johndoe&password=A3ddj3w

在上面的请求中,Authorization头部包含了客户端的ID和Secret,"grant_type=password"表示使用密码模式进行授权,"username"和"password"分别是用户的用户名和密码。

请求参数说明:
参数是否必须说明
grant_type值为password表示使用密码模式
username用户名
password密码
2.5.4、客户端模式
2.5.4.1、获取access_token
请求URL
POST /oauth/token HTTP/1.1
Host: authorization-server.com
Authorization: Basic Base64Encode(client_id:client_secret)
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials

在上面的请求中,Authorization头部包含了客户端的ID和Secret,

请求参数说明:
参数是否必须说明
grant_type值为client_credentials表示客户端模式
2.5.5、token
2.5.5.1、token使用

token_type:有MAC TokenBearer Token两种类型,两种的校验算法不同,RFC 6750建议Oauth2采用 Bearer Token(http://www.rfcreader.com/#rfc6750)。

Bearer Token

bearer token 是一个加密字符串,通常由服务端根据密钥生成。
客户端在请求服务端时,必须在请求头中包含 Authorization: Bearer <token>
服务端收到请求后,解析出 <token> ,并校验 <token> 的合法性。
如果校验通过,则认证通过。

例如:

GET /api/userinfo HTTP/1.1
Host: resource-server.com
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA

MAC Token(略)

(我也没找到资料)

2.5.5.2、刷新token
请求URL
https://cloud.digitalocean.com/v1/oauth/token?grant_type=refresh_token&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&refresh_token=REFRESH_TOKEN 
请求参数说明:
参数是否必须说明
grant_type授权类型,填写refresh_token,表示授权码模式刷新token
client_id平台分配给第三方应用的 ID
client_secret平台分配给第三方应用的 密钥
refresh_token刷新token,这个和access_token不一样 ,在获取access_token的时候,会返回refresh_token

3、spring security

3.1、OAuth2 整合

参考文章:https://docs.spring.io/spring-security/reference/servlet/oauth2/login/index.html

英文文档比较难读,而且暂时不需要用,所以就不深入去解读了。

3.1.1、配置自定义提供程序属性

在这里插入图片描述

例如:

spring:
  security:
    oauth2:
      client:
        registration:
          okta:
            client-id: okta-client-id
            client-secret: okta-client-secret
        provider:
          okta:	
            authorization-uri: https://your-subdomain.oktapreview.com/oauth2/v1/authorize
            token-uri: https://your-subdomain.oktapreview.com/oauth2/v1/token
            user-info-uri: https://your-subdomain.oktapreview.com/oauth2/v1/userinfo
            user-name-attribute: sub
            jwk-set-uri: https://your-subdomain.oktapreview.com/oauth2/v1/keys

4、JWT

4.1、jwt概念

参考文章:https://blog.youkuaiyun.com/sssssooo/article/details/128509302

JWT是一种认证协议,提供了一种用于发布接入令牌(Access Token),并对发布的签名接入令牌进行验证的方法。SSO私钥加密token。应用端公钥解密token,

4.2、jwt格式

参考文章:https://www.jianshu.com/p/455a537854a9
参考文章:https://blog.youkuaiyun.com/Solo95/article/details/123456965

一个JWT包含3个部分:
头部Header:可存放签名的类型
数据Payload:可存放用户数据和有效期,Payload的内容在接收者端是通过签名(Signature)来校验的。
签名Signature:使用密钥对Header和Payload数据进行加密生成签名。

4.2.1、header
{
	"alg": "HS256",
	"typ": "JWT"
}
JWS算法名称描述
HS256HMAC256HMAC with SHA-256
HS384HMAC384HMAC with SHA-384
HS512HMAC512HMAC with SHA-512
RS256RSA256RSASSA-PKCS1-v1_5 with SHA-256
RS384RSA384RSASSA-PKCS1-v1_5 with SHA-384
RS512RSA512RSASSA-PKCS1-v1_5 with SHA-512
ES256ECDSA256ECDSA with curve P-256 and SHA-256
ES384ECDSA384ECDSA with curve P-384 and SHA-384
ES512ECDSA512ECDSA with curve P-521 and SHA-512
PS256RSAPSSSA256RSAPSS with SHA-256
PS384RSAPSSSA384RSAPSS with SHA-384
4.2.2、Payload

JWT token的第二部分是包含了声明的payload,声明是一个实体的表述加上额外信息,一共有三种形式的声明:注册、共有和私有。

注册声明(建议但不强制):

  • iss: jwt签发者
  • sub: jwt使用者
  • aud: jwt接收者
  • exp: jwt过期时间,该时间必须大于签发时间
  • nbf: 定义在某个时间之前,该jwt都是不可用的
  • iat: jwt签发时间
  • jti: jwt唯一身份标注,主要用于一次性token,从而避免重放攻击
    (注:为了保持紧凑,注册声明都是三个字母)

公有声明:
公有声明可以加入任何信息,一般会添加用户相关信息或者业务需要的信息,但不建议添加敏感信息,因为该部分会在客户端解密。
私有声明:
私有声明是提供者和使用者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密,基本等同于明文信息。

例如:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}
4.2.3、Signature(签名)
4.2.4、公式
String header = "";
String payload = "";
String secret = "";
HMACSHA256( 
    base64UrlEncode(header) + "." + base64UrlEncode(payload),
    secret
)

4.3、java代码

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
    public final static String SECRET = "abcdefghijklmnopqrstuvwxyz";
       public String getToken(){
        // Jwt存储信息
        Map<String, Object> claimsMap = new HashMap<String, Object>();
        claimsMap.put("user_key", token);//随机id
        claimsMap.put("user_id", userId);//用户id
        claimsMap.put("username", userName);//用户名
        return createToken(claimsMap);
       }
   public static String createToken(Map<String, Object> claims)
    {
        String token = Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512, secret).compact();
        return token;
    }

4.4、流程图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值