Change default port (#316)

diff --git a/README.md b/README.md
index bd45c64..04792db 100644
--- a/README.md
+++ b/README.md
@@ -164,7 +164,10 @@
 If you are deploying Pulsar Manager using the latest code, you can create a super-user using the following command. Then you can use the super user credentials to log in the Pulsar Manager UI.
 
     ```$xslt
+    CSRF_TOKEN=$(curl http://backend-service:7750/pulsar-manager/csrf-token)
     curl \
+        -H 'X-XSRF-TOKEN: $CSRF_TOKEN' \
+        -H 'Cookie: XSRF-TOKEN=$CSRF_TOKEN;' \
         -H "Content-Type: application/json" \
         -X PUT http://backend-service:7750/pulsar-manager/users/superuser \
         -d '{"name": "admin", "password": "apachepulsar", "description": "test", "email": "username@test.org"}'
diff --git a/build.gradle b/build.gradle
index b856ed3..786039c 100644
--- a/build.gradle
+++ b/build.gradle
@@ -142,6 +142,8 @@
     compile group: 'org.glassfish.jersey.core', name: 'jersey-client', version: jerseyVersion
     compile group: 'org.glassfish.jersey.inject', name: 'jersey-hk2', version: jerseyVersion
     compile group: 'org.glassfish.jersey.media', name: 'jersey-media-json-jackson', version: jerseyVersion
+    compile group: 'org.springframework.boot', name: 'spring-boot-starter-security'
+    compile group: 'org.springframework.security', name: 'spring-security-config'
     compileOnly group: 'org.projectlombok', name: 'lombok', version: lombokVersion
     compileOnly group: 'org.springframework.boot', name: 'spring-boot-devtools', version: springBootVersion
     testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: springBootVersion
diff --git a/front-end/src/api/tokens.js b/front-end/src/api/tokens.js
index 4844cf2..0e7af41 100644
--- a/front-end/src/api/tokens.js
+++ b/front-end/src/api/tokens.js
@@ -56,3 +56,10 @@
     method: 'get'
   })
 }
+
+export function getCsrfToken() {
+  return request({
+    url: SPRING_BASE_URL + '/csrf-token',
+    method: 'get'
+  })
+}
diff --git a/front-end/src/store/modules/user.js b/front-end/src/store/modules/user.js
index 0bae227..b2acd3c 100644
--- a/front-end/src/store/modules/user.js
+++ b/front-end/src/store/modules/user.js
@@ -15,6 +15,7 @@
 import { getToken, setToken, removeToken } from '@/utils/auth'
 import { setName, removeName } from '@/utils/username'
 import { removeEnvironment } from '@/utils/environment'
+import { removeCsrfToken } from '@/utils/csrfToken'
 import { Message } from 'element-ui'
 import { setTenant, removeTenant } from '../../utils/tenant'
 import { getUserInfo } from '@/api/users'
@@ -104,6 +105,7 @@
           commit('SET_TOKEN', '')
           commit('SET_ROLES', [])
           removeToken()
+          removeCsrfToken()
           removeName()
           removeTenant()
           removeEnvironment()
diff --git a/front-end/src/utils/csrfToken.js b/front-end/src/utils/csrfToken.js
new file mode 100644
index 0000000..d9014cf
--- /dev/null
+++ b/front-end/src/utils/csrfToken.js
@@ -0,0 +1,28 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import Cookies from 'js-cookie'
+
+const csrfToken = 'XSRF-TOKEN'
+
+export function getCsrfToken() {
+  return Cookies.get(csrfToken)
+}
+
+export function setCsrfToken(csrfToken) {
+  return Cookies.set(csrfToken, csrfToken)
+}
+
+export function removeCsrfToken() {
+  return Cookies.remove(csrfToken)
+}
diff --git a/front-end/src/utils/request.js b/front-end/src/utils/request.js
index 1f971ee..1a55e73 100644
--- a/front-end/src/utils/request.js
+++ b/front-end/src/utils/request.js
@@ -20,6 +20,7 @@
 import { getEnvironment } from '@/utils/environment'
 import { getTenant } from '@/utils/tenant'
 import router from '../router'
+import { getCsrfToken } from '@/utils/csrfToken'
 
 // create an axios instance
 const service = axios.create({
@@ -37,6 +38,7 @@
     config.headers['username'] = getName()
     config.headers['tenant'] = getTenant()
     config.headers['environment'] = getEnvironment()
+    config.headers['X-XSRF-TOKEN'] = getCsrfToken()
     return config
   },
   error => {
diff --git a/front-end/src/views/login/index.vue b/front-end/src/views/login/index.vue
index f94bb63..f4b79c3 100644
--- a/front-end/src/views/login/index.vue
+++ b/front-end/src/views/login/index.vue
@@ -72,6 +72,8 @@
 <script>
 import LangSelect from '@/components/LangSelect'
 import SocialSign from './socialsignin'
+import { getCsrfToken } from '@/api/tokens'
+import { setCsrfToken } from '@/utils/csrfToken'
 
 export default {
   name: 'Login',
@@ -118,6 +120,7 @@
   },
   created() {
     // window.addEventListener('hashchange', this.afterQRScan)
+    this.fetchCsrfToken()
   },
   destroyed() {
     window.removeEventListener('hashchange', this.afterQRScan)
@@ -172,6 +175,11 @@
       //     this.$router.push({ path: '/' })
       //   })
       // }
+    },
+    fetchCsrfToken() {
+      getCsrfToken().then(response => {
+        setCsrfToken(response.headers['x-csrf-token'])
+      })
     }
   }
 }
diff --git a/src/main/java/org/apache/pulsar/manager/controller/CsrfTokenController.java b/src/main/java/org/apache/pulsar/manager/controller/CsrfTokenController.java
new file mode 100644
index 0000000..535b3dc
--- /dev/null
+++ b/src/main/java/org/apache/pulsar/manager/controller/CsrfTokenController.java
@@ -0,0 +1,39 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pulsar.manager.controller;
+
+import io.swagger.annotations.Api;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.web.csrf.CsrfToken;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+import javax.servlet.http.HttpServletRequest;
+
+@RestController
+@RequestMapping(value = "/pulsar-manager")
+@Api(description = "Generate csrf token for per page.")
+public class CsrfTokenController {
+
+    @RequestMapping(value="/csrf-token", method= RequestMethod.GET)
+    public ResponseEntity<String> getCsrfToken(HttpServletRequest request) {
+        CsrfToken token = (CsrfToken)request.getAttribute(CsrfToken.class.getName());
+        HttpHeaders headers = new HttpHeaders();
+        headers.add("X-Csrf-Token", token.getToken());
+        return new ResponseEntity<> (token.getToken(), headers, HttpStatus.OK);
+    }
+
+}
diff --git a/src/main/java/org/apache/pulsar/manager/interceptor/AdminHandlerInterceptor.java b/src/main/java/org/apache/pulsar/manager/interceptor/AdminHandlerInterceptor.java
index 433e5d0..0d630d0 100644
--- a/src/main/java/org/apache/pulsar/manager/interceptor/AdminHandlerInterceptor.java
+++ b/src/main/java/org/apache/pulsar/manager/interceptor/AdminHandlerInterceptor.java
@@ -15,7 +15,6 @@
 
 import com.google.common.collect.Maps;
 import com.google.gson.Gson;
-import org.apache.commons.lang.StringUtils;
 import org.apache.pulsar.manager.entity.EnvironmentEntity;
 import org.apache.pulsar.manager.entity.EnvironmentsRepository;
 import org.apache.pulsar.manager.entity.UserInfoEntity;
@@ -27,13 +26,11 @@
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.lang.Nullable;
 import org.springframework.stereotype.Component;
-import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.servlet.ModelAndView;
 import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import javax.validation.Valid;
 import java.util.Map;
 import java.util.Optional;
 
@@ -64,8 +61,9 @@
     @Override
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
         // allow frontend requests, in case of front-end running on the same process of backend
-        if (request.getRequestURI().startsWith("/ui")
-                || request.getRequestURI().startsWith("/static")) {
+
+        if (request.getServletPath().startsWith("/ui")
+                || request.getServletPath().startsWith("/static")) {
             return true;
         }
         String token = request.getHeader("token");
@@ -95,11 +93,11 @@
                 return false;
             }
         }
-        String requestUri = request.getRequestURI();
+        String requestUri = request.getServletPath();
         if (!requestUri.equals("/pulsar-manager/users/userInfo")) {
             String environment = request.getHeader("environment");
             Optional<EnvironmentEntity> environmentEntityOptional = environmentsRepository.findByName(environment);
-            if (!request.getRequestURI().startsWith("/pulsar-manager/environments") && !environmentEntityOptional.isPresent()) {
+            if (!request.getServletPath().startsWith("/pulsar-manager/environments") && !environmentEntityOptional.isPresent()) {
                 map.put("message", "Currently there is no active environment, please set one");
                 response.setStatus(400);
                 response.getWriter().append(gson.toJson(map));
diff --git a/src/main/java/org/apache/pulsar/manager/interceptor/WebAppConfigurer.java b/src/main/java/org/apache/pulsar/manager/interceptor/WebAppConfigurer.java
index 0c97479..a70a2a5 100644
--- a/src/main/java/org/apache/pulsar/manager/interceptor/WebAppConfigurer.java
+++ b/src/main/java/org/apache/pulsar/manager/interceptor/WebAppConfigurer.java
@@ -35,6 +35,7 @@
         registry.addInterceptor(adminHandlerInterceptor).addPathPatterns("/**")
                 .excludePathPatterns("/pulsar-manager/login")
                 .excludePathPatterns("/pulsar-manager/users/superuser")
+                .excludePathPatterns("/pulsar-manager/csrf-token")
                 .excludePathPatterns("/pulsar-manager/third-party-login/**")
                 // static front-end resources
                 .excludePathPatterns("/ui")
diff --git a/src/main/java/org/apache/pulsar/manager/security/SecurityConfig.java b/src/main/java/org/apache/pulsar/manager/security/SecurityConfig.java
new file mode 100644
index 0000000..a2f476d
--- /dev/null
+++ b/src/main/java/org/apache/pulsar/manager/security/SecurityConfig.java
@@ -0,0 +1,33 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pulsar.manager.security;
+
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
+
+/**
+ * Security Config.
+ */
+@SuppressWarnings("unchecked")
+@EnableWebSecurity
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
+
+    @Override
+    public void configure(HttpSecurity http) throws Exception {
+        http.csrf()
+                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());;
+    }
+}
diff --git a/src/main/java/org/apache/pulsar/manager/zuul/EnvironmentForward.java b/src/main/java/org/apache/pulsar/manager/zuul/EnvironmentForward.java
index d3336c0..da0d8cc 100644
--- a/src/main/java/org/apache/pulsar/manager/zuul/EnvironmentForward.java
+++ b/src/main/java/org/apache/pulsar/manager/zuul/EnvironmentForward.java
@@ -83,7 +83,8 @@
         HttpServletRequest request = ctx.getRequest();
         String redirect = request.getParameter("redirect");
 
-        String requestUri = request.getRequestURI();
+        String requestUri = request.getServletPath();
+        request.getServletPath();
         String token = request.getHeader("token");
 
         if (!rolesService.isSuperUser(token)) {
@@ -129,17 +130,17 @@
     }
 
     private Object forwardRequest(RequestContext ctx, HttpServletRequest request, String serviceUrl) {
-        ctx.put(REQUEST_URI_KEY, request.getRequestURI());
+        ctx.put(REQUEST_URI_KEY, request.getServletPath());
         try {
             Map<String, String> authHeader = pulsarAdminService.getAuthHeader(serviceUrl);
             authHeader.entrySet().forEach(entry -> ctx.addZuulRequestHeader(entry.getKey(), entry.getValue()));
             ctx.setRouteHost(new URL(serviceUrl));
-            pulsarEvent.parsePulsarEvent(request.getRequestURI(), request);
+            pulsarEvent.parsePulsarEvent(request.getServletPath(), request);
             log.info("Forward request to {} @ path {}",
-                    serviceUrl, request.getRequestURI());
+                    serviceUrl, request.getServletPath());
         } catch (MalformedURLException e) {
             log.error("Route forward to {} path {} error: {}",
-                    serviceUrl, request.getRequestURI(), e.getMessage());
+                    serviceUrl, request.getServletPath(), e.getMessage());
         }
         return null;
     }
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 46e0462..31a07b1 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -13,7 +13,7 @@
 #
 
 spring.cloud.refresh.refreshable=none
-server.port=8080
+server.port=7750
 
 # configuration log
 logging.path=