前言
上一节中我们已经处理完了
上一节中我们已经走完了oauth流程,拿到了服务提供商的信息,但是在交给OAuthenticationProvider处理时候出了问题,在SocialAuthenticationProvider处他把我们导向了signup的路径,下面我们看下为什么出现在这个结果。
SocialAuthenticationProvider类下的authenticate方法:
public Authentication authenticate(Authentication authentication) throws AuthenticationException { //1.判断是否是我们之前通过Connection组装的SocialAuthenticationToken授权对象 Assert.isInstanceOf(SocialAuthenticationToken.class, authentication, "unsupported authentication type"); Assert.isTrue(!authentication.isAuthenticated(), "already authenticated"); SocialAuthenticationToken authToken = (SocialAuthenticationToken)authentication; String providerId = authToken.getProviderId(); //2.connection里面封装了:qq的providerId(qq应用id)和providerUserId(qq应用上的用户id) Connection<?> connection = authToken.getConnection(); //3.根据connection里的roviderId和providerUserId去用户关联表查询对应业务系统的userId String userId = this.toUserId(connection); //4.第一次获取不到,会跑一个异常,异常最后会被:Social AuthenticationFilter获取到 if (userId == null) { throw new BadCredentialsException("Unknown access token"); } else { UserDetails userDetails = this.userDetailsService.loadUserByUserId(userId); if (userDetails == null) { throw new UsernameNotFoundException("Unknown connected account id"); } else { return new SocialAuthenticationToken(connection, userDetails, authToken.getProviderAccountData(), this.getAuthorities(providerId, userDetails)); } } } protected String toUserId(Connection<?> connection) { List<String> userIds = this.usersConnectionRepository.findUserIdsWithConnection(connection); return userIds.size() == 1 ? (String)userIds.iterator().next() : null; }
throw new BadCredentialsException("Unknown access token")抛去异常会被SocialAuthenticationFilter捕获到:如果你配置了一个signupUrl,那么就会跳转到signupUrl地址。
默认的signupUrl是"/signup";
因为我们没有对:signup做授权,所以会被拦截下来,然后跳转到需要授权的请求路径上:/authentication/require
内容
我们该怎样解决这个问题呢?其实很简单:我们自己写一个注册页,然后把signupUrl配置成我们自己写的注册页,最后再配置下授权,让那个注册页不经过身份认证就可以访问。
1.注册页
1.1 spring-security-web配置提示
1.1.1 配置页面
针对于不同的平台注册页信息不同,所以我们需要自定义注册页信息,这个信息是写在S配置文件中:具体注册页是在spring-security-demo里面自己写的。我们只会在spring-security-web时候做一个提示。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>注册</title> </head> <body> <h2>标准注册页面</h2> <h3>这是系统注册页面,请配置yxm.security.browser.signUpUrl属性来设置自己的注册页</h3> </body> </html>
1.1.2.BrowserProperties–添加注册页
有了上面配置项之后我们就可以在spring-security-demo里面去配置:
1.2 spring-security-demo里面具体些配置信息
在spring-security-demo里面,我们配置个性化的登录页:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>登录</title> </head> <body> <h2>Demo注册页</h2> <form action="/user/regist" method="post"> <table> <tr> <td>用户名:</td> <td><input type="text" name="username"></td> </tr> <tr> <td>密码:</td> <td><input type="password" name="password"></td> </tr> <tr> <td colspan="2"> <!--不存在的用户:我们是采用注册:regist--> <button type="submit" name="type" value="regist">注册</button> <!--已经存在的用户,我们是去做一个绑定--> <button type="submit" name="type" value="binding">绑定</button> </td> </tr> </table> </form> </body> </html>
1.3 spring-security-demo注册用户后端
我们在UserController里面注册用户
1.4 spring-security-web配置注册用户请求授权
我们授权signUp的请求,让系统不去拦截。
1.5 spring-security-core配置SocialConfig
让过滤器知道,找不到用户的时候,跳到我们指定的地址上去:
以上我们测试: 1.点击qq登录会转到需要在第三方授权的页面,然后授权之后会返回到第三方应用系统自带的登录页
2.现在有两个问题
- 第一针对于上面的登录页面;我们希望能将用户的QQ信息显示在登陆页上(比如:头像、账号等提示信息),这样界面更加友好.因为我们要考虑如何拿到用户登录的社交信息。
- 第二是我们点了注册后会跳转到我demo项目的注册方法register中进行处理,不管注册还是绑定,最终我们能获取到一个用户的唯一标识:UserId,我们如何把UserId传回给Spring Social;让Spring Social把用户id和之前拿到的社交信息一起一起存数据库中的yxm_UserConnect表中.
为了处理这两个问题,Spring提供了一个工具类ProviderSignInUtils.我们在SocialConfig中对其进行配置,其实他就解决了2个问题:
- 在注册过程中如何拿到Spring Social信息
- 注册完成之后,如何把业务系统的数据绑定到:Spring Social
2.1 spring Social信息获取
然后我们在WebSecurityController里面提供一个使用ProviderSignInUtils返回SocialUserInfo的方法
有了这些SocialUserInfo前台就能返回一个友好的用户提示来。
public class SocialUserInfo { private String providerId; private String providerUserId; private String nickname; private String headimg; //getter setter方法 }
我们从session里面获取到了对应的值,那么我们是什么时候放入到session里面的呢?
我们先把SocialUserInfo部门相关信息存储在session中,然后跳转到signUp,然后进入/social/user类中来设置用户信息。
2.2 配置UserController
我们将信息传给user后,到数据库中注册到User表,再用providerSignUitls到数据库中注册到Userconnetion表,因为需要从session中取值,所以还需呀传一个request.这里为了方便没写具体的注册逻辑.
这个路径按理说是demo项目里的路径,只有demo项目知道它要到这里面注册,在后面我们在授权的时候将只有用户知道的路径剥离,让用户自己去写.
输入QQ凭证,进入注册页,进行注册,userId为xxx,再次输入QQ凭证,可以直接进入系统,打印出的凭证显示userId为xxx.
3.现在有两个问题
原文
https://segmentfault.com/a/1190000022058687
本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » 22.SpringSecurity-处理注册逻辑