代码优化

This commit is contained in:
冷冷 2018-05-14 21:22:12 +08:00
parent fde8a949d0
commit c6e983d1ff
22 changed files with 214 additions and 136 deletions

View File

@ -37,6 +37,27 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!--MySQL-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--tomcat-jdbc排除 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--HikariCP连接池-->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -2,6 +2,7 @@ package com.github.pig.auth.component.mobile;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.util.AuthUtils;
import com.xiaoleilu.hutool.map.MapUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -54,7 +55,7 @@ public class MobileLoginSuccessHandler implements AuthenticationSuccessHandler {
}
try {
String[] tokens = extractAndDecodeHeader(header);
String[] tokens = AuthUtils.extractAndDecodeHeader(header);
assert tokens.length == 2;
String clientId = tokens[0];
@ -76,33 +77,6 @@ public class MobileLoginSuccessHandler implements AuthenticationSuccessHandler {
}
}
/**
* Decodes the header into a username and password.
*
* @throws BadCredentialsException if the Basic header is not present or is not valid
* Base64
*/
private String[] extractAndDecodeHeader(String header)
throws IOException {
byte[] base64Token = header.substring(6).getBytes("UTF-8");
byte[] decoded;
try {
decoded = Base64.decode(base64Token);
} catch (IllegalArgumentException e) {
throw new BadCredentialsException(
"Failed to decode basic authentication token");
}
String token = new String(decoded, CommonConstant.UTF8);
int delim = token.indexOf(":");
if (delim == -1) {
throw new BadCredentialsException("Invalid basic authentication token");
}
return new String[]{token.substring(0, delim), token.substring(delim + 1)};
}
}

View File

@ -1,40 +1,26 @@
package com.github.pig.auth.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
/**
* @author lengleng
* @date 2017/10/28
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "pig.auth")
@ConfigurationProperties(prefix = "auth")
public class AuthServerConfig {
private String clientId;
private String clientSecret;
private String scope;
private List<AuthServer> clients = new ArrayList<>();
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
@Data
class AuthServer {
private String clientId;
private String clientSecret;
private String scope;
}
}

View File

@ -17,12 +17,14 @@ import org.springframework.security.oauth2.config.annotation.web.configuration.A
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
import javax.sql.DataSource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@ -37,9 +39,8 @@ import java.util.Map;
@Order(Integer.MIN_VALUE)
@EnableAuthorizationServer
public class PigAuthorizationConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthServerConfig authServerConfig;
private DataSource dataSource;
@Autowired
private AuthenticationManager authenticationManager;
@ -52,12 +53,10 @@ public class PigAuthorizationConfig extends AuthorizationServerConfigurerAdapter
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient(authServerConfig.getClientId())
.secret(authServerConfig.getClientSecret())
.authorizedGrantTypes(SecurityConstants.REFRESH_TOKEN, SecurityConstants.PASSWORD, SecurityConstants.AUTHORIZATION_CODE)
.scopes(authServerConfig.getScope())
.autoApprove(true);
JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource);
clientDetailsService.setSelectClientDetailsSql(SecurityConstants.DEFAULT_SELECT_STATEMENT);
clientDetailsService.setFindClientDetailsSql(SecurityConstants.DEFAULT_FIND_STATEMENT);
clients.withClientDetails(clientDetailsService);
}
@Override

View File

@ -1,7 +1,7 @@
package com.github.pig.auth.config;
import com.github.pig.auth.component.mobile.MobileSecurityConfigurer;
import com.github.pig.common.bean.config.FilterUrlsPropertiesConfig;
import com.github.pig.common.bean.config.FilterIgnorePropertiesConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Configuration;
@ -20,7 +20,7 @@ import org.springframework.security.config.annotation.web.configurers.Expression
@EnableWebSecurity
public class PigSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private FilterUrlsPropertiesConfig filterUrlsPropertiesConfig;
private FilterIgnorePropertiesConfig filterIgnorePropertiesConfig;
@Autowired
private MobileSecurityConfigurer mobileSecurityConfigurer;
@ -31,9 +31,7 @@ public class PigSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
.loginProcessingUrl("/authentication/form")
.and()
.authorizeRequests();
for (String url : filterUrlsPropertiesConfig.getAnon()) {
registry.antMatchers(url).permitAll();
}
filterIgnorePropertiesConfig.getUrls().forEach(url -> registry.antMatchers(url).permitAll());
registry.anyRequest().authenticated()
.and()
.csrf().disable();

View File

@ -11,7 +11,6 @@ spring:
enabled: true
profile: ${spring.profiles.active}
label: ${spring.profiles.active}
---
spring:
profiles: dev

View File

@ -1,5 +1,6 @@
package com.github.pig.common.bean.config;
import lombok.Data;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@ -11,17 +12,12 @@ import java.util.List;
* @author lengleng
* @date 2018/1/9
*/
@Data
@Configuration
@ConditionalOnExpression("!'${urls}'.isEmpty()")
@ConfigurationProperties(prefix = "urls")
public class FilterUrlsPropertiesConfig {
private List<String> anon = new ArrayList<>();
@ConditionalOnExpression("!'${ignore}'.isEmpty()")
@ConfigurationProperties(prefix = "ignore")
public class FilterIgnorePropertiesConfig {
private List<String> urls = new ArrayList<>();
public List<String> getAnon() {
return anon;
}
public void setAnon(List<String> anon) {
this.anon = anon;
}
private List<String> clients = new ArrayList<>();
}

View File

@ -114,4 +114,28 @@ public interface SecurityConstants {
* 默认的social的注册地址
*/
String DEFAULT_SOCIAL_SIGNUP_URL = "/social/signup";
/**
* sys_oauth_client_details 表的字段不包括client_idclient_secret
*/
String CLIENT_FIELDS = "client_id, client_secret, resource_ids, scope, "
+ "authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, "
+ "refresh_token_validity, additional_information, autoapprove";
/**
*JdbcClientDetailsService 查询语句
*/
String BASE_FIND_STATEMENT = "select " + CLIENT_FIELDS
+ " from sys_oauth_client_details";
/**
* 默认的查询语句
*/
String DEFAULT_FIND_STATEMENT = BASE_FIND_STATEMENT + " order by client_id";
/**
* 按条件client_id 查询
*/
String DEFAULT_SELECT_STATEMENT = BASE_FIND_STATEMENT + " where client_id = ?";
}

View File

@ -0,0 +1,82 @@
package com.github.pig.common.util;
import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.util.exception.CheckedException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.codec.Base64;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @author lengleng
* @date 2018/5/13
* 认证授权相关工具类
*/
@Slf4j
public class AuthUtils {
private static final String BASIC_ = "Basic ";
/**
* 从header 请求中的clientId/clientsecect
*
* @param header header中的参数
* @throws CheckedException if the Basic header is not present or is not valid
* Base64
*/
public static String[] extractAndDecodeHeader(String header)
throws IOException {
byte[] base64Token = header.substring(6).getBytes("UTF-8");
byte[] decoded;
try {
decoded = Base64.decode(base64Token);
} catch (IllegalArgumentException e) {
throw new CheckedException(
"Failed to decode basic authentication token");
}
String token = new String(decoded, CommonConstant.UTF8);
int delim = token.indexOf(":");
if (delim == -1) {
throw new CheckedException("Invalid basic authentication token");
}
return new String[]{token.substring(0, delim), token.substring(delim + 1)};
}
/**
* *从header 请求中的clientId/clientsecect
*
* @param request
* @return
* @throws IOException
*/
public static String[] extractAndDecodeHeader(HttpServletRequest request)
throws IOException {
String header = request.getHeader("Authorization");
if (header == null || !header.startsWith(BASIC_)) {
throw new CheckedException("请求头中client信息为空");
}
byte[] base64Token = header.substring(6).getBytes("UTF-8");
byte[] decoded;
try {
decoded = Base64.decode(base64Token);
} catch (IllegalArgumentException e) {
throw new CheckedException(
"Failed to decode basic authentication token");
}
String token = new String(decoded, CommonConstant.UTF8);
int delim = token.indexOf(":");
if (delim == -1) {
throw new CheckedException("Invalid basic authentication token");
}
return new String[]{token.substring(0, delim), token.substring(delim + 1)};
}
}

View File

@ -64,5 +64,5 @@ public class UserVO implements Serializable {
/**
* 角色列表
*/
private List<SysRole> roleList = new ArrayList<>();
private List<SysRole> roleList;
}

View File

@ -39,7 +39,7 @@
</appender>
<!-- Level: FATAL 0 ERROR 3 WARN 4 INFO 6 DEBUG 7 -->
<root level="WARN">
<root level="DEBUG">
<appender-ref ref="console" />
<appender-ref ref="debug" />
<appender-ref ref="error" />

View File

@ -10,7 +10,7 @@ spring:
config:
server:
git:
uri: https://gitee.com/cqzqxq_lxh/pig-config.git
uri: https://gitee.com/hsLeng/pig-config.git
default-label: ${spring.profiles.active} #解决监控down
# 关闭安全管理
@ -24,7 +24,7 @@ endpoints:
spring:
profiles: dev
rabbitmq:
host: 127.0.0.1
host: 139.224.200.249
port: 5682
username: pig
password: lengleng

View File

@ -44,11 +44,6 @@
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<!--rabbitMQ-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!--swagger ui-->
<dependency>
<groupId>io.springfox</groupId>

View File

@ -1,6 +1,6 @@
package com.github.pig.gateway.component.config;
import com.github.pig.common.bean.config.FilterUrlsPropertiesConfig;
import com.github.pig.common.bean.config.FilterIgnorePropertiesConfig;
import com.github.pig.gateway.component.filter.ValidateCodeFilter;
import com.github.pig.gateway.component.handler.PigAccessDeniedHandler;
import org.springframework.beans.factory.annotation.Autowired;
@ -15,7 +15,6 @@ import org.springframework.security.oauth2.config.annotation.web.configuration.E
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
/**
* @author lengleng
* @date 2017/10/27
@ -24,24 +23,19 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Autowired
private FilterUrlsPropertiesConfig filterUrlsPropertiesConfig;
private FilterIgnorePropertiesConfig filterIgnorePropertiesConfig;
@Autowired
private OAuth2WebSecurityExpressionHandler expressionHandler;
@Autowired
private PigAccessDeniedHandler pigAccessDeniedHandler;
@Autowired
private ValidateCodeFilter validateCodeFilter;
@Override
public void configure(HttpSecurity http) throws Exception {
//http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class);
//允许使用iframe 嵌套避免swagger-ui 不被加载的问题
http.headers().frameOptions().disable();
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http
.authorizeRequests();
for (String url : filterUrlsPropertiesConfig.getAnon()) {
registry.antMatchers(url).permitAll();
}
filterIgnorePropertiesConfig.getUrls().forEach(url -> registry.antMatchers(url).permitAll());
registry.anyRequest()
.access("@permissionService.hasPermission(request,authentication)");
}

View File

@ -15,8 +15,10 @@ import com.xiaoleilu.hutool.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
@ -32,12 +34,11 @@ import static org.springframework.cloud.netflix.zuul.filters.support.FilterConst
* 演示环境控制
*/
@Slf4j
@Component
@RefreshScope
@Configuration
@ConditionalOnProperty(value = "security.validate.preview", havingValue = "true")
public class PreviewFilter extends ZuulFilter {
private static final String TOKEN = "token";
@Value("${security.validate.preview:true}")
private boolean isPreview;
@Override
public String filterType() {
@ -53,15 +54,14 @@ public class PreviewFilter extends ZuulFilter {
public boolean shouldFilter() {
HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
if (StrUtil.equalsIgnoreCase(request.getMethod(), HttpMethod.GET.name()) ||
StrUtil.containsIgnoreCase(request.getRequestURI(), TOKEN)) {
return false;
StrUtil.containsIgnoreCase(request.getRequestURI(), TOKEN)){
return false;
}
return isPreview;
return true;
}
@Override
public Object run() {
log.warn("演示环境,没有权限操作 -> {}", isPreview);
RequestContext ctx = RequestContext.getCurrentContext();
R<String> result = new R<>();
result.setCode(479);

View File

@ -1,43 +1,44 @@
package com.github.pig.gateway.component.filter;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pig.common.bean.config.FilterIgnorePropertiesConfig;
import com.github.pig.common.constant.SecurityConstants;
import com.github.pig.common.util.AuthUtils;
import com.github.pig.common.util.R;
import com.github.pig.common.util.exception.ValidateCodeException;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.xiaoleilu.hutool.collection.CollUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Arrays;
/**
* @author lengleng
* @date 2018/5/10
*
* <p>
* security.validate.code.enabled 默认 为false开启需要设置为true
*
* 验证码校验true开启false关闭校验
* 更细化可以 clientId 进行区分
*/
@Slf4j
@RefreshScope
@Configuration("validateCodeFilter")
@ConditionalOnProperty(value = "security.validate.code.enabled", havingValue = "true")
@ConditionalOnProperty(value = "security.validate.code", havingValue = "true")
public class ValidateCodeFilter extends ZuulFilter {
private static final String EXPIRED_CAPTCHA_ERROR = "验证码已过期,请重新获取";
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private FilterIgnorePropertiesConfig filterIgnorePropertiesConfig;
@Override
public String filterType() {
@ -49,14 +50,33 @@ public class ValidateCodeFilter extends ZuulFilter {
return FilterConstants.SEND_ERROR_FILTER_ORDER + 1;
}
/**
* 是否校验验证码
* 1. 判断验证码开关是否开启
* 2. 判断请求是否登录请求
* 3. 判断终端是否支持
*
* @return true/false
*/
@Override
public boolean shouldFilter() {
HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
if (StrUtil.containsIgnoreCase(request.getRequestURI(), SecurityConstants.OAUTH_TOKEN_URL)
|| StrUtil.containsIgnoreCase(request.getRequestURI(), SecurityConstants.MOBILE_TOKEN_URL)) {
return true;
if (!StrUtil.containsAnyIgnoreCase(request.getRequestURI(),
SecurityConstants.OAUTH_TOKEN_URL, SecurityConstants.MOBILE_TOKEN_URL)) {
return false;
}
return false;
try {
String[] clientInfos = AuthUtils.extractAndDecodeHeader(request);
if (CollUtil.containsAny(filterIgnorePropertiesConfig.getClients(), Arrays.asList(clientInfos))) {
return false;
}
} catch (IOException e) {
log.error("解析终端信息失败", e);
}
return true;
}
@Override
@ -67,7 +87,6 @@ public class ValidateCodeFilter extends ZuulFilter {
RequestContext ctx = RequestContext.getCurrentContext();
R<String> result = new R<>(e);
result.setCode(478);
result.setMsg("演示环境,没有权限操作");
ctx.setResponseStatusCode(478);
ctx.setSendZuulResponse(false);

View File

@ -23,11 +23,6 @@
<artifactId>pig-common</artifactId>
<version>${pig.version}</version>
</dependency>
<!--rabbitMQ-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!--阿里大于-->
<dependency>
<groupId>com.aliyun</groupId>

View File

@ -25,8 +25,8 @@ import org.springframework.stereotype.Component;
public class SmsAliyunMessageHandler extends AbstractMessageHandler {
@Autowired
private SmsAliyunPropertiesConfig smsAliyunPropertiesConfig;
private static final String product = "Dysmsapi";
private static final String domain = "dysmsapi.aliyuncs.com";
private static final String PRODUCT = "Dysmsapi";
private static final String DOMAIN = "dysmsapi.aliyuncs.com";
/**
* 数据校验
@ -53,7 +53,7 @@ public class SmsAliyunMessageHandler extends AbstractMessageHandler {
//初始化acsClient,暂不支持region化
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", smsAliyunPropertiesConfig.getAccessKey(), smsAliyunPropertiesConfig.getSecretKey());
try {
DefaultProfile.addEndpoint("cn-hou", "cn-hangzhou", product, domain);
DefaultProfile.addEndpoint("cn-hou", "cn-hangzhou", PRODUCT, DOMAIN);
} catch (ClientException e) {
log.error("初始化SDK 异常", e);
e.printStackTrace();

View File

@ -57,11 +57,6 @@
<version>${velocity-engine-core.version}</version>
</dependency>
<!--mybatis-plus end -->
<!--rabbitMQ-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!--七牛-->
<dependency>
<groupId>com.qiniu</groupId>

View File

@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import java.io.Serializable;
@ -34,10 +35,12 @@ public class SysUser extends Model<SysUser> {
*/
private String username;
@JsonIgnore
private String password;
/**
* 随机盐
*/
@JsonIgnore
private String salt;
/**
* 创建时间

View File

@ -34,10 +34,6 @@
<artifactId>spring-boot-admin-server-ui</artifactId>
<version>${spring-boot-admin-server-ui.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-turbine</artifactId>

View File

@ -6,7 +6,7 @@ import com.github.pig.common.constant.enums.EnumSmsChannel;
import com.github.pig.common.constant.enums.EnumSmsChannelTemplate;
import com.github.pig.common.util.template.MobileMsgTemplate;
import com.github.pig.monitor.config.MonitorPropertiesConfig;
import com.xiaoleilu.hutool.collection.CollectionUtil;
import com.xiaoleilu.hutool.collection.CollUtil;
import com.xiaoleilu.hutool.date.DateUtil;
import de.codecentric.boot.admin.event.ClientApplicationEvent;
import de.codecentric.boot.admin.event.ClientApplicationStatusChangedEvent;
@ -14,6 +14,8 @@ import de.codecentric.boot.admin.notify.AbstractStatusChangeNotifier;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import java.nio.file.Paths;
/**
* @author lengleng
* @date 2018/4/22
@ -70,7 +72,7 @@ public class StatusChangeNotifier extends AbstractStatusChangeNotifier {
log.info("开始短信通知,内容:{}", text);
rabbitTemplate.convertAndSend(MqQueueConstant.MOBILE_SERVICE_STATUS_CHANGE,
new MobileMsgTemplate(
CollectionUtil.join(monitorMobilePropertiesConfig.getMobile().getMobiles(), ","),
CollUtil.join(monitorMobilePropertiesConfig.getMobile().getMobiles(), ","),
contextJson.toJSONString(),
EnumSmsChannel.ALIYUN.getName(),
EnumSmsChannelTemplate.SERVICE_STATUS_CHANGE.getSignName(),