说在前面
博主最近会有很多项目跟大家一起分享,做完后会上传github上的,希望读友们能给博主提提意见哈哈
这个项目是第三方登录和安全方面的,关于后台与app和网站的登录连接操作的实战项目
使用Spring Social开发第三方登录
OAuth协议简介
OAuth协议要解决的问题
- 如果把用户名密码给予第三方,那么应用可以访问用户在微信上的所有数据,用户只有修改密码才能收回授权,这样会造成授权的其他第三方全部用不了,密码泄漏的可能性大大提高
OAuth协议中的各种角色
- 服务提供者(发令牌)-Provider(如微信)
- 认证服务器-Authorization Server
- 发token
- 资源服务器-Resource Server
- 用户的数据
- 验证令牌
- 认证服务器-Authorization Server
- 资源所有者-Resource Owner
- 第三方应用-Client
OAuth协议中的四种授权模式
- 授权码模式(最通用)
- 密码模式
- 简化模式(少用)
- 客户端模式(少用)
OAuth协议运行流程
QQ登录开发(在代码中我做了详细的注释)
这里只介绍开发流程,具体意义在代码中有详细解释
先写API获取用户的实现–>OAuth2Operations–>ServiceProvider–>ApiAdapter和ServiceProvider–>ConnectionFactory(通过调Connection获取用户信息)–>Connection和UsersConnectionRepository(在Spring中配置即可)–>调DBUserConnection(即数据库去拿到用户信息)
第一模块:开发QQ接口,QQ的实现类,QQService提供者,QQ用户信息(QQ,QQImpl,QQServiceProvider,QQUserInfo)
1.QQImpl继承AbstractOauth2ApiBinding
2.AbstractOauth2ApiBinding–>accessToken类级别的全局变量,意味着这个对象(QQImpl)不是一个单例对象,针对每一个用户走完自己的OAuth流程之后都会为那个用户单独创建一个QQApi的实现,然后存用户特有的accessToken
3.restTemplate:发Http请求的
4.QQServiceProvider继承AbstractOAuth2ServiceProvider
第二模块:开发Adapter和ServiceProvider
1.QQAdapter实现接口ApiAdapter
2.QQConnectionFactory继承OAuth2ConnectionFactory
3.SocialConfig社交配置的适配器,继承SocialConfigurerAdapter,加@Configuration和@EnableSocial(启动社交项目相应的特性)
4.业务系统,即demo中写MyUserDetailsService
5.QQProperties继承SocialProperties(appId,appSecret),加上providerId
6.SocialProperties封装多一层,对所有社交登录的配置进行管理,如果下次有微信登录或者微博登录则在这里面引用即可
7.QQAutoConfig,加上@Configuration
@ConditionalOnProperty(prefix = “tihom.security.social.qq”,name = “aqq-id”) //如果在我的系统中app-id被配置了值了,下面的配置才生效
8.在application.properties中写上
tihom.security.social.qq.app-id=
tihom.security.social.qq.app-secret=
9.SocialConfig中配置SocialAuthentication过滤器,声明@Bean
@Bean
public SpringSocialConfigurer tihomSocialSecurityConfig(){
TihomSpringSocialConfigurer configurer = new TihomSpringSocialConfigurer
(securityProperties.getSocial().getFilterProcessesUrl());
configurer.signupUrl(securityProperties.getBrowser().getSignUpUrl());
return configurer;
}
10.在BrowserSecurityConfig中引入tihomSocialSecurityConfig这个配置Bean
@Autowired
private SpringSocialConfigurer tihomSocialSecurityConfig;
同时在下方的configure上加上.apply(tihomSocialSecurityConfig)
11.在页面上加上社交登录入口
第三模块:处理登录后的跳转问题
1.网站回调域中:/qqLogin/callback.do
2.修改hosts文件,将对应的域名网站如www.xxx.com配置在127.0.0.1上,访问www.xxx.com时就相当于访问本机,同时修改端口
#这里是外网访问本机的端口,在linux下1024以内的端口都需要root权限,所以需要做端口转发,将访问80端口的跳转到9090端口,9090就是我们自己写的demo服务
server.port=9090
3.配置TihomSpringSocialConfigurer继承SpringSocialConfigurer,并且自定义postProcess方法的实现和构造器的配置.在SocialProperties中加上filterProcessesUrl的配置
4.在application.properties配置中加上
tihom.security.social.qq.providerId=callback.do
tihom.security.social.filterProcessesUrl=/qqLogin
5.QQOAuth2Template继承OAuth2Template,重写createRestTemplate方法添加一个消息转换器可以处理text/html这种contentType
6.QQ互联的Access_Token返回格式是这样的
access_token=FE04************************CCE2&expires_in=7776000&refresh_token=88E4************************BE14
所以需要重写postForAccessGrant方法,通过分割和截取将三个属性accessToken、expiresIn、refreshToken获取出来,这样就将请求的格式按QQ的标准做了一个自定义体系
7.在Spring Security中默认不带上client_id和client_secret参数,而QQ需要这两个参数,所以我们要在QQOAuth2Template的构造器中加上
setUseParametersForClientAuthentication(true);
将这两个参数在发请求时被带上
8.在QQServiceProvider中的new OAuth2Template改为new QQOAuth2Template即可
第四模块:处理注册逻辑
1.写一个注册页和UserController层配置
2.针对注册url做授权即在BrowserSecurityConfig的configure中加配置
3.在SocialConfig引入ProviderSignInUtils提供者登录工具
@Bean
public ProviderSignInUtils providerSignInUtils(ConnectionFactoryLocator connectionFactoryLocator){
return new ProviderSignInUtils(connectionFactoryLocator,
getUsersConnectionRepository(connectionFactoryLocator)){};
}
4.往BrowserSecurityController中加一个GetMapping方法,这个方法是获取SocialUserInfo即QQ用户信息的
5.同时UserController加上一个@PostMapping处理注册的逻辑
6.在BrowserSecurityConfig中配置上静态资源
.antMatchers(
SecurityConstants.DEFAULT_UNAUTHENTICATION_URL,
SecurityConstants.DEFAULT_LOGIN_PROCESSING_URL_MOBILE,
securityProperties.getBrowser().getLoginPage(),
SecurityConstants.DEFAULT_VALIDATE_CODE_URL_PREFIX+"/*",
securityProperties.getBrowser().getSignUpUrl(),
"/user/regist")