AipGatewayApiApplicationTests.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. package com.aip.gateway.api;
  2. import com.aip.gateway.api.aip.manager.AipFileManager;
  3. import com.aip.gateway.api.aip.model.AipConfig;
  4. import com.aip.gateway.api.aip.model.AipLabel;
  5. import com.aip.gateway.api.aip.model.AipTemplate;
  6. import com.aip.gateway.api.aip.utils.AipFileUtils;
  7. import com.aip.gateway.api.aip.utils.MemoryTokenCacheWithEviction;
  8. import com.google.common.base.Stopwatch;
  9. import com.microsoft.aad.msal4j.ClientCredentialFactory;
  10. import com.microsoft.aad.msal4j.ClientCredentialParameters;
  11. import com.microsoft.aad.msal4j.ConfidentialClientApplication;
  12. import com.microsoft.aad.msal4j.IAuthenticationResult;
  13. import com.nimbusds.oauth2.sdk.http.HTTPResponse;
  14. import lombok.extern.slf4j.Slf4j;
  15. import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
  16. import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
  17. import org.jasypt.salt.StringFixedSaltGenerator;
  18. import org.junit.jupiter.api.Test;
  19. import java.io.*;
  20. import java.net.HttpURLConnection;
  21. import java.net.URL;
  22. import java.nio.file.Files;
  23. import java.nio.file.Paths;
  24. import java.util.Collections;
  25. import java.util.List;
  26. import java.util.concurrent.CompletableFuture;
  27. import java.util.concurrent.TimeUnit;
  28. @Slf4j
  29. //@SpringBootTest
  30. class AipGatewayApiApplicationTests {
  31. private final String instance = "https://login.microsoftonline.com/";
  32. private final String tenantId = "2e58414a-c6ae-43ff-aaf5-45ab8b78a404";
  33. private final String clientId = "0e225915-3be3-419c-aa04-284d7de5e16b";
  34. private final String scope = "https://graph.microsoft.com/.default";
  35. private final String secret = "CvW8Q~0iANtLN1Y2EXR_nVyYb_tQTDwjW-Z7Ndg3";
  36. private final String secretFile = "C:\\Data\\SSL\\mip\\mip_gateway.pfx";
  37. private ConfidentialClientApplication app;
  38. @Test
  39. void test2() {
  40. String fileName = "c:\\data\\SSL\\mip\\mip_gateway.pfx";
  41. String ext = AipFileUtils.getExtension(fileName);
  42. String name = AipFileUtils.getFileName(fileName);
  43. log.error("[{}] , [{}] [{}] [{}]", fileName, ext, name, AipFileUtils.getFileNameWithoutExtension(fileName));
  44. }
  45. @Test
  46. void jasypt() {
  47. String encKey = "asdkjfaslkjflkajslfjkajlkf";
  48. PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
  49. SimpleStringPBEConfig config = new SimpleStringPBEConfig();
  50. // ==> SimpleStringPBEConfig 사용시 아래 3개 반드시 설정해야함
  51. config.setPassword(encKey); // 암호화에 사용할 키
  52. config.setPoolSize(1); // Pool Size
  53. config.setSaltGenerator(new StringFixedSaltGenerator("fixedSalt")); // 고정으로 암호화(Default: Random)
  54. //config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
  55. //config.setAlgorithm("PBEWithMD5AndTripleDES");
  56. config.setAlgorithm("PBEWithMD5AndDES"); // Jasypt 를 이용한 암호화 알고리즘
  57. config.setProviderName("SunJCE");
  58. config.setKeyObtentionIterations("10000");
  59. config.setStringOutputType("base64");
  60. /*private Boolean proxyPropertySources = false;
  61. private String bean = "jasyptStringEncryptor";
  62. private String password;
  63. private String algorithm = "PBEWithMD5AndDES";
  64. private String keyObtentionIterations = "1000";
  65. private String poolSize = "1";
  66. private String providerName = null;
  67. //config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
  68. private String saltGeneratorClassname = "org.jasypt.salt.RandomSaltGenerator";
  69. private String stringOutputType = "base64";*/
  70. encryptor.setConfig(config);
  71. String dbUser = encryptor.encrypt("aipuser");
  72. String dbPswd = encryptor.encrypt("aipuser");
  73. log.info("{}", dbUser);
  74. log.info("{}", dbPswd);
  75. }
  76. boolean AipFileInitialize(AipConfig aipConfig) {
  77. AipFileManager aipFileManager = new AipFileManager(aipConfig);
  78. if (!aipFileManager.initialize()) {
  79. log.error("AipFileManager.initialize Failed, {}, {}", aipFileManager.getLastErrNo(), aipFileManager.getLastErrMsg());
  80. return false;
  81. }
  82. if (!aipFileManager.createProfile()) {
  83. log.error("AipFileManager.createProfile Failed, {}, {}", aipFileManager.getLastErrNo(), aipFileManager.getLastErrMsg());
  84. return false;
  85. }
  86. if (!aipFileManager.createEngine()) {
  87. log.error("AipFileManager.createEngine Failed, {}, {}", aipFileManager.getLastErrNo(), aipFileManager.getLastErrMsg());
  88. return false;
  89. }
  90. log.info("AipFileManager Initialize And Create Success.");
  91. List<AipLabel> labels = aipFileManager.sensitivityLabels();
  92. log.info("{}", labels);
  93. List<AipLabel> policies = aipFileManager.listSensitivityLabels();
  94. log.info("{}", policies);
  95. List<AipTemplate> templates = aipFileManager.getTemplates();
  96. log.info("{}", templates);
  97. return true;
  98. }
  99. @Test
  100. void aipTest() {
  101. AipConfig aipConfig = AipConfig.builder()
  102. .appName("AIP Gateway RESTFull Service")
  103. .appVersion("1.0.0.0")
  104. .clientId("0e225915-3be3-419c-aa04-284d7de5e16b")
  105. .tenantId("2e58414a-c6ae-43ff-aaf5-45ab8b78a404")
  106. .mipData("App_Data\\\\mip_data")
  107. .loginType(AipConfig.authLoginCert)
  108. .domain("AIP.Gateway")
  109. .eMail("seungho@ms365.hanteinfo.com")
  110. .secretValue("CvW8Q~0iANtLN1Y2EXR_nVyYb_tQTDwjW-Z7Ndg3")
  111. .certThumbPrint("C:\\\\Data\\\\SSL\\\\mip\\\\mip_gateway.pfx")
  112. .build();
  113. AipFileInitialize(aipConfig);
  114. }
  115. private IAuthenticationResult getAccessTokenByClientCredentialGrant(String instance, String clientId, String tenantId, String secret, String scope) throws Exception {
  116. // Setup the token cache first. It is configured to allow 100k token entries, which at 2-3KB per entry, will take under 500MB of memory
  117. // Note that size calculations are approximate and depend on the JVM
  118. String cacheKey = clientId + "_" + tenantId + "_AppTokenCache";
  119. MemoryTokenCacheWithEviction memoryTokenCacheWithEviction = new MemoryTokenCacheWithEviction(cacheKey);
  120. ConfidentialClientApplication cca = ConfidentialClientApplication.builder(
  121. clientId,
  122. ClientCredentialFactory.createFromSecret(secret))
  123. .authority(instance + tenantId)
  124. .setTokenCacheAccessAspect(memoryTokenCacheWithEviction)
  125. .build();
  126. // Important: point the CCA object to a token cache
  127. ClientCredentialParameters clientCredentialParam = ClientCredentialParameters.builder(
  128. Collections.singleton(scope))
  129. .build();
  130. Stopwatch stopwatch = Stopwatch.createStarted();
  131. CompletableFuture<IAuthenticationResult> future = cca.acquireToken(clientCredentialParam);
  132. IAuthenticationResult result = future.get();
  133. log.info("Time to fetch the token: {} ms.", stopwatch.elapsed(TimeUnit.MILLISECONDS));
  134. return result;
  135. }
  136. private void getOrCreateApp(String clientId, String authority, String certPath) throws Exception {
  137. if (app == null) {
  138. //PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(Files.readAllBytes(Paths.get(keyPath)));
  139. //PrivateKey key = KeyFactory.getInstance("RSA").generatePrivate(spec);
  140. InputStream certStream = new ByteArrayInputStream(Files.readAllBytes(Paths.get(certPath)));
  141. //X509Certificate cert = (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(certStream);
  142. String password = "hanteinfo1234!";
  143. app = ConfidentialClientApplication.builder(
  144. clientId,
  145. ClientCredentialFactory.createFromCertificate(certStream, password))
  146. //ClientCredentialFactory.createFromCertificate(key, cert))
  147. .authority(authority)
  148. .build();
  149. }
  150. }
  151. private String getUsersListFromGraph(String accessToken) throws IOException {
  152. URL url = new URL("https://graph.microsoft.com/v1.0/users");
  153. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  154. conn.setRequestMethod("GET");
  155. conn.setRequestProperty("Authorization", "Bearer " + accessToken);
  156. conn.setRequestProperty("Accept","application/json");
  157. int httpResponseCode = conn.getResponseCode();
  158. if(httpResponseCode == HTTPResponse.SC_OK) {
  159. StringBuilder response;
  160. try(BufferedReader in = new BufferedReader(
  161. new InputStreamReader(conn.getInputStream()))){
  162. String inputLine;
  163. response = new StringBuilder();
  164. while (( inputLine = in.readLine()) != null) {
  165. response.append(inputLine);
  166. }
  167. }
  168. return response.toString();
  169. } else {
  170. return String.format("Connection returned HTTP code: %s with message: %s",
  171. httpResponseCode, conn.getResponseMessage());
  172. }
  173. }
  174. @Test
  175. void testSecretAuth() {
  176. try {
  177. IAuthenticationResult result = getAccessTokenByClientCredentialGrant(instance, clientId, tenantId, secret, scope);
  178. // If you try to fetch the same token again, it will hit the token cache and it will be much faster.
  179. // In case AAD has an outage, cached tokens are still available, increasing your app's resiliency.
  180. result = getAccessTokenByClientCredentialGrant(instance, clientId, tenantId, secret, scope);
  181. String usersListFromGraph = getUsersListFromGraph(result.accessToken());
  182. log.info("Users in the Tenant = {}", usersListFromGraph);
  183. System.out.println("Press any key to exit ...");
  184. System.in.read();
  185. } catch(Exception ex){
  186. System.out.println("Oops! We have an exception of type - " + ex.getClass());
  187. System.out.println("Exception message - " + ex.getMessage());
  188. try {
  189. throw ex;
  190. } catch (Exception e) {
  191. throw new RuntimeException(e);
  192. }
  193. }
  194. }
  195. @Test
  196. void testCertFile() {
  197. try {
  198. // Ensure the app object is not re-created on each request, as it holds a token cache
  199. // If you are getting tokens for many tenants (millions), see the msal-client-credential-secret-high-availability sample
  200. // which shows how to use an in-memory token cache with eviction based on a size limit
  201. getOrCreateApp(clientId, instance+tenantId, "C:\\Data\\SSL\\mip\\mip_gateway.pfx");
  202. ClientCredentialParameters clientCredentialParam = ClientCredentialParameters.builder(
  203. Collections.singleton(scope))
  204. .build();
  205. // The first time this is called, the app will make an HTTP request to the token issuer, so this is slow. Latency can be >1s
  206. IAuthenticationResult result = app.acquireToken(clientCredentialParam).get();
  207. // On subsequent calls, the app will return a token from its cache. It is important to reuse the app object
  208. // Now that we have a Bearer token, call the protected API
  209. String usersListFromGraph = getUsersListFromGraph(result.accessToken());
  210. System.out.println("Users in the Tenant = " + usersListFromGraph);
  211. System.out.println("Press any key to exit ...");
  212. System.in.read();
  213. } catch (Exception ex) {
  214. System.out.println("Oops! We have an exception of type - " + ex.getClass());
  215. System.out.println("Exception message - " + ex.getMessage());
  216. try {
  217. throw ex;
  218. } catch (Exception e) {
  219. throw new RuntimeException(e);
  220. }
  221. }
  222. }
  223. // @Test
  224. // void testAip() throws ExecutionException, InterruptedException {
  225. // InputStreamReader input = new InputStreamReader(System.in);
  226. // BufferedReader reader = new BufferedReader(input);
  227. //
  228. // // ApplicationInfo is used to store the application name, clientId, and version.
  229. // ApplicationInfo appInfo = new ApplicationInfo();
  230. // FileOptions options = new FileOptions();
  231. //
  232. // appInfo.setApplicationId("0e225915-3be3-419c-aa04-284d7de5e16b");
  233. // appInfo.setApplicationName("MIP SDK Java Sample");
  234. // appInfo.setApplicationVersion("1.11");
  235. //
  236. // String userName = "shjung@ms365.hanteinfo.com";
  237. //
  238. // Action action = new Action(appInfo, userName);
  239. //
  240. // // Fetch the list of labels for the authenticated user and display.
  241. // action.ListLabels();
  242. //
  243. // // Copy a label Id from the output and paste into the prompt.
  244. // options.LabelId = "1098bdb0-f2bc-43d3-b9c7-e610431fc1a4";
  245. //
  246. // // Provide an input file that should be labeled.
  247. // options.InputFilePath = "C:\\Data\\Source\\source.pptx";
  248. //
  249. // // Provide the output path for the file. The original file remains intact and a
  250. // // copy is created.
  251. // options.OutputFilePath = "C:\\Data\\Source\\source-out.pptx";
  252. //
  253. // // The privileged AssignmentMethod is used when users label files, and can
  254. // // override STANDARD.
  255. // options.AssignmentMethod = AssignmentMethod.PRIVILEGED;
  256. //
  257. // // Information on datastate is used to populate audit information. This field
  258. // // doesn't impact the SDK behavior.
  259. // options.DataState = DataState.REST;
  260. //
  261. // // Sets whether the sample should generate an audit event.
  262. // options.IsAuditDiscoveryEnabled = true;
  263. //
  264. // // Apply the chosen label to the input file.
  265. //
  266. // boolean result = action.SetLabel(options);
  267. //
  268. // if (result) {
  269. // // This section attempts to read the label from the file, if one was applied.
  270. // log.error("Reading label from file...");
  271. //
  272. // options.InputFilePath = options.OutputFilePath;
  273. //
  274. // log.error("File Name: " + options.InputFilePath);
  275. // log.error("File Label: " + action.GetLabel(options).label.getName());
  276. //
  277. // log.error("Reading owner from file...");
  278. // log.error("File Label: " + action.GetProtection(options).getOwner());
  279. // }
  280. // else {
  281. // log.error("No changes were written to the input file.");
  282. // }
  283. //
  284. // }
  285. }