本笔记用于记录微信扫码登陆过程当中遇到的问题
目的:React嵌入iframe微信扫码登陆html
流程git
内容 | 版本 |
---|---|
Cas | 5.3.1 |
微信 | - |
springboot | 1.5.13 |
域名 | 做用 |
---|---|
https://cas.demo.com | Cas服务端 |
https://gateway.demo.com | SpringCloud网关 |
https://gateway.demo.com/app/... | Cas客户端(由网关进行负载) |
添加依赖github
<dependency> <groupId>org.apereo.cas</groupId> <artifactId>cas-server-support-pac4j-webflow</artifactId> <version>${cas.version}</version> </dependency>
配置文件web
application.propertiesredis
#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.propertiesspring
cas.server.prefix=https://cas.demo.com
or数据库
--cas.server.prefix=https://cas.demo.com/cas
api
注:此处不容许使用端口,否则会显示参数错误缓存
分布式部署配置
<dependency> <groupId>org.apereo.cas</groupId> <artifactId>cas-server-webapp-session-redis</artifactId> <version>${cas.version}</version> </dependency>
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
POM.xml
<dependency> <groupId>net.unicon.cas</groupId> <artifactId>cas-client-autoconfig-support</artifactId> <version>1.4.0-GA</version> </dependency> <dependency> <groupId>org.jasig.cas.client</groupId> <artifactId>cas-client-core</artifactId> <version>3.5.0</version> </dependency>
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<String, String> 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、扫码完成,重定向回到cas
https://cas.demo.com/login?client_name=WeChat&codexxx&state=xxx
4、cas校验完成后重定向到客户端服务器
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/sso
http://www.ibloger.net/articl...
http://www.cassso-china.cn/ap...