一、OAuth2.0 - 自定义模式授权

上篇文章我们分析了目前的情况,演示了微服务的大环境下在保证安全的情况下通过SpringGateWay实现统一的鉴权处理,但是前面的演示中,我们都是基于用户名密码的方式,但是现在已经普及短信验证码登录、微信登录、QQ登录等这些第三方的登录方式,这些方式显然不在Oauth2.0提供的四种授权模式下,因此我们如果要实现第三方的登录需要自定义一个授权模式,下面我们就以短信验证码登录为例进行实现。

下面是上篇文章的地址:

https://blog.csdn.net/qq_43692950/article/details/122566821

二、短信验证码登录

SpringOauth2.0虽说只有四种授权模式,但是他提供了非常高的扩展性,我们可以很方便的进行授权模式的扩展,而无需大量的改动,在SpringOauth2.0中扩展授权模式,只需继承AbstractTokenGranter类,并在构造方法中super父类时,指定自己的授权标识,当用户认证传入grant_type为该标识,则会触发该生成器的getOAuth2Authentication方法,我们可以在这里获取客户端传入的参数,比如手机号和验证码,然后我们再和预先的验证码对比,如果OK,可以根据手机号获取用户的信息组成UsernamePasswordAuthenticationToken对象再交给Oauth2即可:

下面编写一个SmsCodeTokenGranter这里只是演示功能,直接将用户和验证码写死了:

public class SmsCodeTokenGranter extends AbstractTokenGranter {private static final String SMS_GRANT_TYPE = "sms_code";private UserService userService;public SmsCodeTokenGranter(AuthorizationServerTokenServices tokenServices,ClientDetailsService clientDetailsService,OAuth2RequestFactory requestFactory,UserService userService) {super(tokenServices, clientDetailsService, requestFactory, SMS_GRANT_TYPE);this.userService = userService;}@Overrideprotected OAuth2Authentication getOAuth2Authentication(ClientDetails client,TokenRequest tokenRequest) {Map<String, String> parameters = new LinkedHashMap<String, String>(tokenRequest.getRequestParameters());System.out.println(parameters.toString());// 客户端提交的手机号码String phoneNumber = parameters.get("phone");if (StringUtils.isBlank(phoneNumber)) {throw new AccessDeniedException("get phone is null !");}// 客户端提交的验证码String smsCode = parameters.get("code");if (!smsCode.equals("9876")) {throw new AccessDeniedException("code err!");}UserDetails user = userService.loadUserByUsername("admin");AbstractAuthenticationToken userAuth = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());userAuth.setDetails(parameters);OAuth2Request oAuth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest);return new OAuth2Authentication(oAuth2Request, userAuth);}
}

下面还需修改AuthorizationServer将上面的生成器配制进AuthorizationServerEndpointsConfigurer中:

@Configuration
@EnableAuthorizationServer
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {@Autowiredprivate TokenStore tokenStore;@Autowired@Qualifier("jdbcClientDetailsService")private ClientDetailsService clientDetailsService;@Autowiredprivate AuthenticationManager authenticationManager;@Autowiredprivate AuthorizationCodeServices authorizationCodeServices;@Autowiredprivate JwtAccessTokenConverter accessTokenConverter;@AutowiredUserService userService;@AutowiredPasswordEncoder passwordEncoder;@Bean("jdbcClientDetailsService")public ClientDetailsService clientDetailsService(DataSource dataSource) {JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource);clientDetailsService.setPasswordEncoder(passwordEncoder);return clientDetailsService;}@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.withClientDetails(clientDetailsService);}@Beanpublic AuthorizationCodeServices authorizationCodeServices(DataSource dataSource) {return new JdbcAuthorizationCodeServices(dataSource);//设置授权码模式的授权码如何存取}@Beanpublic AuthorizationServerTokenServices tokenService() {DefaultTokenServices service = new DefaultTokenServices();service.setClientDetailsService(clientDetailsService);service.setSupportRefreshToken(true);service.setTokenStore(tokenStore);//令牌增强TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();List<TokenEnhancer> tokenEnhancers = new ArrayList<>();//内容增强tokenEnhancers.add(tokenEnhancer());tokenEnhancers.add(accessTokenConverter);tokenEnhancerChain.setTokenEnhancers(tokenEnhancers);service.setTokenEnhancer(tokenEnhancerChain);service.setAccessTokenValiditySeconds(7200); // 令牌默认有效期2小时service.setRefreshTokenValiditySeconds(259200); // 刷新令牌默认有效期3天return service;}@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) {endpoints.authenticationManager(authenticationManager)//认证管理器.authorizationCodeServices(authorizationCodeServices)//授权码服务.tokenGranter(tokenGranter(endpoints)).tokenServices(tokenService())//令牌管理服务.allowedTokenEndpointRequestMethods(HttpMethod.POST);}@Overridepublic void configure(AuthorizationServerSecurityConfigurer security) throws Exception {security.tokenKeyAccess("permitAll()")                    //oauth/token_key是公开.checkTokenAccess("permitAll()")                  //oauth/check_token公开.allowFormAuthenticationForClients();                //表单认证(申请令牌)}/*** JWT内容增强*/@Beanpublic TokenEnhancer tokenEnhancer() {return (accessToken, authentication) -> {Map<String, Object> additionalInfo = new HashMap<>();additionalInfo.put("userid", -1);Authentication auth = authentication.getUserAuthentication();if (auth != null) {UserEntity user = (UserEntity) auth.getPrincipal();additionalInfo.put("userid", user.getId());}else {String clientId = authentication.getOAuth2Request().getClientId();String grantType = authentication.getOAuth2Request().getRequestParameters().get("grant_type");if (Objects.equals(clientId, "c1") && Objects.equals(grantType, "client_credentials")) {additionalInfo.put("userid", "root");}}((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);return accessToken;};}/*** 添加自定义授权类型** @return List<TokenGranter>*/private TokenGranter tokenGranter(AuthorizationServerEndpointsConfigurer endpoints) {// endpoints.getTokenGranter() 获取SpringSecurity OAuth2.0 现有的授权类型List<TokenGranter> granters = new ArrayList<TokenGranter>(Collections.singletonList(endpoints.getTokenGranter()));// 构建短信验证授权类型SmsCodeTokenGranter smsCodeTokenGranter = new SmsCodeTokenGranter(endpoints.getTokenServices(), endpoints.getClientDetailsService(),endpoints.getOAuth2RequestFactory(),userService);// 向集合中添加短信授权类型granters.add(smsCodeTokenGranter);// 返回所有类型return new CompositeTokenGranter(granters);}}

三、测试

使用PostMan发送POST请求:

http://localhost:8020/oauth/token?client_id=c1&client_secret=secret&grant_type=sms_code&phone=110&code=9562

注意:grant_type要传sms_code

可以看到返回的是Unauthorized grant type: sms_code未授权的类型,这个是因为c1这个客户端没有sms_code认证类型,给c1添加上sms_code类型:


下面重新测试:

已经有我我们写的返回了,下面输入正确的验证码:

http://localhost:8020/oauth/token?client_id=c1&client_secret=secret&grant_type=sms_code&phone=110&code=9876


已经成功获取到令牌。


喜欢的小伙伴可以关注我的个人微信公众号,获取更多学习资料!

OAuth2.0 - 自定义模式授权 - 短信验证码登录相关推荐

  1. SpringBoot OAuth2.0 使用短信验证码登录授权

    SpringBoot OAuth2.0 使用短信验证码登录授权 实现步骤: 自定义授权器,继承 AbstractTokenGranter 类: 重写 getOAuth2Authentication 函 ...

  2. Spring Security OAuth2 优雅的集成短信验证码登录以及第三方登录

    基于SpringCloud做微服务架构分布式系统时,OAuth2.0作为认证的业内标准,Spring Security OAuth2也提供了全套的解决方案来支持在Spring Cloud/Spring ...

  3. cas5.3.9自定义手机短信验证码登录

    cas自定义多种登录方式 cas添加手机短信验证码登录 cas添加手机短信验证码登录 全部基于SpringBoot,以及SpringWebflow开发,请在有此基础再进行学习! 添加Maven依赖 & ...

  4. 短信验证码登录,以及第三方登录

    短信验证码登录 首先去阿里云服务器开通短信服务功能,进入短信服务界面 点击国内消息,申请一个签名和模板 申请一个AccessKey,并且将短信服务的权限加入其中 加入相关的依赖 <depende ...

  5. 5.Spring Security 短信验证码登录

    Spring Security 短信验证码登录 在 Spring Security 添加图形验证码一节中,我们已经实现了基于 Spring Boot + Spring Security 的账号密码登录 ...

  6. 手机短信验证码登录功能的开发实录(机器识别码、短信限流、错误提示、发送验证码倒计时60秒)

    短信验证码登录功能 项目分析 核心代码 1.外部js库调用 2.HTML容器构建 3.javaScript业务逻辑验证 4.后端验证逻辑 总结 短信验证码是通过发送验证码到手机的一种有效的验证码系统, ...

  7. SpringSecurity短信验证码登录

    短信验证码登录 时下另一种非常常见的网站登录方式为手机短信验证码登录,但Spring Security默认只提供了账号密码的登录认证逻辑,所以要实现手机短信验证码登录认证功能,我们需要模仿Spring ...

  8. Redis(2)短信验证码登录

    Redis实现短信验证码登录 登录流程 1.发送验证码: 2.短信验证码登录,注册 3.校验登录状态 解决状态登录刷新问题 redis指令参考:https://blog.csdn.net/weixin ...

  9. Spring Security 短信验证码登录(5)

    在Spring Security添加图形验证码中,我们已经实现了基于Spring Boot + Spring Security的账号密码登录,并集成了图形验证码功能.时下另一种非常常见的网站登录方式为 ...

最新文章

  1. pycharm 无法导包、无法导入模块(模块名不能含有连接符“-”)
  2. Macbook m1 install Homebrew
  3. POJ 3750 小孩报数问题
  4. attribute java c_属性别名(Attribute Aliasing)
  5. linux添加文件后无法启动,linux安装后grub无法启动
  6. 修改Tomcat端口号
  7. Run-time error “70“:Permission denied
  8. 不同php文件,不同文件构建PHP程序的正确方式
  9. 计算机二级 java和web_2016计算机二级web程序设计判断题及答案
  10. 2019.2.18接口2
  11. Matlab R2016a安装教程
  12. ECRS分析原则(转载)
  13. 基于人工萤火虫优化(GSO)算法的函数寻优算法
  14. 发送邮件被对方服务器退回_国内邮件群发
  15. Unity图片闪烁效果
  16. 【单片机】温度感应报警装置的设计与制作(说明书)
  17. sqlserver进阶必会基础入门不止select into from 插入数据必知
  18. cartographer源码解析(二)node_main.cc文件详解
  19. 宣城市高新技术企业认定补贴政策 申报流程整理分析
  20. mysql.data.dll 位置_MySql.Data.dll,下载,简介,描述,修复,等相关问题一站搞定_DLL之家...

热门文章

  1. 01.04_计算机基础知识(键盘功能键和快捷键)
  2. 图片按指定比例缩放并压缩至指定大小,解决保存图片文件体积过大bug。
  3. 【玩转微信公众平台之二】 账号注册
  4. HObject,unsigned char的相互转换
  5. 一文告诉你哪些map element类型支持就地更新
  6. 神经网络模型的工作原理,人脑神经网络模型
  7. 多元统计分析-橄榄油数据集
  8. 随机生成26个英文字母
  9. 第12节 实例-挖方填方量的计算
  10. 免费数据库应用程序工具 - 不需代码