package com.cm.serviceusercenter.authentication.dingding; import com.cm.common.dingding.service.IDingDingAppUserService; import com.cm.common.exception.SearchException; import com.cm.common.pojo.bos.UserBO; import com.cm.serviceusercenter.authentication.user.UserAuthenticationToken; import com.cm.serviceusercenter.config.properties.DingDingScanCodeLoginProperties; import com.cm.serviceusercenter.enums.LoginType; import com.cm.serviceusercenter.exception.UserAuthenticationException; import com.cm.serviceusercenter.service.UserLoginService; import com.dingtalk.api.DefaultDingTalkClient; import com.dingtalk.api.request.OapiSnsGetuserinfoBycodeRequest; import com.dingtalk.api.response.OapiSnsGetuserinfoBycodeResponse; import com.dingtalk.api.response.OapiUserGetResponse; import com.taobao.api.ApiException; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.userdetails.UserDetailsService; /** * When you feel like quitting. Think about why you started * 当你想要放弃的时候,想想当初你为何开始 * * @ClassName: DingDingAuthenticationProvider * @Description: 钉钉登陆认证 * @Author: WangGeng * @Date: 2020/8/31 15:10 * @Version: 1.0 **/ public class DingDingAuthenticationProvider implements AuthenticationProvider { private static final Logger LOG = LoggerFactory.getLogger(DingDingAuthenticationProvider.class); private DingDingScanCodeLoginProperties dingDingScanCodeLoginProperties; private IDingDingAppUserService dingDingAppUserService; private UserDetailsService userDetailsService; private UserLoginService userLoginService; @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { DingDingAuthenticationToken dingDingAuthenticationToken = (DingDingAuthenticationToken) authentication; String userMobile = null; try { String unionId = getUnionIdByTmpAuthCode(dingDingAuthenticationToken.getPrincipal().toString()); String userId = dingDingAppUserService.getUserIdByUnionId(unionId); OapiUserGetResponse oapiUserGetResponse = dingDingAppUserService.getUserByUserId(userId); userMobile = oapiUserGetResponse.getMobile(); } catch (SearchException e) { throw new UserAuthenticationException(e.getMessage()); } if (StringUtils.isBlank(userMobile)) { throw new UserAuthenticationException("钉钉账号未绑定手机号,请绑定后再试"); } UserBO userBO = (UserBO) userDetailsService.loadUserByUsername(userMobile); if (userBO == null) { throw new UserAuthenticationException("该钉钉手机号账号不在系统中,请联系管理员"); } userLoginService.updateUserLoginInfo(userBO.getUserId(), userBO.getUserName(), LoginType.DING_DING_SCAN_CODE.getValue()); DingDingAuthenticationToken dingDingAuthenticationTokenResult = new DingDingAuthenticationToken(userBO, null, userBO.getAuthorities()); dingDingAuthenticationTokenResult.setDetails(dingDingAuthenticationToken.getDetails()); return dingDingAuthenticationTokenResult; } @Override public boolean supports(Class authentication) { return DingDingAuthenticationToken.class.isAssignableFrom(authentication); } public void setDingDingScanCodeLoginProperties(DingDingScanCodeLoginProperties dingDingScanCodeLoginProperties) { this.dingDingScanCodeLoginProperties = dingDingScanCodeLoginProperties; } public void setDingDingAppUserService(IDingDingAppUserService dingDingAppUserService) { this.dingDingAppUserService = dingDingAppUserService; } public void setUserDetailsService(UserDetailsService userDetailsService) { this.userDetailsService = userDetailsService; } public void setUserLoginService(UserLoginService userLoginService) { this.userLoginService = userLoginService; } /** * 获取用户unionId * * @param tmpAuthCode * @return */ private String getUnionIdByTmpAuthCode(String tmpAuthCode) { DefaultDingTalkClient defaultDingTalkClient = new DefaultDingTalkClient(dingDingScanCodeLoginProperties.getUserinfoUrl()); OapiSnsGetuserinfoBycodeRequest oapiSnsGetuserinfoBycodeRequest = new OapiSnsGetuserinfoBycodeRequest(); oapiSnsGetuserinfoBycodeRequest.setTmpAuthCode(tmpAuthCode); try { OapiSnsGetuserinfoBycodeResponse oapiSnsGetuserinfoBycodeResponse = defaultDingTalkClient.execute(oapiSnsGetuserinfoBycodeRequest, dingDingScanCodeLoginProperties.getAppId(), dingDingScanCodeLoginProperties.getAppSecret()); if (oapiSnsGetuserinfoBycodeResponse.getErrcode() != 0) { throw new SearchException(oapiSnsGetuserinfoBycodeResponse.getErrmsg()); } return oapiSnsGetuserinfoBycodeResponse.getUserInfo().getUnionid(); } catch (ApiException e) { LOG.error(e.getMessage(), e); throw new SearchException("钉钉扫码失败"); } } }