diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/angular/ui/.angular-cli.json b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/angular/ui/.angular-cli.json
index a781f3aaaa..2b50d70065 100644
--- a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/angular/ui/.angular-cli.json
+++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/angular/ui/.angular-cli.json
@@ -6,7 +6,7 @@
"apps": [
{
"root": "src",
- "outDir": "../../resources/public",
+ "outDir": "../../resources/static/home",
"assets": [
"assets",
"favicon.ico"
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/angular/ui/src/index.html b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/angular/ui/src/index.html
index c98f7b29d6..f53f1e4ae6 100644
--- a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/angular/ui/src/index.html
+++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/angular/ui/src/index.html
@@ -3,7 +3,7 @@
Ui
-
+
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/SecurityConfig.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/SecurityConfig.java
index 752382aa4c..2741118678 100644
--- a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/SecurityConfig.java
+++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/SecurityConfig.java
@@ -26,16 +26,21 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
- .httpBasic()
+ .formLogin()
+ .loginPage("/login.html")
+ .loginProcessingUrl("/login")
+ .defaultSuccessUrl("/home/index.html")
.and()
.authorizeRequests()
+ .antMatchers("/book-service/**", "/rating-service/**", "/login*").permitAll()
.antMatchers("/eureka/**").hasRole("ADMIN")
- .anyRequest().permitAll()
+ .antMatchers("/home/*").authenticated()
+ .anyRequest().authenticated()
.and()
.logout()
.and()
.addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class)
- .csrf().csrfTokenRepository(csrfTokenRepository()).ignoringAntMatchers("/logout");
+ .csrf().csrfTokenRepository(csrfTokenRepository());
}
private CsrfTokenRepository csrfTokenRepository() {
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/favicon.ico b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/favicon.ico
similarity index 100%
rename from spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/favicon.ico
rename to spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/favicon.ico
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/index.html b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/index.html
similarity index 96%
rename from spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/index.html
rename to spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/index.html
index b5db60844f..fa434d86bd 100644
--- a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/index.html
+++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/index.html
@@ -3,7 +3,7 @@
Ui
-
+
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/inline.bundle.js b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/inline.bundle.js
similarity index 100%
rename from spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/inline.bundle.js
rename to spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/inline.bundle.js
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/inline.bundle.js.map b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/inline.bundle.js.map
similarity index 96%
rename from spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/inline.bundle.js.map
rename to spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/inline.bundle.js.map
index ce5b662529..b7d273d794 100644
--- a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/inline.bundle.js.map
+++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/inline.bundle.js.map
@@ -1 +1 @@
-{"version":3,"sources":["webpack:///webpack/bootstrap 9308ff2b844df71fc1fd"],"names":[],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAQ,oBAAoB;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAY,2BAA2B;AACvC;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,mDAA2C,cAAc;;AAEzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA,kDAA0C,oBAAoB,WAAW","file":"inline.bundle.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [], result;\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId])\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);\n \t\twhile(resolves.length)\n \t\t\tresolves.shift()();\n \t\tif(executeModules) {\n \t\t\tfor(i=0; i < executeModules.length; i++) {\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = executeModules[i]);\n \t\t\t}\n \t\t}\n \t\treturn result;\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// objects to store loaded and loading chunks\n \tvar installedChunks = {\n \t\t4: 0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId) {\n \t\tif(installedChunks[chunkId] === 0)\n \t\t\treturn Promise.resolve();\n\n \t\t// an Promise means \"currently loading\".\n \t\tif(installedChunks[chunkId]) {\n \t\t\treturn installedChunks[chunkId][2];\n \t\t}\n \t\t// start chunk loading\n \t\tvar head = document.getElementsByTagName('head')[0];\n \t\tvar script = document.createElement('script');\n \t\tscript.type = 'text/javascript';\n \t\tscript.charset = 'utf-8';\n \t\tscript.async = true;\n \t\tscript.timeout = 120000;\n\n \t\tif (__webpack_require__.nc) {\n \t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n \t\t}\n \t\tscript.src = __webpack_require__.p + \"\" + chunkId + \".chunk.js\";\n \t\tvar timeout = setTimeout(onScriptComplete, 120000);\n \t\tscript.onerror = script.onload = onScriptComplete;\n \t\tfunction onScriptComplete() {\n \t\t\t// avoid mem leaks in IE.\n \t\t\tscript.onerror = script.onload = null;\n \t\t\tclearTimeout(timeout);\n \t\t\tvar chunk = installedChunks[chunkId];\n \t\t\tif(chunk !== 0) {\n \t\t\t\tif(chunk) chunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));\n \t\t\t\tinstalledChunks[chunkId] = undefined;\n \t\t\t}\n \t\t};\n\n \t\tvar promise = new Promise(function(resolve, reject) {\n \t\t\tinstalledChunks[chunkId] = [resolve, reject];\n \t\t});\n \t\tinstalledChunks[chunkId][2] = promise;\n\n \t\thead.appendChild(script);\n \t\treturn promise;\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// identity function for calling harmony imports with the correct context\n \t__webpack_require__.i = function(value) { return value; };\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 9308ff2b844df71fc1fd"],"sourceRoot":""}
\ No newline at end of file
+{"version":3,"sources":["webpack:///webpack/bootstrap 4559b314d1c9c6b8ff0b"],"names":[],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAQ,oBAAoB;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAY,2BAA2B;AACvC;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,mDAA2C,cAAc;;AAEzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA,kDAA0C,oBAAoB,WAAW","file":"inline.bundle.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [], result;\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId])\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);\n \t\twhile(resolves.length)\n \t\t\tresolves.shift()();\n \t\tif(executeModules) {\n \t\t\tfor(i=0; i < executeModules.length; i++) {\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = executeModules[i]);\n \t\t\t}\n \t\t}\n \t\treturn result;\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// objects to store loaded and loading chunks\n \tvar installedChunks = {\n \t\t4: 0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId) {\n \t\tif(installedChunks[chunkId] === 0)\n \t\t\treturn Promise.resolve();\n\n \t\t// an Promise means \"currently loading\".\n \t\tif(installedChunks[chunkId]) {\n \t\t\treturn installedChunks[chunkId][2];\n \t\t}\n \t\t// start chunk loading\n \t\tvar head = document.getElementsByTagName('head')[0];\n \t\tvar script = document.createElement('script');\n \t\tscript.type = 'text/javascript';\n \t\tscript.charset = 'utf-8';\n \t\tscript.async = true;\n \t\tscript.timeout = 120000;\n\n \t\tif (__webpack_require__.nc) {\n \t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n \t\t}\n \t\tscript.src = __webpack_require__.p + \"\" + chunkId + \".chunk.js\";\n \t\tvar timeout = setTimeout(onScriptComplete, 120000);\n \t\tscript.onerror = script.onload = onScriptComplete;\n \t\tfunction onScriptComplete() {\n \t\t\t// avoid mem leaks in IE.\n \t\t\tscript.onerror = script.onload = null;\n \t\t\tclearTimeout(timeout);\n \t\t\tvar chunk = installedChunks[chunkId];\n \t\t\tif(chunk !== 0) {\n \t\t\t\tif(chunk) chunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));\n \t\t\t\tinstalledChunks[chunkId] = undefined;\n \t\t\t}\n \t\t};\n\n \t\tvar promise = new Promise(function(resolve, reject) {\n \t\t\tinstalledChunks[chunkId] = [resolve, reject];\n \t\t});\n \t\tinstalledChunks[chunkId][2] = promise;\n\n \t\thead.appendChild(script);\n \t\treturn promise;\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// identity function for calling harmony imports with the correct context\n \t__webpack_require__.i = function(value) { return value; };\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 4559b314d1c9c6b8ff0b"],"sourceRoot":""}
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/main.bundle.js b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/main.bundle.js
similarity index 100%
rename from spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/main.bundle.js
rename to spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/main.bundle.js
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/main.bundle.js.map b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/main.bundle.js.map
similarity index 100%
rename from spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/main.bundle.js.map
rename to spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/main.bundle.js.map
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/polyfills.bundle.js b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/polyfills.bundle.js
similarity index 100%
rename from spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/polyfills.bundle.js
rename to spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/polyfills.bundle.js
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/polyfills.bundle.js.map b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/polyfills.bundle.js.map
similarity index 100%
rename from spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/polyfills.bundle.js.map
rename to spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/polyfills.bundle.js.map
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/styles.bundle.js b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/styles.bundle.js
similarity index 100%
rename from spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/styles.bundle.js
rename to spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/styles.bundle.js
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/styles.bundle.js.map b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/styles.bundle.js.map
similarity index 100%
rename from spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/styles.bundle.js.map
rename to spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/styles.bundle.js.map
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/vendor.bundle.js b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/vendor.bundle.js
similarity index 100%
rename from spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/vendor.bundle.js
rename to spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/vendor.bundle.js
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/vendor.bundle.js.map b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/vendor.bundle.js.map
similarity index 100%
rename from spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/public/vendor.bundle.js.map
rename to spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/home/vendor.bundle.js.map
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/login.html b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/login.html
new file mode 100644
index 0000000000..92c1b35ac9
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/login.html
@@ -0,0 +1,65 @@
+
+
+
+
+ Login
+
+
+
+
+
+
\ No newline at end of file