Cas5 springcloud 위챗 스캔 로그인

8515 단어 위챗cas
이 노트는 위챗 스캔 로그인 과정에서 발생한 문제를 기록하는 데 쓰인다

환경 배경


목적: iframe 위챗 스캔 로그인
프로세스
  • 로그인 페이지, 모드 창에 Cas가 내장되어 있습니다
  • 로그인 페이지, 컨트롤이 터치되면 스캔해서 로그인합니다.QR코드를 표시합니다
  • 로그인 페이지, 스캔 후 카스-login으로 이동합니다
  • 성공 후 로그인 성공 후 클라이언트 서버로 이동합니다
  • 성공 후 클라이언트 서버, 검증, 정적 h5 인터페이스로 이동, 메시지 알림 성공
  • 성공한 후, 메시지 감청, token 얻기, 사용자 정보 다시 얻기

  • 컨텐트
    버전
    Cas
    5.3.1
    위챗
    -
    springboot
    1.5.13

    서버 준비


    도메인 이름
    작용
    https://cas.demo.com
    Cas 서버
    https://gateway.demo.com
    SpringCloud 게이트웨이
    https://gateway.demo.com/app/...
    Cas 클라이언트(게이트웨이에서 로드됨)

    Cas 서버 구성


    의존 추가
    
         org.apereo.cas
         cas-server-support-pac4j-webflow
         ${cas.version}
     

    프로파일
    application.properties
    #WeChat OAuth Login
    cas.authn.pac4j.oauth2[0].id=wxac0f1c863937d887
    # clinet_id, appid
    cas.authn.pac4j.oauth2[0].customParams.appid=wxac0f1c863937d887
    # scope snsapi_login
    cas.authn.pac4j.oauth2[0].customParams.scope=snsapi_login
    cas.authn.pac4j.oauth2[0].secret=cceedc350fe15f45315a0ab67643085e
    cas.authn.pac4j.oauth2[0].authUrl=https://open.weixin.qq.com/connect/qrconnect
    #todo  
    cas.authn.pac4j.oauth2[0].tokenUrl=https://gateway.demo.com/app/auth/weixin/access_token
    cas.authn.pac4j.oauth2[0].profileUrl=https://gateway.demo.com/app/auth/weixin/userinfo
    cas.authn.pac4j.oauth2[0].clientName=WeChat

    프로파일
    cas.properties
    cas.server.prefix=https://cas.demo.com

    or --cas.server.prefix=https://cas.demo.com/cas
    참고: 여기에서는 포트를 사용할 수 없습니다. 그렇지 않으면 매개 변수 오류가 표시됩니다.
    분산 배치 구성
    
         org.apereo.cas
         cas-server-webapp-session-redis
         ${cas.version}
     

    application.properties
    cas.ticket.registry.redis.host=${spring.redis.host}
    cas.ticket.registry.redis.database=10
    cas.ticket.registry.redis.port=${spring.redis.port}
    cas.ticket.registry.redis.password=${spring.redis.password}
    cas.ticket.registry.redis.timeout=2000
    cas.ticket.registry.redis.useSsl=false
    cas.ticket.registry.redis.usePool=true
    
    cas.ticket.registry.redis.pool.max-active=20
    cas.ticket.registry.redis.pool.maxIdle=8
    cas.ticket.registry.redis.pool.minIdle=0
    cas.ticket.registry.redis.pool.maxActive=8
    cas.ticket.registry.redis.pool.maxWait=-1
    
    cas.ticket.registry.redis.pool.numTestsPerEvictionRun=0
    cas.ticket.registry.redis.pool.softMinEvictableIdleTimeMillis=0
    cas.ticket.registry.redis.pool.minEvictableIdleTimeMillis=0
    cas.ticket.registry.redis.pool.lifo=true
    cas.ticket.registry.redis.pool.fairness=false
    
    #  ticket , ticket 
    cas.tgc.crypto.encryption.key=${encryption_key}
    cas.tgc.crypto.signing.key=${signing_key}
    
    # session 
    cas.webflow.autoconfigure=true
    cas.webflow.alwaysPauseRedirect=false
    cas.webflow.refresh=true
    cas.webflow.redirectSameState=false
    
    cas.webflow.session.lockTimeout=30
    cas.webflow.session.compress=false
    cas.webflow.session.maxConversations=5
    cas.webflow.session.storage=true
    
    srping.session.store-type=redis

    Cas 클라이언트 구성


    POM.xml
    
         net.unicon.cas
         cas-client-autoconfig-support
         1.4.0-GA
     
    
         org.jasig.cas.client
         cas-client-core
         3.5.0
     

    application.yml
    cas:
      #cas , 
      server-url-prefix: https://cas.demo.com
      #cas 
      server-login-url: https://cas.demo.com/login
      # 
      client-host-url: https://gateway.demo.com/app/auth
      # ticket 
      validation-type: CAS3
      authenticationUrlPatterns:
        - /cas/login
        - /app/auth/cas/login
      validationUrlPatterns:
        - /cas/login
        - /app/auth/cas/login
      requestWrapperUrlPatterns:
        - /cas/login
        - /app/auth/cas/login
    auth:
      wechat:
        appid: wxac0f1c863937d887
        secret: cceedc350fe15f45315a0ab67643085e
        access_token: https://api.weixin.qq.com/sns/oauth2/access_token
        userinfo: https://api.wexin.qq.com/sns/userinfo
      loginComplete: /loginComplete
      service: https://gateway.demo.com/app/auth/cas/login

    CasConfig
    @Configuration
    public class CasConfig extends CasClientConfiggurerAdapter {
    
      @Value("${auth.service}")
      private String AUTH_SERVICE;
    
      @Override
      public void configureValidationFilter(FilterRegistrationBean validationFilter){
        super.configureValidationFilter(validationFilter);
        validationFilter.getInitParameters().put("redirectAfterValidation","false");
        validationFilter.getInitParameters().remove("serverName");
        validationFilter.getInitParameters().put("service",AUTH_SERVICE);
      }
    
    }

    ProxyController
    @RestController
    @RequestMapping("")
    public class ProxyController {
      
      @Autowired
      private StringRedisTemplate stringRedisTemplate
    
      @Value("${auth.loginComplete}")
      private String AUTH_LOGIN_COMPLETE;
    
      @Value("${auth.wechat.appid}")
      private String AUTH_WECHAT_APPID;
    
      @Value("${auth.wechat.secret}")
      private String AUTH_WECHAT_SECRET;
    
      @Value("${auth.wechat.access_token}")
      private String AUTH_WECHAT_ACCESS_TOKEN;
    
      @Value("${auth.wechat.userinfo}")
      private String AUTH_WECHAT_USERINFO;
    
      @PostMapping(value = "/weixin/access_token")
      public Object weixinAccessToken(@RequestBody String body){
        Map param=RequestUrlParamUtls.getParam(body);
        StringBuidder url= new StringBuilder();
        url.append(AUTH_WECHAT_ACCESS_TOKEN+"?");
        url.append("appid="+AUTH_WECHAT_APPID);
        url.append("&secret="+AUTH_WECHAT_SECRET);
        url.append("&code="+param.get("code"));
        url.append("&grant_type=authorization_code");
        RestTemplate restTemplate = RequestUrlParamUtils.getInstance();
        String weAppBody=restTemplate.postForObject(url.toString(),null,String.class);
        
        String weChatToken="auth_weChat_"+JSON.parseObject(weAppBody).getString("access_token");
        stringRedisTemplate.opsForValue().set(weChatToken,weAppBody,1,TimeUnit.HOURS);
        return JSON.parseObject(weAppBody,Map.class);
    
      }
    
      @PostMapping(value = "/weixin/userinfo")
      public Object weixinUserinfo(@RequestBody String body){
        String access_token=body.split("=")[1];
        StringBuilder url=new StringBuilder();
        String weChatToken="auth_weChat_"+access_token;
        String weAppBody=stringRedisTemplate.opsForValue().get(weChatToken);
        url.append(AUTH_WECHAT_USERINFO+"?");
        url.append("access_token=");
        url.append(access_token);
        url.append("&openid=");
        url.append(JSON.parseObject(weAppBody).getSAtring("openid"));
        RestTemplate restTemplate = RequestUrlParamUtils.getInstance();
        String infoBody=restTemplate.postForObject(url.toString(),null,String.class);
        return JSON.parseObject(infoBody,Map.class);
      }
    
      @GetMapping(value = "/cas/login")
      public Object casLogin(HttpServletRequest request,HttpServletResponse response){
        AttributePrincipal ap=AssertionHolder.getAssertion().getPrincipal();
        // TODO:  , 。( rest cas)
        StringBuilder url=new StringBuilder();
        url.append(AUTH_LOGIN_COMPLETE);
        // TODO: 
        response.sendRedirect(url.toString());
        return null;
      }
    }
  • 이상 토큰에 따라 사용자 정보를 얻는 방식이 추가로 필요합니다

  • 실현 효과


    1. 액세스 연결 포함
    https://cas.demo.com/clientredirect?client_name=WeChat&service=https://gateway.demo.com/app/auth/cas/login

    2. 위챗 스캔 페이지로 이동
    https://open.weixin.qq.com/connet/grconect?xxxxxx

    3. 코드 스캔 완료, 다시 카스로 이동
    https://cas.demo.com/login?client_name=WeChat&codexxx&state=xxx

    4. 카스 검사가 끝난 후 클라이언트 서버로 리디렉션
    https://gateway.demo.com/app/auth/cas/login?ticket=xxx

    5. 클라이언트 서버가 정적 페이지로 리디렉션
    https://gateway.demo.com/app/auth/login_complate?status=up&token=

    자동으로 위챗 스캔 권한 수여 인터페이스로 이동하여 리셋 URL을 완성합니다

    참고문


    https://gitee.com/Kawhi-Carl/ssohttp://www.ibloger.net/articl...http://www.cassso-china.cn/ap...

    좋은 웹페이지 즐겨찾기