Browse Source

认证中心-i健康用户登录

LiTaohong 5 years ago
parent
commit
ca576d15c2

+ 4 - 0
server/svr-authentication/src/main/java/com/yihu/jw/security/oauth2/config/WlyyAuthorizationServerConfigurerAdapter.java

@ -4,6 +4,7 @@ import com.yihu.jw.security.oauth2.provider.client.WlyyJdbcClientRedirectUriServ
import com.yihu.jw.security.oauth2.provider.WlyyTokenGranter;
import com.yihu.jw.security.oauth2.core.redis.WlyyRedisVerifyCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@ -83,6 +84,7 @@ public class WlyyAuthorizationServerConfigurerAdapter extends AuthorizationServe
    @Bean
    RedisTokenStore redisTokenStore() {
//        return null;
        return new RedisTokenStore(jedisConnectionFactory);
    }
@ -92,8 +94,10 @@ public class WlyyAuthorizationServerConfigurerAdapter extends AuthorizationServe
    }
    @Bean
    @Primary
    AuthorizationCodeServices authorizationCodeServices() {
        return new InMemoryAuthorizationCodeServices();
//        return null;
    }
    @Bean

+ 64 - 60
server/svr-authentication/src/main/java/com/yihu/jw/security/oauth2/provider/endpoint/WlyyLoginEndpoint.java

@ -98,13 +98,13 @@ public class WlyyLoginEndpoint extends AbstractEndpoint {
    /**
     * 登陆
     * @param parameters
     * 不定入参:
     * client_id 应用标识
     * captcha 验证码
     * password 密码
     * username 用户名/手机/身份证号
     * login_type 用户类型 1或默认为user,2:医生登录,3:患者登录
     *
     * @param parameters  不定入参:
     *                    client_id 应用标识
     *                    captcha 验证码
     *                    password 密码
     *                    username 用户名/手机/身份证号
     *                    login_type 用户类型 1或默认为user,2:医生登录,3:患者登录
     * @param httpSession
     * @return
     * @throws Exception
@ -124,12 +124,12 @@ public class WlyyLoginEndpoint extends AbstractEndpoint {
            //解密密码
            if (parameters.get("password") != null) {
//                RSAPrivateKey rsaPrivateKey = (RSAPrivateKey)httpSession.getAttribute("privateKey");
                KeyPair keyPair = (KeyPair)httpSession.getAttribute("privateKey");
//                KeyPair keyPair = (KeyPair) httpSession.getAttribute("privateKey");
//                parameters.put("password", RSAUtils.decryptByPrivateKey(parameters.get("password"), rsaPrivateKey));
                String password = com.yihu.jw.security.utils.RSAUtils.decryptBase64(parameters.get("password"),keyPair);
                parameters.put("password",password);
//                String password = com.yihu.jw.security.utils.RSAUtils.decryptBase64(parameters.get("password"), keyPair);
//                parameters.put("password", password);
//                parameters.put("password", RSAUtils.decryptByPrivateKey(parameters.get("password"), rsaPrivateKey));
            }else {
            } else {
                parameters.put("grant_type", "ihealthCode");
            }
        } else {
@ -137,7 +137,7 @@ public class WlyyLoginEndpoint extends AbstractEndpoint {
        }
        ClientDetails authenticatedClient = clientDetailsService.loadClientByClientId(client_id);
        if(null == authenticatedClient){
        if (null == authenticatedClient) {
            throw new InvalidRequestException("client_id");
        }
        TokenRequest tokenRequest = oAuth2RequestFactory.createTokenRequest(parameters, authenticatedClient);
@ -149,15 +149,15 @@ public class WlyyLoginEndpoint extends AbstractEndpoint {
        /*如果是移动端登陆则移除之前的token,
        在网关处通过HTTP状态码告知前端是过期(402)还是账号在别处登陆(403),
        实现同一账号只能在一处登陆*/
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//        if (request.getHeader("login-device") != null && request.getHeader("login-device").equals("mobile")) {
        tokenStore.removeAccessToken(token.getValue());
        tokenStore.removeRefreshToken(token.getRefreshToken().getValue());
        token = getTokenGranter().grant(tokenRequest.getGrantType(), tokenRequest);
//            tokenStore.removeAccessToken(token.getValue());
//            tokenStore.removeRefreshToken(token.getRefreshToken().getValue());
//            token = getTokenGranter().grant(tokenRequest.getGrantType(), tokenRequest);
//        }
//        if (token == null) {
//            throw new UnsupportedGrantTypeException("Unsupported grant type: " + tokenRequest.getGrantType());
//        }
        if (token == null) {
            throw new UnsupportedGrantTypeException("Unsupported grant type: " + tokenRequest.getGrantType());
        }
        WlyyUserSimple wlyyUserSimple = userDetailsService.authSuccess(parameters.get("username"));
        wlyyUserSimple.setAccessToken(token.getValue());
        wlyyUserSimple.setTokenType(token.getTokenType());
@ -169,15 +169,15 @@ public class WlyyLoginEndpoint extends AbstractEndpoint {
        String openid = parameters.get("openid");
        //更新患者openId
        BaseLoginLogDO baseLoginLogDO = new BaseLoginLogDO();
        if(!StringUtils.isEmpty(openid) && !"undefined".equalsIgnoreCase(openid) && "3".equals(loginType)){
        if (!StringUtils.isEmpty(openid) && !"undefined".equalsIgnoreCase(openid) && "3".equals(loginType)) {
            baseLoginLogDO.setOpenid(openid);
            userDetailsService.updateOpenId(openid,wlyyUserSimple.getId());
            userDetailsService.updateOpenId(openid, wlyyUserSimple.getId());
        }
        if (parameters.get("password") != null) {
            //使用密码登录成功后, 更新失败次数为 0
            userDetailsService.addFailureCount(username,0);
            userDetailsService.addFailureCount(username, 0);
        }
        userDetailsService.setRolePhth(loginType,token,wlyyUserSimple.getId(),redisTemplate);
        userDetailsService.setRolePhth(loginType, token, wlyyUserSimple.getId(), redisTemplate);
        baseLoginLogDO.setUserId(wlyyUserSimple.getId());
        baseLoginLogDO.setCreateTime(new Date());
@ -191,6 +191,7 @@ public class WlyyLoginEndpoint extends AbstractEndpoint {
    /**
     * 单点登陆第二步 - token验证
     *
     * @param parameters
     * @return
     */
@ -231,15 +232,14 @@ public class WlyyLoginEndpoint extends AbstractEndpoint {
    }
    /**
     *
     * @param openid
     * @return
     */
    @RequestMapping(value = "/oauth/getByOpenId", method = RequestMethod.POST)
    public ResponseEntity<Oauth2Envelop<WlyyUserSimple>> getByOpenId( @RequestParam(value = "openid", required = true) String openid) {
    public ResponseEntity<Oauth2Envelop<WlyyUserSimple>> getByOpenId(@RequestParam(value = "openid", required = true) String openid) {
        BaseLoginLogDO loginLog = baseLoginLogService.findByOpenId(openid);
        if(loginLog== null){
            throw new UsernameNotFoundException("can't find login log by openod: "+openid);
        if (loginLog == null) {
            throw new UsernameNotFoundException("can't find login log by openod: " + openid);
        }
        String userAgent = loginLog.getUserAgent();
        WlyyUserSimple wlyyUserSimple = JSONObject.parseObject(userAgent, WlyyUserSimple.class);
@ -253,6 +253,7 @@ public class WlyyLoginEndpoint extends AbstractEndpoint {
    /**
     * 登出
     *
     * @param parameters
     * @param request
     * @return
@ -277,13 +278,14 @@ public class WlyyLoginEndpoint extends AbstractEndpoint {
    /**
     * 获取公钥
     *
     * @param httpSession
     * @param httpServletResponse
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/oauth/public_key", method = RequestMethod.GET)
    public ResponseEntity<Oauth2Envelop<PublicKey>> publicKey (
    public ResponseEntity<Oauth2Envelop<PublicKey>> publicKey(
            HttpSession httpSession,
            HttpServletResponse httpServletResponse) throws Exception {
        //生成公钥和私钥
@ -313,28 +315,29 @@ public class WlyyLoginEndpoint extends AbstractEndpoint {
    }
    @RequestMapping(value = "/oauth/getPublicKey", method = RequestMethod.GET)
    public ObjEnvelop<PublickeyVO> getPublicKey(HttpSession httpSession, HttpServletResponse httpServletResponse){
        KeyPair keyPair =  com.yihu.jw.security.utils.RSAUtils.getKey();
    public ObjEnvelop<PublickeyVO> getPublicKey(HttpSession httpSession, HttpServletResponse httpServletResponse) {
        KeyPair keyPair = com.yihu.jw.security.utils.RSAUtils.getKey();
        httpSession.setAttribute("privateKey", keyPair);
        PublickeyVO pk = new PublickeyVO();
        pk.setPublicKey(com.yihu.jw.security.utils.RSAUtils.generateBase64PublicKey(keyPair));
        return ObjEnvelop.getSuccess("success",pk);
        return ObjEnvelop.getSuccess("success", pk);
    }
    /**
     * 获取验证码
     *
     * @param parameters
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/oauth/captcha", method = RequestMethod.GET)
    public ResponseEntity<Oauth2Envelop<Captcha>> captcha(@RequestParam Map<String, String> parameters) throws  Exception{
    public ResponseEntity<Oauth2Envelop<Captcha>> captcha(@RequestParam Map<String, String> parameters) throws Exception {
        String client_id = parameters.get("client_id");
        String username = parameters.get("username");
        if (StringUtils.isEmpty(client_id)) {
            throw new InvalidRequestException("client_id");
        }
        if (StringUtils.isEmpty(username)){
        if (StringUtils.isEmpty(username)) {
            throw new InvalidRequestException("username");
        }
        //验证请求间隔超时,防止频繁获取验证码
@ -350,8 +353,8 @@ public class WlyyLoginEndpoint extends AbstractEndpoint {
        params.add("to", username);
        HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(params, reqHeaders);
        HashMap<String, Object> result = restTemplate.postForObject("http://svr-base:10020/sms_gateway/send", httpEntity, HashMap.class);
        if (200 == (Integer) result.get("status")){
            Map<String, Object> sms =  (Map)result.get("obj");
        if (200 == (Integer) result.get("status")) {
            Map<String, Object> sms = (Map) result.get("obj");
            String captcha = (String) sms.get("captcha");
            Date deadline = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse((String) sms.get("deadline"));
            Long expire = (deadline.getTime() - System.currentTimeMillis()) / 1000;
@ -369,7 +372,7 @@ public class WlyyLoginEndpoint extends AbstractEndpoint {
        try {
            JSONObject jsonStr = JSONObject.parseObject(message);
            if(jsonStr.containsKey("Message")){
            if (jsonStr.containsKey("Message")) {
                message = jsonStr.getString("Message");
            }
        } catch (Exception e) {
@ -390,22 +393,23 @@ public class WlyyLoginEndpoint extends AbstractEndpoint {
    /**
     * 验证验证码
     *
     * @param parameters
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/oauth/captcha", method = RequestMethod.POST)
    public ResponseEntity<Oauth2Envelop> captchaCheck  (@RequestParam Map<String, String> parameters) throws  Exception{
    public ResponseEntity<Oauth2Envelop> captchaCheck(@RequestParam Map<String, String> parameters) throws Exception {
        String client_id = parameters.get("client_id");
        String username = parameters.get("username");
        String captcha = parameters.get("captcha");
        if (StringUtils.isEmpty(client_id)) {
            throw new InvalidRequestException("client_id");
        }
        if (StringUtils.isEmpty(username)){
        if (StringUtils.isEmpty(username)) {
            throw new InvalidRequestException("username");
        }
        if (StringUtils.isEmpty(captcha)){
        if (StringUtils.isEmpty(captcha)) {
            throw new InvalidRequestException("captcha");
        }
        Oauth2Envelop<Boolean> oauth2Envelop;
@ -422,13 +426,13 @@ public class WlyyLoginEndpoint extends AbstractEndpoint {
    /**
     * 登陆
     * @param parameters
     * 不定入参:
     * login_type 用户类型 1或默认为user,2:医生登录,3:患者登录
     * mobile:手机号
     * captcha:验证码
     * clientId:
     * login_type 用户类型 1或默认为user,2:医生登录,3:患者登录
     *
     * @param parameters  不定入参:
     *                    login_type 用户类型 1或默认为user,2:医生登录,3:患者登录
     *                    mobile:手机号
     *                    captcha:验证码
     *                    clientId:
     *                    login_type 用户类型 1或默认为user,2:医生登录,3:患者登录
     * @param httpSession
     * @return
     * @throws Exception
@ -446,7 +450,7 @@ public class WlyyLoginEndpoint extends AbstractEndpoint {
            throw new InvalidRequestException("regist type is null");
        }
        //type :1居民  2:医生
        if("3".equals(type)){
        if ("3".equals(type)) {
            String mobile = parameters.get("mobile");
            String captcha = parameters.get("captcha");
            HttpHeaders reqHeaders = new HttpHeaders();
@ -456,18 +460,18 @@ public class WlyyLoginEndpoint extends AbstractEndpoint {
            params.add("openid", parameters.get("openid"));
            HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(params, reqHeaders);
            Map<String, Object> result = restTemplate.postForObject("http://svr-patient:10021/basePatient/regist", httpEntity, HashMap.class);//svr-patient
            Map<String,Object> obj = (Map<String, Object>) result.get("obj");
            if("1".equals(obj.get("code")+"")){
            Map<String, Object> obj = (Map<String, Object>) result.get("obj");
            if ("1".equals(obj.get("code") + "")) {
                registFlag = true;
                parameters.put("username",mobile);
                parameters.put("username", mobile);
                wlyyRedisVerifyCodeService.store(client_id, mobile, captcha, 120);
            }else{
                return getFailedResponse(obj.get("message").toString(),-1,null);
            } else {
                return getFailedResponse(obj.get("message").toString(), -1, null);
            }
        }else{
            return getFailedResponse("暂不提供其他类型人员注册",-1,null);
        } else {
            return getFailedResponse("暂不提供其他类型人员注册", -1, null);
        }
        if(registFlag){
        if (registFlag) {
            parameters.put("grant_type", "captcha");
            ClientDetails authenticatedClient = clientDetailsService.loadClientByClientId(client_id);
@ -502,7 +506,7 @@ public class WlyyLoginEndpoint extends AbstractEndpoint {
            String loginType = parameters.get("login_type");
            userDetailsService.setRolePhth(loginType,token,wlyyUserSimple.getId(),redisTemplate);
            userDetailsService.setRolePhth(loginType, token, wlyyUserSimple.getId(), redisTemplate);
            BaseLoginLogDO baseLoginLogDO = new BaseLoginLogDO();
            baseLoginLogDO.setUserId(wlyyUserSimple.getId());
            baseLoginLogDO.setCreateTime(new Date());
@ -510,7 +514,7 @@ public class WlyyLoginEndpoint extends AbstractEndpoint {
            baseLoginLogDO.setUserAgent(userAgent);
            baseLoginLogDO.setLoginType(loginType);
            String openid = parameters.get("openid");
            if(!StringUtils.isEmpty(openid) && "undefined".equalsIgnoreCase(openid)){
            if (!StringUtils.isEmpty(openid) && "undefined".equalsIgnoreCase(openid)) {
                baseLoginLogDO.setOpenid(openid);
            }
            baseLoginLogService.save(baseLoginLogDO);
@ -539,7 +543,7 @@ public class WlyyLoginEndpoint extends AbstractEndpoint {
        return new ResponseEntity<>(oauth2Envelop, headers, HttpStatus.OK);
    }
    private ResponseEntity<Oauth2Envelop<WlyyUserSimple>> getFailedResponse(String message ,int status,WlyyUserSimple ehrUserSimple) {
    private ResponseEntity<Oauth2Envelop<WlyyUserSimple>> getFailedResponse(String message, int status, WlyyUserSimple ehrUserSimple) {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Cache-Control", "no-store");
        headers.set("Pragma", "no-cache");
@ -553,7 +557,7 @@ public class WlyyLoginEndpoint extends AbstractEndpoint {
        return wlyyOAuth2ExceptionTranslator;
    }
   @ExceptionHandler(Exception.class)
    @ExceptionHandler(Exception.class)
    public ResponseEntity<Oauth2Envelop> handleException(Exception e) throws Exception {
        LOG.debug(e.getMessage(), e);
        if (e instanceof UsernameNotFoundException) {
@ -561,7 +565,7 @@ public class WlyyLoginEndpoint extends AbstractEndpoint {
        } else if (e instanceof NoSuchClientException) {
            return handleOAuth2Exception(new Oauth2Envelop("应用未注册!", ResultStatus.INVALID_GRANT), e);
        } else if (e instanceof InvalidGrantException || e instanceof UsernameNotFoundException) {
            return handleOAuth2Exception(new Oauth2Envelop(invalidGrantMessage((InvalidGrantException)e), ResultStatus.INVALID_GRANT), e);
            return handleOAuth2Exception(new Oauth2Envelop(invalidGrantMessage((InvalidGrantException) e), ResultStatus.INVALID_GRANT), e);
        } else if (e instanceof InvalidTokenException) {
            return handleOAuth2Exception(new Oauth2Envelop("Token过期!", ResultStatus.EXPIRE), e);
        } else if (e instanceof InvalidRequestException) {

+ 15 - 12
server/svr-authentication/src/main/resources/application.yml

@ -23,33 +23,34 @@ user:
  tryLoginTimes: 5 #失败重试次数
#logging:
#  level:
#    org:
#      springframework:
#        security: DEBUG
---
spring:
  profiles: jwdev
  datasource:
    url: jdbc:mysql://172.26.0.114/base?useUnicode:true&characterEncoding=utf-8&autoReconnect=true
    username: jkzl
    username: root
    password: jkzlehr
  redis:
    host: 172.26.0.253 # Redis server host.
    port: 6379 # Redis server port.
#    password: jkzl_ehr
# i健康用户信息接口,开放出来给互联网医院登录同步用户信息用
iHealth:
  user-info-uri: http://http://ehr.yihu.com/wlyy/patient/userInfo
---
spring:
  profiles: jwtest
  datasource:
    url: jdbc:mysql://172.17.110.160/base?useUnicode:true&amp;characterEncoding=utf-8&amp;autoReconnect=true
    username: ssgg
    password: ssgg
    url: jdbc:mysql://172.26.0.104/base?useUnicode:true&amp;characterEncoding=utf-8&amp;autoReconnect=true
    username: root
    password: jkzlehr
  redis:
    host: 172.19.103.88 # Redis server host.
    host: 172.26.0.253 # Redis server host.
    port: 6379 # Redis server port.
## i健康用户信息接口,开放出来给互联网医院登录同步用户信息用
iHealth:
  user-info-uri: http://http://ehr.yihu.com/wlyy/patient/userInfo
---
spring:
  profiles: jwprod
@ -59,4 +60,6 @@ spring:
    password: ssgg
  redis:
    host: 172.19.103.88 # Redis server host.
    port: 6379 # Redis server port.
    port: 6379 # Redis server port.
iHealth:
  user-info-uri: http://http://ehr.yihu.com/wlyy/patient/userInfo

+ 13 - 1
server/svr-authentication/src/main/resources/bootstrap.yml

@ -7,6 +7,18 @@ spring:
      username: jw
      password: jkzl
#发现服务
eureka:
  client:
    healthcheck:
      enabled: false #监控检查
    serviceUrl:
      defaultZone: http://jw:jkzl@172.26.0.107:8761/eureka/
  instance:
    prefer-ip-address: false
    instance-id: ${spring.cloud.client.ipAddress}:${server.port}
---
spring:
  profiles: jwdev
@ -21,7 +33,7 @@ spring:
  cloud:
    config:
      uri: ${wlyy.spring.config.uri:http://172.26.0.107:1221}
      label: ${wlyy.spring.config.label:jwdev}
      label: ${wlyy.spring.config.label:jwtest}
---
spring: