diff --git a/docker/Dockerfile b/docker/Dockerfile index 9fb4932a..52c6430b 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -40,13 +40,16 @@ COPY providers/keycloak-sms-provider-yunxin.jar /opt/keycloak/providers/ #tencent provider COPY providers/keycloak-sms-provider-tencent.jar /opt/keycloak/providers/ -# + #aliyun provider COPY providers/keycloak-sms-provider-aliyun.jar /opt/keycloak/providers/ #aws provider COPY providers/keycloak-sms-provider-aws-sns.jar /opt/keycloak/providers/ +#wx app provider +COPY providers/keycloak-wx-provider-app.jar /opt/keycloak/providers/ + RUN mkdir /opt/keycloak/certs RUN /opt/keycloak/bin/kc.sh build diff --git a/examples/docker-compose.yml b/examples/docker-compose.yml index 574ad170..64a8edeb 100644 --- a/examples/docker-compose.yml +++ b/examples/docker-compose.yml @@ -26,7 +26,7 @@ services: ports: - 8080:8080 command: - - start-dev --spi-phone-default-service=dummy + - start-dev environment: KEYCLOAK_ADMIN: admin KEYCLOAK_ADMIN_PASSWORD: admin diff --git a/keycloak-sms-provider-aliyun/README.md b/keycloak-sms-provider-aliyun/README.md index 4121fa80..4acc5021 100644 --- a/keycloak-sms-provider-aliyun/README.md +++ b/keycloak-sms-provider-aliyun/README.md @@ -13,7 +13,7 @@ cp target/providers/keycloak-sms-provider-aliyun.jar ${KEYCLOAK_HOME}/providers/ ${KEYCLOAK_HOME}/bin/kc.sh build ${KEYCLOAK_HOME}/bin/kc.sh start --spi-phone-default-service=aliyun \ - --spi-message-sender-service-aliyun-region=cn-hangzhou \ + --spi-message-sender-service-aliyun-token=${token} \ --spi-message-sender-service-aliyun-key=${accessKey} \ --spi-message-sender-service-aliyun-secret=${accessSecret} \ --spi-message-sender-service-aliyun-otp-template={templateId} diff --git a/keycloak-sms-provider-aliyun/pom.xml b/keycloak-sms-provider-aliyun/pom.xml index 3dd669e3..889632ea 100644 --- a/keycloak-sms-provider-aliyun/pom.xml +++ b/keycloak-sms-provider-aliyun/pom.xml @@ -19,10 +19,23 @@ 2.4.1-snapshot provided + + + + + + + com.aliyun - aliyun-java-sdk-core - 4.6.3 + alibabacloud-dysmsapi20170525 + 3.0.0 + + + org.bouncycastle + bcprov-jdk15on + + diff --git a/keycloak-sms-provider-aliyun/src/main/java/cc/coopersoft/keycloak/phone/providers/sender/AliyunSmsSenderServiceProvider.java b/keycloak-sms-provider-aliyun/src/main/java/cc/coopersoft/keycloak/phone/providers/sender/AliyunSmsSenderServiceProvider.java index 56edde08..bee0c6de 100644 --- a/keycloak-sms-provider-aliyun/src/main/java/cc/coopersoft/keycloak/phone/providers/sender/AliyunSmsSenderServiceProvider.java +++ b/keycloak-sms-provider-aliyun/src/main/java/cc/coopersoft/keycloak/phone/providers/sender/AliyunSmsSenderServiceProvider.java @@ -4,18 +4,18 @@ import cc.coopersoft.keycloak.phone.providers.exception.MessageSendException; import cc.coopersoft.keycloak.phone.providers.spi.MessageSenderService; import cc.coopersoft.common.OptionalUtils; -import com.aliyuncs.CommonRequest; -import com.aliyuncs.CommonResponse; -import com.aliyuncs.DefaultAcsClient; -import com.aliyuncs.IAcsClient; -import com.aliyuncs.exceptions.ClientException; -import com.aliyuncs.http.MethodType; -import com.aliyuncs.profile.DefaultProfile; +import com.aliyun.auth.credentials.Credential; +import com.aliyun.auth.credentials.provider.StaticCredentialProvider; +import com.aliyun.sdk.service.dysmsapi20170525.AsyncClient; +import com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsRequest; +import com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsResponse; +import darabonba.core.client.ClientOverrideConfiguration; import org.jboss.logging.Logger; import org.keycloak.Config; import org.keycloak.models.RealmModel; import java.util.Optional; +import java.util.concurrent.CompletableFuture; public class AliyunSmsSenderServiceProvider implements MessageSenderService { @@ -23,13 +23,48 @@ public class AliyunSmsSenderServiceProvider implements MessageSenderService { private final Config.Scope config; private final RealmModel realm; - private final IAcsClient client; + private final AsyncClient client; public AliyunSmsSenderServiceProvider(Config.Scope config, RealmModel realm) { this.config = config; this.realm = realm; - DefaultProfile profile = DefaultProfile.getProfile(config.get("region") , config.get("key"), config.get("secret")); - client = new DefaultAcsClient(profile); + + // HttpClient Configuration + /*HttpClient httpClient = new ApacheAsyncHttpClientBuilder() + .connectionTimeout(Duration.ofSeconds(10)) // Set the connection timeout time, the default is 10 seconds + .responseTimeout(Duration.ofSeconds(10)) // Set the response timeout time, the default is 20 seconds + .maxConnections(128) // Set the connection pool size + .maxIdleTimeOut(Duration.ofSeconds(50)) // Set the connection pool timeout, the default is 30 seconds + // Configure the proxy + .proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("", 9001)) + .setCredentials("", "")) + // If it is an https connection, you need to configure the certificate, or ignore the certificate(.ignoreSSL(true)) + .x509TrustManagers(new X509TrustManager[]{}) + .keyManagers(new KeyManager[]{}) + .ignoreSSL(false) + .build();*/ + + + // Configure Credentials authentication information, including ak, secret, token + StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder() + .accessKeyId(config.get("key")) + .accessKeySecret(config.get("secret")) + .securityToken(config.get("token")) // use STS token + .build()); + + // Configure the Client + client = AsyncClient.builder() + //.httpClient(httpClient) // Use the configured HttpClient, otherwise use the default HttpClient (Apache HttpClient) + .credentialsProvider(provider) + //.serviceConfiguration(Configuration.create()) // Service-level configuration + // Client-level configuration rewrite, can set Endpoint, Http request parameters, etc. + .overrideConfiguration( + ClientOverrideConfiguration.create() + // Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi + .setEndpointOverride("dysmsapi.ap-southeast-1.aliyuncs.com") + //.setConnectTimeout(Duration.ofSeconds(30)) + ) + .build(); } @@ -40,27 +75,35 @@ public void sendSmsMessage(TokenCodeType type, String phoneNumber, String code, String templateId = Optional.ofNullable(config.get(realm.getName().toLowerCase() + "-" + kindName + "-template")) .orElse(config.get(kindName + "-template")); - CommonRequest request = new CommonRequest(); - request.setSysMethod(MethodType.POST); - request.setSysDomain("dysmsapi.aliyuncs.com"); - request.setSysVersion("2017-05-25"); - request.setSysAction("SendSms"); - request.putQueryParameter("RegionId", config.get("region")); - request.putQueryParameter("PhoneNumbers", phoneNumber); - request.putQueryParameter("SignName", realm.getDisplayName().toLowerCase()); - request.putQueryParameter("TemplateCode", templateId); - - request.putQueryParameter("TemplateParam", String.format("{\"code\":\"%s\",\"expires\":\"%s\"}",code,expires / 60)); - try { - CommonResponse response = client.getCommonResponse(request); - logger.debug(response.getData()); - } catch (ClientException e) { - throw new MessageSendException(500,e.getErrCode(),e.getMessage()); - } + // Parameter settings for API request + SendSmsRequest sendSmsRequest = SendSmsRequest.builder() + .phoneNumbers(phoneNumber) + .signName(realm.getDisplayName().toLowerCase()) + .templateCode(templateId) + .templateParam(String.format("{\"code\":\"%s\",\"expires\":\"%s\"}",code,expires / 60)) + // Request-level configuration rewrite, can set Http request parameters, etc. + // .requestConfiguration(RequestConfiguration.create().setHttpHeaders(new HttpHeaders())) + .build(); + + // Asynchronously get the return value of the API request + CompletableFuture response = client.sendSms(sendSmsRequest); + // Synchronously get the return value of the API request + //SendSmsResponse resp = response.get(); + //System.out.println(new Gson().toJson(resp)); + // Asynchronous processing of return values + /*response.thenAccept(resp -> { + System.out.println(new Gson().toJson(resp)); + }).exceptionally(throwable -> { // Handling exceptions + System.out.println(throwable.getMessage()); + return null; + });*/ + + // Finally, close the client + client.close(); } @Override public void close() { - + client.close(); } }