OAuth2客户端根据与授权服务器进行安全认证的能力,分为机密型(Confidential)和公开型(Public)。机密类型本身会有密码凭证,比如web服务器后台程序;而public类型是没有密码凭证的,大多数纯浏览器前端应用或者手机客户端应用都属于这种类型。无论哪种方式,它们都有一个客户端ID(client_id)。OAuth2客户端认证客户端在执行OAuth2授权的敏感过程(相关过程包括token请求、token自省请求、token撤销请求)必须使用授权服务器进行客户端认证,保证客户端不会中途被认证。换生灵。客户端认证方式目前的客户端认证方式有以下几种:之前的GiteeDEMO使用过时的POST方式;微信DEMO使用非OAuth2标准方式;目前SpringAuthorizationServer相关的DEMO使用的是client_secret_basic方法。剩下的方法中,用的最多的是client_secret_jwt和private_key_jwt。这两种方式可以很好的保护客户端的认证信息,更加安全。目前SpringSecurity和SpringAuthorizationServer都支持这两种方式。client_secret_jwtclient_secret_jwt方法是OAuth2客户端使用自己的key作为HmacSHA256算法的key生成一个SecretKey:byte[]pin=clientSecret.getBytes(StandardCharsets.UTF_8);SecretKeySpecsecretKey=newSecretKeySpec(pin,"HmacSHA256");然后通过SecretKey生成一个携带OAuth2客户端信息的JWT,携带在授权码请求Token链接中,以便授权服务器对客户端进行认证。请求的消息是:POST/oauth2/tokenHTTP/1.1Host:oauth2_client.felord.cnContent-Type:application/x-www-form-urlencodedgrant_type=authorization_code&code=n0esc3NRze7LTCu7iYzS6a5acc3f0ogp4&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion=你的JWT授权服务器接收到客户端的请求,通过OAuth2client_secret解码并验证JWT对客户端进行认证。该方法可以很好的保护非HTTPS环境下client_secret的传输。这里的OAuth2客户端密钥(client_secret)位长必须大于等于256。private_key_jwtprivate_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。详情请订阅我的SpringSecurityOAuth2专栏。这些OAuth2客户端认证方式在不同的场景下有不同的优势,您可以根据不同的安全级别选择不同的OAuth2客户端认证方式。关注公众号:Felordcn获取更多资讯个人博客:https://felord.cn
