Spring Boot+Spring Security+Spring Social项目开发(四):使用Spring Social开发第三方登录、QQ登录开发

说在前面

博主最近会有很多项目跟大家一起分享,做完后会上传github上的,希望读友们能给博主提提意见哈哈

这个项目是第三方登录和安全方面的,关于后台与app和网站的登录连接操作的实战项目


使用Spring Social开发第三方登录

OAuth协议简介

OAuth协议简介

OAuth协议要解决的问题

  • 如果把用户名密码给予第三方,那么应用可以访问用户在微信上的所有数据,用户只有修改密码才能收回授权,这样会造成授权的其他第三方全部用不了,密码泄漏的可能性大大提高

OAuth协议中的各种角色

  • 服务提供者(发令牌)-Provider(如微信)
    • 认证服务器-Authorization Server
      • 发token
    • 资源服务器-Resource Server
      • 用户的数据
      • 验证令牌
  • 资源所有者-Resource Owner
  • 第三方应用-Client

OAuth协议中的四种授权模式

  • 授权码模式(最通用)
  • 密码模式
  • 简化模式(少用)
  • 客户端模式(少用)

OAuth协议运行流程


QQ登录开发(在代码中我做了详细的注释)

这里只介绍开发流程,具体意义在代码中有详细解释
这里写图片描述

先写API获取用户的实现–>OAuth2Operations–>ServiceProvider–>ApiAdapter和ServiceProvider–>ConnectionFactory(通过调Connection获取用户信息)–>Connection和UsersConnectionRepository(在Spring中配置即可)–>调DBUserConnection(即数据库去拿到用户信息)

QQ处理流程

第一模块:开发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")

猜你喜欢

转载自blog.csdn.net/tryandfight/article/details/80468394