oauth2登录路径是/oauth/token,根据参数的不同,可实现不同方式的登录。

入口文件是TokenEndpoint,但在进入到此方法之前,会先进行认证,拿最普通的密码方式登录来说,需要传的参数必须得有Authorization或者client_id和client_secret,否则登录接口会返回401。二者关系是client_id:client_secret的base64加密的值就是Authorization传的参数值。

1.判断登录接口的认证是走client认证还是Authorization认证

判断方法是AbstractAuthenticationProcessingFilter.doFilter

 if的条件会进入ClientCredentialsTokenEndpointFilter.ClientCredentialsRequestMatcher.matches方法,内容如下,主要是判断参数中是否含有client_id参数,有的话就走client认证,没有的话就走上图if条件,Authorization认证

2.Authorization认证

Authorization认证的代码均在BasicAuthenticationFilter.doFilterInternal方法中

 上图中 this.authenticationConverter.convert 会将Authorization进行解密,解析出client_id和client_secret,放到authRequest中,供后续使用。两种认证方式,只是数据传入服务的方式不同,后台对参数进行不同的处理后,其实认证方式是相同的,都是ProviderManager.authenticate。

3.client认证

AbstractAuthenticationProcessingFilter.doFilter方法的else中,调用了 attemptAuthentication方法,然后ClientCredentialsTokenEndpointFilter.attemptAuthentication实现了该方法。

 在做了一些验证之后,进入到ProviderManager.authenticate方法中。

4.后续认证

ProviderManager.authenticate方法

核心是 result = provider.authenticate(authentication),在这个部分,provider为DaoAuthenticationProvider,DaoAuthenticationProvider继承了AbstractUserDetailsAuthenticationProvider,authenticate使用的是AbstractUserDetailsAuthenticationProvider.authenticate。

后续逻辑调用依次为

this.retrieveUser

>>>DaoAuthenticationProvider.retrieveUser

>>>ClientDetailsUserDetailsService.loadUserByUsername

>>>JdbcClientDetailsService.loadClientByClientId

JdbcClientDetailsService这个类中包含了从数据库去客户端认证的相关信息,可对内置的sql进行赋值覆盖,从而从自定义的表中取信息。信息中包含密码信息,在对比解析出的密码,就完成了验证。验证之后,才进入到登录接口中


版权声明:本文为qq_39584267原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_39584267/article/details/126409125