123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- package cn.com.qmth.mps.service.impl;
- import java.util.HashMap;
- import java.util.Map;
- import javax.crypto.Cipher;
- import javax.crypto.spec.IvParameterSpec;
- import javax.crypto.spec.SecretKeySpec;
- import org.apache.commons.lang3.StringUtils;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import com.qmth.boot.core.exception.StatusException;
- import com.qmth.boot.core.security.annotation.AuthorizationComponent;
- import com.qmth.boot.core.security.service.AuthorizationService;
- import com.qmth.boot.tools.signature.SignatureType;
- import com.qmth.boot.tools.uuid.FastUUID;
- import cn.com.qmth.mps.bean.User;
- import cn.com.qmth.mps.config.SysProperty;
- import cn.com.qmth.mps.entity.UserEntity;
- import cn.com.qmth.mps.entity.WxappAccessTokenEntity;
- import cn.com.qmth.mps.entity.WxappInfoEntity;
- import cn.com.qmth.mps.enums.Role;
- import cn.com.qmth.mps.exception.ParameterExceptions;
- import cn.com.qmth.mps.service.AuthService;
- import cn.com.qmth.mps.service.SessionService;
- import cn.com.qmth.mps.service.UserService;
- import cn.com.qmth.mps.service.WxappAccessTokenService;
- import cn.com.qmth.mps.service.WxappInfoService;
- import cn.com.qmth.mps.util.ByteUtil;
- import cn.com.qmth.mps.util.HttpUtil;
- import cn.com.qmth.mps.util.SHA256;
- import cn.com.qmth.mps.vo.AdminLoginVo;
- import net.sf.json.JSONObject;
- import sun.misc.BASE64Decoder;
- @AuthorizationComponent
- @Service
- public class AuthServiceImpl implements AuthorizationService<User>, AuthService {
- @Autowired
- private UserService userService;
- @Autowired
- private SessionService sessionService;
- @Autowired
- private WxappAccessTokenService wxappAccessTokenService;
- @Autowired
- private SysProperty sysProperty;
- @Autowired
- private WxappInfoService wxappInfoService;
- @Override
- public AdminLoginVo loginWxAppCode(String loginCode) {
- JSONObject auth=getAuthorization(loginCode);
- String openid=auth.getString("openid");
- WxappInfoEntity wi=wxappInfoService.getByOpenId(openid);
- if(wi==null) {
- throw ParameterExceptions.OPENID_NOT_FOUND;
- }
- UserEntity userEntity = userService.getByLoginName(wi.getPhone());
- if (userEntity == null) {
- throw new StatusException("微信所绑定手机号系统中不存在");
- }
- if (!userEntity.getEnable()) {
- throw new StatusException("该用户已禁用");
- }
- if (!userEntity.getRoleId().equals(Role.SECTION_LEADER.getId())) {
- throw new StatusException("该用户不是科组长");
- }
- User user = new User();
- user.setName(userEntity.getName());
- user.setSchoolId(userEntity.getSchoolId());
- user.setId(userEntity.getId());
- user.setRole(Role.getById(userEntity.getRoleId()));
- user.setAccessToken(FastUUID.get());
- user.buildKey();
- sessionService.userLogin(user);
- AdminLoginVo vo = new AdminLoginVo();
- vo.setAccessToken(user.getAccessToken());
- vo.setName(user.getName());
- vo.setSessionId(user.getSessionId());
- vo.setSchoolId(user.getSchoolId());
- vo.setRole(user.getRole());
- return vo;
- }
- @Override
- public AdminLoginVo loginAdmin(String loginName, String password) {
- UserEntity userEntity = userService.getByLoginName(loginName);
- if (userEntity == null) {
- throw new StatusException("账号不存在");
- }
- if (!userEntity.getEnable()) {
- throw new StatusException("该用户已禁用");
- }
- if (userEntity.getRoleId().equals(Role.SECTION_LEADER.getId())) {
- throw new StatusException("科组长无权限登录");
- }
- byte[] bytes = SHA256.encode(password);
- String encodePassword = ByteUtil.toHexAscii(bytes);
- if (!encodePassword.equals(userEntity.getPassword())) {
- throw new StatusException("密码错误");
- }
- User user = new User();
- user.setName(userEntity.getName());
- user.setSchoolId(userEntity.getSchoolId());
- user.setId(userEntity.getId());
- user.setRole(Role.getById(userEntity.getRoleId()));
- user.setAccessToken(FastUUID.get());
- user.buildKey();
- sessionService.userLogin(user);
- AdminLoginVo vo = new AdminLoginVo();
- vo.setAccessToken(user.getAccessToken());
- vo.setName(user.getName());
- vo.setSessionId(user.getSessionId());
- vo.setSchoolId(user.getSchoolId());
- vo.setRole(user.getRole());
- return vo;
- }
- @Override
- public void logout(User user) {
- sessionService.userLogout(user);
- }
- @Override
- public User findByIdentity(String identity, SignatureType type, String path) {
- User user = sessionService.getSessionUser(identity);
- return user;
- }
- @Override
- public boolean hasPermission(User user, String path) {
- sessionService.updateUserSession(user);
- return true;
- }
- @Override
- public void modifyWxappAccessToken() {
- WxappAccessTokenEntity token = wxappAccessTokenService.getWxappAccessToken();
- long now = System.currentTimeMillis();
- if (StringUtils.isEmpty(token.getAccessToken()) || token.getExpiresTime() - now <= 15 * 60 * 1000) {
- Map<String, String> params = new HashMap<>();
- params.put("appid", sysProperty.getWxappAppid());
- params.put("secret", sysProperty.getWxappSecret());
- params.put("grant_type", "client_credential");
- String ret;
- try {
- ret = HttpUtil.httpActionGet("https://api.weixin.qq.com/cgi-bin/token", null, params);
- } catch (Exception e) {
- throw new StatusException("获取失败", e);
- }
- JSONObject jo = JSONObject.fromObject(ret);
- if (jo.containsKey("errcode")) {
- throw new StatusException("获取失败," + jo.getString("errmsg"));
- }
- int ex = jo.getInt("expires_in");
- String at = jo.getString("access_token");
- token.setAccessToken(at);
- token.setExpiresTime(now + ex * 1000);
- wxappAccessTokenService.updateById(token);
- }
- }
- @Transactional
- @Override
- public AdminLoginVo loginWxAppByEncryptedData(String loginCode, String encryptedData, String iv) {
- JSONObject auth=getAuthorization(loginCode);
- String openid=auth.getString("openid");
- JSONObject jo=decrypt(encryptedData, iv, auth.getString("session_key"));
- String phone=jo.getString("purePhoneNumber");
- UserEntity userEntity = userService.getByLoginName(phone);
- if (userEntity == null) {
- throw new StatusException("微信所绑定手机号系统中不存在");
- }
- if (!userEntity.getEnable()) {
- throw new StatusException("该用户已禁用");
- }
- if (!userEntity.getRoleId().equals(Role.SECTION_LEADER.getId())) {
- throw new StatusException("该用户不是科组长");
- }
- WxappInfoEntity wi=wxappInfoService.getByOpenId(openid);
- if(wi==null) {
- wi=new WxappInfoEntity();
- wi.setOpenid(openid);
- }
- wi.setPhone(phone);
- wxappInfoService.saveOrUpdate(wi);
- User user = new User();
- user.setName(userEntity.getName());
- user.setSchoolId(userEntity.getSchoolId());
- user.setId(userEntity.getId());
- user.setRole(Role.getById(userEntity.getRoleId()));
- user.setAccessToken(FastUUID.get());
- user.buildKey();
- sessionService.userLogin(user);
- AdminLoginVo vo = new AdminLoginVo();
- vo.setAccessToken(user.getAccessToken());
- vo.setName(user.getName());
- vo.setSessionId(user.getSessionId());
- vo.setSchoolId(user.getSchoolId());
- vo.setRole(user.getRole());
- return vo;
- }
- private JSONObject getAuthorization(String loginCode) {
- Map<String, String> params = new HashMap<>();
- params.put("appid", sysProperty.getWxappAppid());
- params.put("secret", sysProperty.getWxappSecret());
- params.put("js_code", loginCode);
- params.put("grant_type", "authorization_code");
- String ret;
- try {
- ret = HttpUtil.httpActionGet("https://api.weixin.qq.com/sns/jscode2session", null, params);
- } catch (Exception e) {
- throw new StatusException("登录失败", e);
- }
- JSONObject jo = JSONObject.fromObject(ret);
- if (jo.containsKey("errcode")) {
- throw new StatusException("登录失败," + jo.getString("errmsg"));
- }
- return jo;
- }
- private JSONObject decrypt(String encryptedData, String iv, String sessionKey){
- String cipherString = "AES/CBC/PKCS5Padding";
- String jsonStr;
- try {
- BASE64Decoder base64Decoder = new BASE64Decoder();
- /**
- * 小程序加密数据解密算法
- * https://developers.weixin.qq.com/miniprogram/dev/api/signature.html#wxchecksessionobject
- * 1.对称解密的目标密文为 Base64_Decode(encryptedData)。 2.对称解密秘钥 aeskey =
- * Base64_Decode(session_key), aeskey 是16字节。 3.对称解密算法初始向量
- * 为Base64_Decode(iv),其中iv由数据接口返回。
- */
- byte[] encryptedByte = base64Decoder.decodeBuffer(encryptedData);
- byte[] sessionKeyByte = base64Decoder.decodeBuffer(sessionKey);
- byte[] ivByte = base64Decoder.decodeBuffer(iv);
- /**
- * 以下为AES-128-CBC解密算法
- */
- SecretKeySpec skeySpec = new SecretKeySpec(sessionKeyByte, "AES");
- Cipher cipher = Cipher.getInstance(cipherString);
- IvParameterSpec ivParameterSpec = new IvParameterSpec(ivByte);
- cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivParameterSpec);
- byte[] original = cipher.doFinal(encryptedByte);
- jsonStr = new String(original);
- } catch (Exception e) {
- throw new StatusException("登录失败,信息有误 ",e);
- }
- JSONObject jsonObject = JSONObject.fromObject(jsonStr);
- return jsonObject;
- }
- @Transactional
- @Override
- public AdminLoginVo loginWxAppByPhoneCode(String loginCode,String phoneCode) {
- Map<String, String> params = new HashMap<>();
- params.put("code", phoneCode);
- String ret;
- try {
- ret = HttpUtil.httpActionPost("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token="
- + wxappAccessTokenService.getWxappAccessToken().getAccessToken(), null, params);
- } catch (Exception e) {
- throw new StatusException("登录失败", e);
- }
- JSONObject jo = JSONObject.fromObject(ret);
- if (jo.getInt("errcode") != 0) {
- throw new StatusException("登录失败," + jo.getString("errmsg"));
- }
- String phone=jo.getJSONObject("phone_info").getString("purePhoneNumber");
- UserEntity userEntity = userService.getByLoginName(phone);
- if (userEntity == null) {
- throw new StatusException("微信所绑定手机号系统中不存在");
- }
- if (!userEntity.getEnable()) {
- throw new StatusException("该用户已禁用");
- }
- if (!userEntity.getRoleId().equals(Role.SECTION_LEADER.getId())) {
- throw new StatusException("该用户不是科组长");
- }
- JSONObject auth=getAuthorization(loginCode);
- String openid=auth.getString("openid");
- WxappInfoEntity wi=wxappInfoService.getByOpenId(openid);
- if(wi==null) {
- wi=new WxappInfoEntity();
- wi.setOpenid(openid);
- }
- wi.setPhone(phone);
- wxappInfoService.saveOrUpdate(wi);
- User user = new User();
- user.setName(userEntity.getName());
- user.setSchoolId(userEntity.getSchoolId());
- user.setId(userEntity.getId());
- user.setRole(Role.getById(userEntity.getRoleId()));
- user.setAccessToken(FastUUID.get());
- user.buildKey();
- sessionService.userLogin(user);
- AdminLoginVo vo = new AdminLoginVo();
- vo.setAccessToken(user.getAccessToken());
- vo.setName(user.getName());
- vo.setSessionId(user.getSessionId());
- vo.setSchoolId(user.getSchoolId());
- vo.setRole(user.getRole());
- return vo;
- }
- }
|