100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > springcloud oauth2 认证服务器自定义手机短信验证码登录

springcloud oauth2 认证服务器自定义手机短信验证码登录

时间:2021-02-19 09:58:31

相关推荐

springcloud oauth2 认证服务器自定义手机短信验证码登录

这里写自定义目录标题

介绍自定义授权类型(短信验证码等)测试

介绍

您已经知道,oauth2常见的授权类型authorization_code(授权码模式),password(密码模式)在spring security中都有相对于的实现,我们从AbstractTokenGranter类中可以看到一些token授予的实现。

自定义授权类型(短信验证码等)

我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:

继承抽象类AbstractTokenGranter,我们也是抽象的,后面好扩展;

/*** 自定义token授予抽象实现*/public abstract class CustomAbstractTokenGranter extends AbstractTokenGranter {CustomAbstractTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, String grantType) {super(tokenServices, clientDetailsService, requestFactory, grantType);}@Overrideprotected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {Map<String, String> parameters = tokenRequest.getRequestParameters();UserDetails details = getUserDetails(parameters);if (null == details) {throw new InvalidGrantException("账户未找到");}Authentication userAuth = new UsernamePasswordAuthenticationToken(details,details.getPassword(), details.getAuthorities());OAuth2Request storedOAuth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest);return new OAuth2Authentication(storedOAuth2Request, userAuth);/*这段已经弃用了,用这种写法会出现即使你重写了getAuthorities方法,访问也没有权限403,让你产生明明给你登录的用户设置了角色或者权限,但是却访问无权限403的错觉。这种写法是没有将authorities(OAuth2Authentication的父类AbstractAuthenticationToken的属性 )的值给设置上去,authorities永远都是一个空数组。OAuth2Authentication authentication = super.getOAuth2Authentication(client, tokenRequest);authentication.setDetails(details);authentication.setAuthenticated(true);return authentication;*/![在这里插入图片描述](https://img-/1228002332851.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzMzk2NjA4,size_16,color_FFFFFF,t_70)}/*** 自定义获取用户信息*/protected abstract UserDetails getUserDetails(Map<String, String> parameters);}

定义短信验证码具体逻辑

/*** 手机号-短信验证码*/public class PhoneSmsTokenGranter extends CustomAbstractTokenGranter {private static final String PHONE_SMS = "phone_sms";private CustomUserDetailService customUserDetailService;public PhoneSmsTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, CustomUserDetailService customUserDetailService) {super(tokenServices, clientDetailsService, requestFactory, PHONE_SMS);this.customUserDetailService = customUserDetailService;}@Overrideprotected UserDetails getUserDetails(Map<String, String> parameters) {String phone = parameters.get("phone");String smsCode = parameters.get("sms_code");return userDetailsService.loadUserByPhone(phone,smsCode);}}

自定义的获取用户信息

@Servicepublic class CustomUserDetailService {UserDetails loadUserByPhone(String phone, String code) {//在验证手机号和验证码if (!"123456".equals(code)) {throw new InvalidGrantException("验证码错误或已过期");}return new User(phone, "", AuthorityUtils.createAuthorityList("user:add", "user:delete"));}//按照这个思路你可以自定义二维码登录等}

在你的授权服务器@EnableAuthorizationServerl类加入自定义的token授予

@Autowiredprivate CustomUserDetailService customUserDetailService;/*** 定义授权(authorization)和令牌端点(token)以及令牌服务(token services)** @param endpoints 配置*/@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) {//...//在原有授权的基础上增加自定义手机号短信登录List<TokenGranter> tokenGranters = getTokenGranters(endpoints.getTokenServices(), endpoints.getClientDetailsService(), endpoints.getOAuth2RequestFactory());//原有的授权endpoints.getTokenGranter()tokenGranters.add(endpoints.getTokenGranter());endpoints.tokenGranter(new CompositeTokenGranter(tokenGranters));}/*** 自定义TokenGranter集合*/private List<TokenGranter> getTokenGranters(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory) {return new ArrayList<>(Collections.singletonList(new PhoneSmsTokenGranter(tokenServices, clientDetailsService, requestFactory, customUserDetailService)));}

测试

由于我的客户端信息是在数据库的,所以得加上自定义的phone_sms类型,如果您的在内存或其他也需要给客户端加上自定义的授权类型

由于这个短信登录是给app端用的,这些client_id,secret是没有给app开发者的,所以app短信登录是没有直接访问默认的/oauth/token的,这里内部通过Feign请求了,并且办法的凭证进行了jwt签名(由各自需求而定)

短信验证码也在controller层进行了验证,后面的只是为了给用户颁发凭证,如果您需要在service验证,就需要把sms_code给传过去

自定义授权参考网络并在自己业务中实现

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。