提交 e6802132 编写于 作者: M MaxKey

workweixin

企业扫描微信登录
上级 8f7346bd
...@@ -24,6 +24,7 @@ import org.maxkey.authn.AbstractAuthenticationProvider; ...@@ -24,6 +24,7 @@ import org.maxkey.authn.AbstractAuthenticationProvider;
import org.maxkey.authn.support.socialsignon.service.SocialSignOnProvider; import org.maxkey.authn.support.socialsignon.service.SocialSignOnProvider;
import org.maxkey.authn.support.socialsignon.service.SocialSignOnProviderService; import org.maxkey.authn.support.socialsignon.service.SocialSignOnProviderService;
import org.maxkey.authn.support.socialsignon.service.SocialsAssociateService; import org.maxkey.authn.support.socialsignon.service.SocialsAssociateService;
import org.maxkey.configuration.ApplicationConfig;
import org.maxkey.web.WebContext; import org.maxkey.web.WebContext;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -77,6 +78,9 @@ public class AbstractSocialSignOnEndpoint { ...@@ -77,6 +78,9 @@ public class AbstractSocialSignOnEndpoint {
@Autowired @Autowired
@Qualifier("authenticationProvider") @Qualifier("authenticationProvider")
AbstractAuthenticationProvider authenticationProvider ; AbstractAuthenticationProvider authenticationProvider ;
@Autowired
ApplicationConfig applicationConfig;
protected AuthRequest buildAuthRequest(String provider){ protected AuthRequest buildAuthRequest(String provider){
...@@ -84,7 +88,7 @@ public class AbstractSocialSignOnEndpoint { ...@@ -84,7 +88,7 @@ public class AbstractSocialSignOnEndpoint {
_logger.debug("socialSignOn Provider : "+socialSignOnProvider); _logger.debug("socialSignOn Provider : "+socialSignOnProvider);
if(socialSignOnProvider!=null){ if(socialSignOnProvider!=null){
authRequest=socialSignOnProviderService.getAuthRequest(provider); authRequest=socialSignOnProviderService.getAuthRequest(provider,applicationConfig);
WebContext.setAttribute(SOCIALSIGNON_OAUTH_SERVICE_SESSION, authRequest); WebContext.setAttribute(SOCIALSIGNON_OAUTH_SERVICE_SESSION, authRequest);
WebContext.setAttribute(SOCIALSIGNON_PROVIDER_SESSION, socialSignOnProvider); WebContext.setAttribute(SOCIALSIGNON_PROVIDER_SESSION, socialSignOnProvider);
return authRequest; return authRequest;
......
...@@ -22,7 +22,9 @@ package org.maxkey.authn.support.socialsignon; ...@@ -22,7 +22,9 @@ package org.maxkey.authn.support.socialsignon;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.maxkey.authn.support.socialsignon.service.SocialSignOnProvider;
import org.maxkey.authn.support.socialsignon.service.SocialsAssociate; import org.maxkey.authn.support.socialsignon.service.SocialsAssociate;
import org.maxkey.configuration.ApplicationConfig;
import org.maxkey.constants.ConstantsLoginType; import org.maxkey.constants.ConstantsLoginType;
import org.maxkey.web.WebContext; import org.maxkey.web.WebContext;
import org.slf4j.Logger; import org.slf4j.Logger;
...@@ -33,10 +35,9 @@ import org.springframework.stereotype.Controller; ...@@ -33,10 +35,9 @@ import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.ModelAndView;
import me.zhyd.oauth.utils.AuthStateUtils;
/** /**
* @author Crystal.Sea * @author Crystal.Sea
* *
...@@ -46,25 +47,26 @@ import me.zhyd.oauth.utils.AuthStateUtils; ...@@ -46,25 +47,26 @@ import me.zhyd.oauth.utils.AuthStateUtils;
public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
final static Logger _logger = LoggerFactory.getLogger(SocialSignOnEndpoint.class); final static Logger _logger = LoggerFactory.getLogger(SocialSignOnEndpoint.class);
public ModelAndView socialSignOnAuthorize(String provider){ public ModelAndView socialSignOnAuthorize(HttpServletRequest request,String provider){
_logger.debug("SocialSignOn provider : "+provider); _logger.debug("SocialSignOn provider : "+provider);
String authorizationUrl=buildAuthRequest(provider).authorize(AuthStateUtils.createState()); String authorizationUrl=buildAuthRequest(provider).authorize(request.getSession().getId());
_logger.debug("authorize SocialSignOn : "+authorizationUrl); _logger.debug("authorize SocialSignOn : "+authorizationUrl);
return WebContext.redirect(authorizationUrl); return WebContext.redirect(authorizationUrl);
} }
@RequestMapping(value={"/authorize/{provider}"}, method = RequestMethod.GET) @RequestMapping(value={"/authorize/{provider}"}, method = RequestMethod.GET)
public ModelAndView authorize(@PathVariable String provider) { public ModelAndView authorize(HttpServletRequest request,
@PathVariable String provider) {
WebContext.setAttribute(SOCIALSIGNON_TYPE_SESSION, SOCIALSIGNON_TYPE.SOCIALSIGNON_TYPE_LOGON); WebContext.setAttribute(SOCIALSIGNON_TYPE_SESSION, SOCIALSIGNON_TYPE.SOCIALSIGNON_TYPE_LOGON);
return socialSignOnAuthorize(provider); return socialSignOnAuthorize(request,provider);
} }
@RequestMapping(value={"/bind/{provider}"}, method = RequestMethod.GET) @RequestMapping(value={"/bind/{provider}"}, method = RequestMethod.GET)
public ModelAndView bind(HttpServletRequest request, public ModelAndView bind(HttpServletRequest request,
@PathVariable String provider) { @PathVariable String provider) {
WebContext.setAttribute(SOCIALSIGNON_SESSION_REDIRECT_URI, request.getParameter(SOCIALSIGNON_REDIRECT_URI)); WebContext.setAttribute(SOCIALSIGNON_SESSION_REDIRECT_URI, request.getParameter(SOCIALSIGNON_REDIRECT_URI));
WebContext.setAttribute(SOCIALSIGNON_TYPE_SESSION, SOCIALSIGNON_TYPE.SOCIALSIGNON_TYPE_BIND); WebContext.setAttribute(SOCIALSIGNON_TYPE_SESSION, SOCIALSIGNON_TYPE.SOCIALSIGNON_TYPE_BIND);
return socialSignOnAuthorize(provider); return socialSignOnAuthorize(request,provider);
} }
@RequestMapping(value={"/unbind/{provider}"}, method = RequestMethod.GET) @RequestMapping(value={"/unbind/{provider}"}, method = RequestMethod.GET)
...@@ -88,10 +90,23 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{ ...@@ -88,10 +90,23 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
} }
@RequestMapping(value={"/authorize/{provider}/{appid}"}, method = RequestMethod.GET) @RequestMapping(value={"/authorize/{provider}/{appid}"}, method = RequestMethod.GET)
public ModelAndView authorize2AppId(@PathVariable("provider") String provider, public ModelAndView authorize2AppId(HttpServletRequest request,
@PathVariable("appid") String appid) { @PathVariable("provider") String provider,
@PathVariable("appid") String appid) {
WebContext.setAttribute(SOCIALSIGNON_SESSION_REDIRECT_URI, "/authorize/"+appid); WebContext.setAttribute(SOCIALSIGNON_SESSION_REDIRECT_URI, "/authorize/"+appid);
return authorize(provider); return authorize(request,provider);
}
@RequestMapping(value={"/scanqrcode/{provider}"}, method = RequestMethod.GET)
@ResponseBody
public SocialSignOnProvider scanQRCode(
HttpServletRequest request,
@PathVariable("provider") String provider) {
socialSignOnAuthorize(request,provider);
SocialSignOnProvider socialSignOnProvider = socialSignOnProviderService.get(provider);
socialSignOnProvider.setState(request.getSession().getId());
socialSignOnProvider.setRedirectUri(applicationConfig.getServerPrefix()+ "/logon/oauth20/callback/"+provider);
return socialSignOnProvider;
} }
......
/* /*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top] * Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
...@@ -33,24 +33,34 @@ public class JdbcSocialsAssociateService implements SocialsAssociateService{ ...@@ -33,24 +33,34 @@ public class JdbcSocialsAssociateService implements SocialsAssociateService{
private static final String DEFAULT_DEFAULT_INSERT_STATEMENT = "INSERT INTO MXK_SOCIALS_ASSOCIATE(ID, UID , USERNAME , PROVIDER , SOCIALUID , ACCESSTOKEN , SOCIALUSERINFO , EXATTRIBUTE )VALUES( ? , ? , ? , ? , ?, ? , ? , ?)"; private static final String DEFAULT_DEFAULT_INSERT_STATEMENT = "INSERT INTO MXK_SOCIALS_ASSOCIATE(ID, UID , USERNAME , PROVIDER , SOCIALUID , ACCESSTOKEN , SOCIALUSERINFO , EXATTRIBUTE )VALUES( ? , ? , ? , ? , ?, ? , ? , ?)";
private static final String DEFAULT_DEFAULT_SIGNON_SELECT_STATEMENT = "SELECT ID, UID , USERNAME , PROVIDER , SOCIALUID , ACCESSTOKEN , SOCIALUSERINFO , EXATTRIBUTE , CREATEDDATE , UPDATEDDATE FROM MXK_SOCIALS_ASSOCIATE WHERE PROVIDER = ? AND SOCIALUID = ?"; private static final String DEFAULT_DEFAULT_INSERT_STATEMENT_ORACLE = "INSERT INTO MXK_SOCIALS_ASSOCIATE(ID, \"UID\" , USERNAME , PROVIDER , SOCIALUID , ACCESSTOKEN , SOCIALUSERINFO , EXATTRIBUTE )VALUES( ? , ? , ? , ? , ?, ? , ? , ?)";
private static final String DEFAULT_DEFAULT_SIGNON_SELECT_STATEMENT = "SELECT ID, \"UID\" , USERNAME , PROVIDER , SOCIALUID , ACCESSTOKEN , SOCIALUSERINFO , EXATTRIBUTE , CREATEDDATE , UPDATEDDATE FROM MXK_SOCIALS_ASSOCIATE WHERE PROVIDER = ? AND SOCIALUID = ?";
private static final String DEFAULT_DEFAULT_BIND_SELECT_STATEMENT = "SELECT ID, UID , USERNAME , PROVIDER , SOCIALUID , ACCESSTOKEN , SOCIALUSERINFO , EXATTRIBUTE , CREATEDDATE , UPDATEDDATE FROM MXK_SOCIALS_ASSOCIATE WHERE UID = ?" ; private static final String DEFAULT_DEFAULT_BIND_SELECT_STATEMENT = "SELECT ID, \"UID\" , USERNAME , PROVIDER , SOCIALUID , ACCESSTOKEN , SOCIALUSERINFO , EXATTRIBUTE , CREATEDDATE , UPDATEDDATE FROM MXK_SOCIALS_ASSOCIATE WHERE \"UID\" = ?" ;
private static final String DEFAULT_DEFAULT_DELETE_STATEMENT = "DELETE FROM MXK_SOCIALS_ASSOCIATE WHERE UID = ? AND PROVIDER = ?"; private static final String DEFAULT_DEFAULT_DELETE_STATEMENT = "DELETE FROM MXK_SOCIALS_ASSOCIATE WHERE \"UID\" = ? AND PROVIDER = ?";
private static final String DEFAULT_DEFAULT_UPDATE_STATEMENT= "UPDATE MXK_SOCIALS_ASSOCIATE SET ACCESSTOKEN = ? , SOCIALUSERINFO = ? , EXATTRIBUTE = ? ,UPDATEDDATE = ? WHERE ID = ?"; private static final String DEFAULT_DEFAULT_UPDATE_STATEMENT= "UPDATE MXK_SOCIALS_ASSOCIATE SET ACCESSTOKEN = ? , SOCIALUSERINFO = ? , EXATTRIBUTE = ? ,UPDATEDDATE = ? WHERE ID = ?";
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private String jdbcType;
public JdbcSocialsAssociateService(JdbcTemplate jdbcTemplate) { public JdbcSocialsAssociateService(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate=jdbcTemplate; this.jdbcTemplate=jdbcTemplate;
try {
jdbcType = jdbcTemplate.getDataSource().getConnection().getMetaData().getDatabaseProductName();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
@Override @Override
public boolean insert(SocialsAssociate socialsAssociate) { public boolean insert(SocialsAssociate socialsAssociate) {
socialsAssociate.setId(socialsAssociate.generateId()); socialsAssociate.setId(socialsAssociate.generateId());
jdbcTemplate.update(DEFAULT_DEFAULT_INSERT_STATEMENT, jdbcTemplate.update("Oracle".equals(jdbcType)?DEFAULT_DEFAULT_INSERT_STATEMENT_ORACLE:DEFAULT_DEFAULT_INSERT_STATEMENT,
new Object[] { new Object[] {
socialsAssociate.getId(), socialsAssociate.getId(),
socialsAssociate.getUid(), socialsAssociate.getUid(),
......
...@@ -28,14 +28,15 @@ public class SocialSignOnProvider { ...@@ -28,14 +28,15 @@ public class SocialSignOnProvider {
private String icon; private String icon;
private String clientId; private String clientId;
private String clientSecret; private String clientSecret;
private String redirectUri;
private String agentId;
private String accountId; private String accountId;
private String bindTime; private String bindTime;
private String unBindTime; private String unBindTime;
private String lastLoginTime; private String lastLoginTime;
private String state;
private int sortOrder; private int sortOrder;
private boolean userBind; private boolean userBind;
/** /**
...@@ -134,34 +135,58 @@ public class SocialSignOnProvider { ...@@ -134,34 +135,58 @@ public class SocialSignOnProvider {
this.lastLoginTime = lastLoginTime; this.lastLoginTime = lastLoginTime;
} }
@Override public String getRedirectUri() {
public String toString() { return redirectUri;
StringBuilder builder = new StringBuilder(); }
builder.append("SocialSignOnProvider [provider=");
builder.append(provider); public void setRedirectUri(String redirectUri) {
builder.append(", providerName="); this.redirectUri = redirectUri;
builder.append(providerName); }
builder.append(", icon=");
builder.append(icon); public String getAgentId() {
builder.append(", clientId="); return agentId;
builder.append(clientId); }
builder.append(", clientSecret=");
builder.append(clientSecret); public void setAgentId(String agentId) {
builder.append(", accountId="); this.agentId = agentId;
builder.append(accountId); }
builder.append(", bindTime=");
builder.append(bindTime); public String getState() {
builder.append(", unBindTime="); return state;
builder.append(unBindTime); }
builder.append(", lastLoginTime=");
builder.append(lastLoginTime); public void setState(String state) {
builder.append(", sortOrder="); this.state = state;
builder.append(sortOrder); }
builder.append(", userBind=");
builder.append(userBind); @Override
builder.append("]"); public String toString() {
return builder.toString(); StringBuilder builder = new StringBuilder();
} builder.append("SocialSignOnProvider [provider=");
builder.append(provider);
builder.append(", providerName=");
builder.append(providerName);
builder.append(", clientId=");
builder.append(clientId);
builder.append(", clientSecret=");
builder.append(clientSecret);
builder.append(", agentId=");
builder.append(agentId);
builder.append(", accountId=");
builder.append(accountId);
builder.append(", bindTime=");
builder.append(bindTime);
builder.append(", unBindTime=");
builder.append(unBindTime);
builder.append(", lastLoginTime=");
builder.append(lastLoginTime);
builder.append(", sortOrder=");
builder.append(sortOrder);
builder.append(", userBind=");
builder.append(userBind);
builder.append("]");
return builder.toString();
}
......
...@@ -20,6 +20,7 @@ package org.maxkey.authn.support.socialsignon.service; ...@@ -20,6 +20,7 @@ package org.maxkey.authn.support.socialsignon.service;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import org.maxkey.configuration.ApplicationConfig;
import org.maxkey.web.WebContext; import org.maxkey.web.WebContext;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -43,12 +44,12 @@ public class SocialSignOnProviderService{ ...@@ -43,12 +44,12 @@ public class SocialSignOnProviderService{
return socialSignOnProviderMaps.get(provider); return socialSignOnProviderMaps.get(provider);
} }
public AuthRequest getAuthRequest(String provider) { public AuthRequest getAuthRequest(String provider,ApplicationConfig applicationConfig) {
AuthRequest authRequest = null; AuthRequest authRequest = null;
AuthConfig authConfig = AuthConfig.builder() AuthConfig authConfig = AuthConfig.builder()
.clientId(this.get(provider).getClientId()) .clientId(this.get(provider).getClientId())
.clientSecret(this.get(provider).getClientSecret()) .clientSecret(this.get(provider).getClientSecret())
.redirectUri(WebContext.getHttpContextPath()+ "/logon/oauth20/callback/"+provider) .redirectUri(applicationConfig.getServerPrefix()+ "/logon/oauth20/callback/"+provider)
.build(); .build();
if(provider.equalsIgnoreCase("WeChatOpen")) { if(provider.equalsIgnoreCase("WeChatOpen")) {
...@@ -99,7 +100,7 @@ public class SocialSignOnProviderService{ ...@@ -99,7 +100,7 @@ public class SocialSignOnProviderService{
authRequest = new AuthToutiaoRequest(authConfig); authRequest = new AuthToutiaoRequest(authConfig);
}else if(provider.equalsIgnoreCase("WeChatQyQrcode")) { }else if(provider.equalsIgnoreCase("WeChatQyQrcode")) {
authRequest = new AuthWeChatEnterpriseQrcodeRequest(authConfig); authRequest = new AuthWeChatEnterpriseQrcodeRequest(authConfig);
}else if(provider.equalsIgnoreCase("WeChatQyWeb")) { }else if(provider.equalsIgnoreCase("workweixin")) {
authRequest = new AuthWeChatEnterpriseWebRequest(authConfig); authRequest = new AuthWeChatEnterpriseWebRequest(authConfig);
} }
......
...@@ -57,6 +57,8 @@ public class SocialSignOnAutoConfiguration implements InitializingBean { ...@@ -57,6 +57,8 @@ public class SocialSignOnAutoConfiguration implements InitializingBean {
String clientId=applicationProperty.getProperty("maxkey.socialsignon."+provider+".client.id"); String clientId=applicationProperty.getProperty("maxkey.socialsignon."+provider+".client.id");
String clientSecret=applicationProperty.getProperty("maxkey.socialsignon."+provider+".client.secret"); String clientSecret=applicationProperty.getProperty("maxkey.socialsignon."+provider+".client.secret");
String sortOrder = applicationProperty.getProperty("maxkey.socialsignon."+provider+".sortorder"); String sortOrder = applicationProperty.getProperty("maxkey.socialsignon."+provider+".sortorder");
String agentId = applicationProperty.getProperty("maxkey.socialsignon."+provider+".agent.id");
SocialSignOnProvider socialSignOnProvider = new SocialSignOnProvider(); SocialSignOnProvider socialSignOnProvider = new SocialSignOnProvider();
socialSignOnProvider.setProvider(provider); socialSignOnProvider.setProvider(provider);
socialSignOnProvider.setProviderName(providerName); socialSignOnProvider.setProviderName(providerName);
...@@ -64,6 +66,8 @@ public class SocialSignOnAutoConfiguration implements InitializingBean { ...@@ -64,6 +66,8 @@ public class SocialSignOnAutoConfiguration implements InitializingBean {
socialSignOnProvider.setClientId(clientId); socialSignOnProvider.setClientId(clientId);
socialSignOnProvider.setClientSecret(clientSecret); socialSignOnProvider.setClientSecret(clientSecret);
socialSignOnProvider.setSortOrder(Integer.valueOf(sortOrder)); socialSignOnProvider.setSortOrder(Integer.valueOf(sortOrder));
socialSignOnProvider.setAgentId(agentId);
_logger.debug("socialSignOnProvider " + socialSignOnProvider.getProvider() _logger.debug("socialSignOnProvider " + socialSignOnProvider.getProvider()
+ "(" + socialSignOnProvider.getProviderName()+")"); + "(" + socialSignOnProvider.getProviderName()+")");
_logger.trace("socialSignOnProvider " + socialSignOnProvider); _logger.trace("socialSignOnProvider " + socialSignOnProvider);
......
...@@ -371,6 +371,15 @@ maxkey.socialsignon.wechatopen.client.id=ee6fdc484b3398d17e7 ...@@ -371,6 +371,15 @@ maxkey.socialsignon.wechatopen.client.id=ee6fdc484b3398d17e7
maxkey.socialsignon.wechatopen.client.secret=7a5faccdbad maxkey.socialsignon.wechatopen.client.secret=7a5faccdbad
maxkey.socialsignon.wechatopen.account.id=id maxkey.socialsignon.wechatopen.account.id=id
maxkey.socialsignon.wechatopen.sortorder=2 maxkey.socialsignon.wechatopen.sortorder=2
#work weixin
maxkey.socialsignon.workweixin.provider=workweixin
maxkey.socialsignon.workweixin.provider.name=\u4F01\u4E1A\u5fae\u4fe1
maxkey.socialsignon.workweixin.icon=images/social/wechat.png
maxkey.socialsignon.workweixin.client.id=wx00d052e8f417f8f9
maxkey.socialsignon.workweixin.client.secret=lIy40iP0z4D65eJaWDNoe-vSlttmqY2WGJBygbM0TlY
maxkey.socialsignon.workweixin.agent.id=1000002
maxkey.socialsignon.workweixin.account.id=id
maxkey.socialsignon.workweixin.sortorder=2
#sina weibo #sina weibo
maxkey.socialsignon.sinaweibo.provider=sinaweibo maxkey.socialsignon.sinaweibo.provider=sinaweibo
maxkey.socialsignon.sinaweibo.provider.name=\u65b0\u6d6a\u5fae\u535a maxkey.socialsignon.sinaweibo.provider.name=\u65b0\u6d6a\u5fae\u535a
......
...@@ -363,6 +363,15 @@ maxkey.socialsignon.wechatopen.client.id=ee6fdc484b3398d17e7 ...@@ -363,6 +363,15 @@ maxkey.socialsignon.wechatopen.client.id=ee6fdc484b3398d17e7
maxkey.socialsignon.wechatopen.client.secret=7a5faccdbad maxkey.socialsignon.wechatopen.client.secret=7a5faccdbad
maxkey.socialsignon.wechatopen.account.id=id maxkey.socialsignon.wechatopen.account.id=id
maxkey.socialsignon.wechatopen.sortorder=2 maxkey.socialsignon.wechatopen.sortorder=2
#work weixin
maxkey.socialsignon.workweixin.provider=workweixin
maxkey.socialsignon.workweixin.provider.name=\u4F01\u4E1A\u5fae\u4fe1
maxkey.socialsignon.workweixin.icon=images/social/wechat.png
maxkey.socialsignon.workweixin.client.id=wx00d052e8f417f8f9
maxkey.socialsignon.workweixin.client.secret=lIy40iP0z4D65eJaWDNoe-vSlttmqY2WGJBygbM0TlY
maxkey.socialsignon.workweixin.agent.id=1000002
maxkey.socialsignon.workweixin.account.id=id
maxkey.socialsignon.workweixin.sortorder=2
#sina weibo #sina weibo
maxkey.socialsignon.sinaweibo.provider=sinaweibo maxkey.socialsignon.sinaweibo.provider=sinaweibo
maxkey.socialsignon.sinaweibo.provider.name=\u65b0\u6d6a\u5fae\u535a maxkey.socialsignon.sinaweibo.provider.name=\u65b0\u6d6a\u5fae\u535a
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册