在早期我写过一篇spring social理解的文章,介绍了一些spring social的概念,但是没有提供一个例子。在这篇博客中,提供一个简单的spring social的例子,实现 百度登录,那为什么不实现QQ登录或微信登录,主要是在QQ和微信上申请应用比较麻烦,没有百度方便,在文章的末尾我也放出 QQ登录 和 微信登录 的源码。2018-11-28号增加了一个 github 的登录。
实现功能:
1,实现百度登录
2,与 spring security 整合
3,当是第一次使用百度登录时,自动在业务中中创建一个用户。
4,显示获取到百度用户的用户昵称和图像等
与spring security整合注意事项:
1,在spring security的过滤器链中增加 SocialAuthenticationFilter 来判断用户是否是社交登录,默认拦截 /auth 开头的请求。该过滤器在 SpringSocialConfigurer 类中配置的。
2,当我们使用百度登录成功后,如何和我们自动业务系统中的userId进行关联,是有UserConnection表进行关联的。
3,需要实现 SocialUserDetailsService 接口,返回业务系统中的用户信息,用户id就是业务系统中的userId.
开发一个社交登录
1,看spring social官网提供的步骤
前置条件
1,在百度开发者中心创建一个应用,设置好回调 url , 假设此处为 http://www.huan1993.com/auth/baidu
2,记录好上一步的 apikey 和 securityKey
3,在本地 hosts 文件中配置 127.0.0.1 www.huan1993.com
4,在数据库中创建 UserConnection 表,表名不可变,但是可以加前缀。建表语句在 JdbcConnectionRepository.java 文件下方。这张表维护了 业务系统张三(userId)在百度(providerId)上的唯一用户标识(providerUserId)
实现步骤
1,新建 BaiduUserInfo 类,此类是保存着用户在百度上的基本信息
/** * 百度的用户信息 * * @author huan.fu * @date 2018/9/27 - 16:58 */ @NoArgsConstructor @Data public class BaiduUserInfo { @SerializedName("userid") private String userId; private String username; @SerializedName("realname") private String realName; @SerializedName("userdetail") private String userDetail; private String birthday; private String marriage; private String portrait; private String sex; private String blood; private String constellation; private String figure; private String education; private String trade; private String job; @SerializedName("birthday_year") private String birthdayYear; @SerializedName("birthday_month") private String birthdayMonth; @SerializedName("birthday_day") private String birthdayDay; }
2,新建 Baidu 接口类,申明一个方法用于获取百度的基本信息
/** * baidu api 接口 * * @author huan.fu * @date 2018/9/27 - 17:00 */ public interface Baidu { /** * 获取百度用户信息 * * @return */ BaiduUserInfo getUserInfo(); }
3,新建 BaiduTemplate.java 类,获取具体的百度用户信息
/** * 百度接口实现,此处用户获取用户在百度上的基本信息 * * @author huan.fu * @date 2018/9/27 - 17:01 */ @Slf4j public class BaiduTemplate extends AbstractOAuth2ApiBinding implements Baidu { @Getter private String userInfoUrl; @Getter private String accessToken; public BaiduTemplate(String accessToken, String userInfoUrl) { /** * 调用父类 2 个参数的构造方法, * TokenStrategy.ACCESS_TOKEN_PARAMETER 父类会自动将此参数带上,默认是放在请求头Authorization头中 */ super(accessToken, TokenStrategy.OAUTH_TOKEN_PARAMETER); this.userInfoUrl = userInfoUrl; this.accessToken = accessToken; } @Override public BaiduUserInfo getUserInfo() { String userInfo = getRestTemplate().getForObject(String.format(this.getUserInfoUrl(), this.getAccessToken()), String.class); log.info("获取的百度用户信息为:[{}]", userInfo); return new Gson().fromJson(userInfo, BaiduUserInfo.class); } }
4,新建 BaiduAdapter.java 类,用于将百度的用户信息转换成Connection的标准信息
/** * 百度的 api 适配器 * * @author huan.fu * @date 2018/9/27 - 17:10 */ public class BaiduAdapter implements ApiAdapter<Baidu> { @Override public boolean test(Baidu api) { return true; } @Override public void setConnectionValues(Baidu api, ConnectionValues values) { BaiduUserInfo userInfo = api.getUserInfo(); values.setDisplayName(userInfo.getRealName() == null ? userInfo.getUsername() : userInfo.getRealName()); values.setImageUrl(String.format("http://tb.himg.baidu.com/sys/portrait/item/%s", userInfo.getPortrait())); values.setProfileUrl(null); values.setProviderUserId(userInfo.getUserId()); } @Override public UserProfile fetchUserProfile(Baidu api) { return null; } @Override public void updateStatus(Baidu api, String message) { } }
5,新建 BaiduOauth2Template.java 类,用于走oauth2授权码流程,获取到真正的访问令牌
/** * 走完oauth2流程 * * @author huan.fu * @date 2018/9/27 - 17:14 */ @Slf4j public class BaiduOauth2Template extends OAuth2Template { public BaiduOauth2Template(String clientId, String clientSecret, String authorizeUrl, String accessTokenUrl) { super(clientId, clientSecret, authorizeUrl, accessTokenUrl); // 设置为true,将客户端凭证作为参数传递给提供者,而不是使用HTTP基本身份验证 createRestTemplate() 此方法中如果useParametersForClientAuthentication=false将会使用basic认证 setUseParametersForClientAuthentication(true); } @Override public String buildAuthenticateUrl(OAuth2Parameters parameters) { StringBuilder builder = new StringBuilder(super.buildAuthenticateUrl(parameters)); // force_login=1 在百度登录中表示:force_login:非必须参数,如传递“force_login=1”,则加载登录页时强制用户输入用户名和口令,不会从cookie中读取百度用户的登陆状态。 builder.append("&force_login=1"); log.info("获取code的访问url:[{}]", builder.toString()); return builder.toString(); } }
6,创建一个 BaiduServiceProvider.java类 封装 api 和 oauth2template
/** * 服务提供商 * * @author huan.fu * @date 2018/9/27 - 17:20 */ @Getter public class BaiduServiceProvider extends AbstractOAuth2ServiceProvider<Baidu> { private String userInfoUrl; public BaiduServiceProvider(String clientId, String clientSecret, String userInfoUrl, String authorizeUrl, String accessTokenUrl) { super(new BaiduOauth2Template(clientId, clientSecret, authorizeUrl, accessTokenUrl)); this.userInfoUrl = userInfoUrl; } @Override public Baidu getApi(String accessToken) { return new BaiduTemplate(accessToken, this.getUserInfoUrl()); } }
7,创建 BaiduConnectionFactory 用来产生连接
/** * 百度 connection fatory * * @author huan.fu * @date 2018/9/27 - 17:22 */ public class BaiduConnectionFactory extends OAuth2ConnectionFactory<Baidu> { public BaiduConnectionFactory(String providerId, String clientId, String userInfoUrl, String clientSecret, String authorizeUrl, String accessTokenUrl) { super( providerId, new BaiduServiceProvider(clientId, clientSecret, userInfoUrl, authorizeUrl, accessTokenUrl), new BaiduAdapter() ); } }
8,创建 BaiduConnectionSignUp 类用来为用户在业务系统注册一个用户
/** * 一个简单的注册处理 * * @author huan.fu * @date 2018/9/27 - 17:29 */ @Slf4j public class BaiduConnectionSignUp implements ConnectionSignUp { /** * 可以在此方法中进行简单的用户注册 * * @param connection * @return 用户注册后, 业务系统中的 用户编号 */ @Override public String execute(Connection<?> connection) { ConnectionData connectionData = connection.createData(); log.info("用户在系统中是第一次使用百度登录,系统自动给用户进行注册一个用户,返回用户在业务系统中的id:[{}]", connectionData.getProviderUserId()); return connectionData.getProviderUserId(); } }
9,百度的登录社交配置
社交登录中需要用到的配置属性
/** * 百度 社交登录配置属性 * * @author huan.fu * @date 2018/9/27 - 15:30 */ @ConfigurationProperties(prefix = "spring.social.baidu") @Data public class BaiduProperties { private String providerId; private String clientId; private String clientSecret; private String userInfoUrl; private String authorizeUrl; private String accessTokenUrl; }
社交登录配置
/** * 百度 社交登录的自动配置 * * @author huan.fu * @date 2018/9/27 - 17:35 */ @Configuration @EnableSocial @ConditionalOnProperty(prefix = "spring.social.baidu", name = "provider-id") @AutoConfigureBefore(SocialWebAutoConfiguration.class) @AutoConfigureAfter(WebMvcAutoConfiguration.class) public class BaiduAutoAuthConfig extends SocialAutoConfigurerAdapter { @Autowired private BaiduProperties baiduProperties; @Autowired private DataSource dataSource; @Autowired private BaiduAuthenticationSuccessHandlerSuccessHandler baiduAuthenticationSuccessHandlerSuccessHandler; @Override protected ConnectionFactory<?> createConnectionFactory() { return new BaiduConnectionFactory( baiduProperties.getProviderId(), baiduProperties.getClientId(), baiduProperties.getUserInfoUrl(), baiduProperties.getClientSecret(), baiduProperties.getAuthorizeUrl(), baiduProperties.getAccessTokenUrl() ); } @Override public UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) { // 第三个参数表数保存到数据库中的数据是以何种方式进行存储的,此处明文进行存储 JdbcUsersConnectionRepository jdbcUsersConnectionRepository = new JdbcUsersConnectionRepository(dataSource, connectionFactoryLocator, Encryptors.noOpText()); // 设置 UserConnection 表的前缀,此处不进行设置 jdbcUsersConnectionRepository.setTablePrefix(""); jdbcUsersConnectionRepository.setConnectionSignUp(new BaiduConnectionSignUp()); return jdbcUsersConnectionRepository; } /** * 将 spring social 加入到 spring security 的过滤器链中 * * @return */ @Bean public SpringSocialConfigurer springSocialConfigurer() { return new SpringSocialConfigurer() { @Override protected <T> T postProcess(T object) { SocialAuthenticationFilter filter = (SocialAuthenticationFilter) object; filter.setAuthenticationSuccessHandler(baiduAuthenticationSuccessHandlerSuccessHandler); return (T) filter; } }; } /** * 登录帮助类 * * @param connectionFactoryLocator * @param usersConnectionRepository * @return */ @Bean public ProviderSignInUtils providerSignInUtils(ConnectionFactoryLocator connectionFactoryLocator, UsersConnectionRepository usersConnectionRepository) { return new ProviderSignInUtils(new HttpSessionSessionStrategy(), connectionFactoryLocator, usersConnectionRepository); } }
10,spring security 配置
11,登录页面
12,用户信息显示
完整代码
百度登录:https://gitee.com/huan1993/spring-social-parent/tree/feature%2Fbaidu/
github登录:https://gitee.com/huan1993/spring-social-parent/tree/feature%2Fgithub/
QQ登录:https://gitee.com/huan1993/spring-social-parent/tree/feature%2Fqq/
微信登录:https://gitee.com/huan1993/spring-social-parent/tree/feature%2Fweixin/
百度&QQ&微信登录:https://gitee.com/huan1993/spring-social-parent/tree/master/
相关推荐
本教程是全网最细致地讲解Spring Security、Spring Social 、Spring Security OAuth三种技术开发安全的REST服务,彻底掌握一线互联网公司主流的身份认证和授权方式。 Spring Security是一个能够为基于Spring的企业...
Spring社交扩展框架 Spring Social ,Spring Social 是 Spring 框架的扩展,用来方便开发Web社交应用程序,可通过该项...
springboot+ spring security实现登录认证
Spring实现简单登录注册功能 1.注册信息写入mysql数据库 2.可以用注册的账号来进行登录 3.利用cookie,实现登录成功界面显示用户名 4.界面使用表单验证和ajax,进行规则判断和相应显示
教程视频:spring提供的安全权限框架,Spring Security、Spring Social 、Spring Security OAuth
Github社交联合登录 步骤 1. 创建开发者应用 登录GitHub,【Settings】--> 【Developer settings】-->【OAuth Apps】-->【New Oauth App】,然后填写应用...spring.social.github.app-secret=YOUR_APP_SECRET
用STS(Spring Tool Suite)开发的,spring mvc + spring security 实现的最简单的登录系统,无数据库。
spring-social-core,详情官网http://www.springsource.org/spring-social
Spring+Spring MVC+Spring JDBC+MySql实现简单登录注册
Spring+Hibernate实现用户登录程序,可执行,里面配置文件是正确的,在mysql中见一个wangwei数据库,再建个user表就可执行
Spring boot实现用户登录,转盘,并将获得的奖励记录数据库的功能,可以实现用户登录,并且查看自己获得的奖励,和其他所有人获得的奖励等功能
Spring Security源码分析三:Spring Social 实现QQ社交登录 Spring Security源码分析四:Spring Social 实现微信社交登录 Spring Security源码分析五:Spring Security 实现短信登录 Spring Security源码分析六:...
struts2+Spring2.5+Spring3.2)实现登录.struts2+Spring2.5+Spring3.2)实现登录.struts2+Spring2.5+Spring3.2)实现登录。
主要介绍了利用Spring Social轻松搞定微信授权登录的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
第1章 SpringCloud简介 第2章 SpringCache缓存详细讲解及应用 第3章 Redis高级缓存讲解及应用 第4章 SpringSecurity安全详细讲解及应用 第5章 RabbitMQ高级消息的讲解及应用 第6章 ElasticSearch详细讲解及应用 第7...
spring-social-google.zip,带有连接支持和google的api绑定的googleapipring社交扩展
Spring Cloud 安全:集成OAuth2实现身份认证和单点登录 示例代码 Spring Cloud 安全:集成OAuth2实现身份认证和单点登录 示例代码
剖析OAUTH 协议,探秘Spring Social 的功能,使用,下载和安装等等
去掉JAR包了。Spring+LDAP实现单点登录SSO 单点登录 LDAP SPRING
尚硅谷spring培训视频百度云资源,需要的下载吧