OAuth2客户端依照它们与受权服务器进行平安认证的能力能够分为秘密类型(Confidential)和公共类型(Public)。
秘密类型的本身会有个明码凭据,比方Web服务器后端程序;而公共类型则没有明码凭据,纯浏览器前端利用或者挪动客户端利用大都属于这一种类型。不论是哪一种,它们都有客户端ID(client_id)。
OAuth2客户端认证
客户端在执行OAuth2受权的敏感流程中(相干的流程有令牌申请、令牌自省申请、令牌撤销申请)必须应用受权服务器进行客户端身份验证,确保客户端中途不会被调包。
客户端认证形式
目前客户端认证的形式有以下几种:
后面Gitee的DEMO应用的是过期的POST形式;微信DEMO应用的是非OAuth2规范的形式;Spring Authorization Server目前相干的DEMO应用的是client_secret_basic形式。剩下的形式中client_secret_jwt和private_key_jwt用的比拟多,这两种形式能够很好地爱护客户端的认证信息,安全性更高。Spring Security和Spring Authorization Server目前曾经反对这两种形式。
client_secret_jwt
client_secret_jwt
形式是OAuth2客户端将本人的密钥作为HmacSHA256
算法的key生成SecretKey
:
byte[] pin = clientSecret.getBytes(StandardCharsets.UTF_8);SecretKeySpec secretKey = new SecretKeySpec(pin,"HmacSHA256");
而后通过SecretKey
生成一个携带OAuth2客户端信息的JWT,在受权码申请Token环节携带该JWT以便受权服务器进行客户端认证,申请的报文为:
POST /oauth2/token HTTP/1.1 Host: oauth2_client.felord.cn Content-Type: application/x-www-form-urlencoded grant_type=authorization_code& code=n0esc3NRze7LTCu7iYzS6a5acc3f0ogp4& client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer& client_assertion=你的JWT
受权服务器收到申请后通过OAuth2客户端的client_secret
对JWT进行解码校验以认证客户端。这种形式能很好的爱护client_secret
在非HTTPS环境下的传输。
这里OAuth2客户端的密钥(client_secret)比特长度必须大于等于256。
private_key_jwt
private_key_jwt
和client_secret_jwt
惟一的区别就是生成JWT的形式不同。通过这种形式,OAuth2客户端曾经不须要client_secret
,只须要配置一对RSA
或者EC
密钥,通过密钥来生成JWT,另外还须要向受权服务器提供公钥,通常是一个jwkSetUrl。该形式的细节曾经在OAuth2专栏中JOSE标准一文中进行过具体阐明了,这里不再赘述。这种形式让客户端的认证信息更加平安的传输,是我集体比拟喜爱的形式。
tls_client_auth
这个比拟高级,嵌入了TLS平安层,在HTTP协定级别来认证OAuth2客户端,它波及的证书来自可信赖的CA。这种形式根本脱离了应用层,是一种无侵入的形式。
self_signed_tls_client_auth
这个同样也是在TLS平安层,不过它应用了自签名的X.509证书。
总结
市面上的教程大多只会提到过期的POST形式以及client_secret_basic和client_secret_post形式,对前面的五种则很少波及,胖哥曾经对private_key_jwt和client_secret_jwt进行了实现,具体请订阅我的Spring Security OAuth2专栏。这些OAuth2客户端认证形式在不同的场景有不同的劣势,你能够依据不同的安全级别抉择不同的OAuth2客户端认证形式。
关注公众号:Felordcn 获取更多资讯
集体博客:https://felord.cn