diff --git a/maxkey-core/src/main/java/org/maxkey/authn/AbstractAuthenticationProvider.java b/maxkey-core/src/main/java/org/maxkey/authn/AbstractAuthenticationProvider.java
index 4f60ee08d..4fe47fa39 100644
--- a/maxkey-core/src/main/java/org/maxkey/authn/AbstractAuthenticationProvider.java
+++ b/maxkey-core/src/main/java/org/maxkey/authn/AbstractAuthenticationProvider.java
@@ -87,6 +87,10 @@ public abstract class AbstractAuthenticationProvider {
.getAttribute(WebConstants.CURRENT_LOGIN_USER_PASSWORD_SET_TYPE);
// 登录完成后切换SESSION
_logger.debug("Login Session {}.", WebContext.getSession().getId());
+
+ final Object firstSavedRequest =
+ WebContext.getAttribute(WebConstants.FIRST_SAVED_REQUEST_PARAMETER);
+
WebContext.getSession().invalidate();
WebContext.setAttribute(
WebConstants.CURRENT_USER_SESSION_ID, WebContext.getSession().getId());
@@ -95,6 +99,7 @@ public abstract class AbstractAuthenticationProvider {
authenticationRealm.insertLoginHistory(
userInfo, ConstantsLoginType.LOCAL, "", "xe00000004", "success");
+ WebContext.setAttribute(WebConstants.FIRST_SAVED_REQUEST_PARAMETER,firstSavedRequest);
// 认证设置
WebContext.setAuthentication(authentication);
WebContext.setUserInfo(userInfo);
diff --git a/maxkey-core/src/main/java/org/maxkey/authn/SavedRequestAwareAuthenticationSuccessHandler.java b/maxkey-core/src/main/java/org/maxkey/authn/SavedRequestAwareAuthenticationSuccessHandler.java
index 86ee74269..b5f5b46cb 100644
--- a/maxkey-core/src/main/java/org/maxkey/authn/SavedRequestAwareAuthenticationSuccessHandler.java
+++ b/maxkey-core/src/main/java/org/maxkey/authn/SavedRequestAwareAuthenticationSuccessHandler.java
@@ -20,45 +20,47 @@ import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.util.StringUtils;
/**
- * An authentication success strategy which can make use of the {@link DefaultSavedRequest} which may have been stored in
- * the session by the {@link ExceptionTranslationFilter}. When such a request is intercepted and requires authentication,
- * the request data is stored to record the original destination before the authentication process commenced, and to
- * allow the request to be reconstructed when a redirect to the same URL occurs. This class is responsible for
- * performing the redirect to the original URL if appropriate.
+ * An authentication success strategy which can make use of the
+ * {@link DefaultSavedRequest} which may have been stored in the session by the
+ * {@link ExceptionTranslationFilter}. When such a request is intercepted and
+ * requires authentication, the request data is stored to record the original
+ * destination before the authentication process commenced, and to allow the
+ * request to be reconstructed when a redirect to the same URL occurs. This
+ * class is responsible for performing the redirect to the original URL if
+ * appropriate.
*
- * Following a successful authentication, it decides on the redirect destination, based on the following scenarios:
+ * Following a successful authentication, it decides on the redirect
+ * destination, based on the following scenarios:
*
- *
- * If the {@code alwaysUseDefaultTargetUrl} property is set to true, the {@code defaultTargetUrl}
- * will be used for the destination. Any {@code DefaultSavedRequest} stored in the session will be
- * removed.
- *
- *
- * If the {@code targetUrlParameter} has been set on the request, the value will be used as the destination.
- * Any {@code DefaultSavedRequest} will again be removed.
- *
- *
- * If a {@link SavedRequest} is found in the {@code RequestCache} (as set by the {@link ExceptionTranslationFilter} to
- * record the original destination before the authentication process commenced), a redirect will be performed to the
- * Url of that original destination. The {@code SavedRequest} object will remain cached and be picked up
- * when the redirected request is received
- * (See {@link org.springframework.security.web.savedrequest.SavedRequestAwareWrapper SavedRequestAwareWrapper}).
- *
- *
- * If no {@code SavedRequest} is found, it will delegate to the base class.
+ *
If the {@code alwaysUseDefaultTargetUrl} property is set to true, the
+ * {@code defaultTargetUrl} will be used for the destination. Any
+ * {@code DefaultSavedRequest} stored in the session will be removed.
+ *
If the {@code targetUrlParameter} has been set on the request, the value
+ * will be used as the destination. Any {@code DefaultSavedRequest} will again
+ * be removed.
+ *
If a {@link SavedRequest} is found in the {@code RequestCache} (as set by
+ * the {@link ExceptionTranslationFilter} to record the original destination
+ * before the authentication process commenced), a redirect will be performed to
+ * the Url of that original destination. The {@code SavedRequest} object will
+ * remain cached and be picked up when the redirected request is received (See
+ * {@link org.springframework.security.web.savedrequest.SavedRequestAwareWrapper
+ * SavedRequestAwareWrapper}).
+ *
If no {@code SavedRequest} is found, it will delegate to the base class.
*
*
*
* @author Luke Taylor
* @since 3.0
*/
-public class SavedRequestAwareAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
- protected final Logger _logger = LoggerFactory.getLogger(SavedRequestAwareAuthenticationSuccessHandler.class);
+public class SavedRequestAwareAuthenticationSuccessHandler
+ extends SimpleUrlAuthenticationSuccessHandler {
+ protected final Logger _logger = LoggerFactory.getLogger(
+ SavedRequestAwareAuthenticationSuccessHandler.class);
@Autowired
- @Qualifier("remeberMeService")
- protected AbstractRemeberMeService remeberMeService;
-
+ @Qualifier("remeberMeService")
+ protected AbstractRemeberMeService remeberMeService;
+
private RequestCache requestCache = new HttpSessionRequestCache();
@Override
@@ -66,15 +68,18 @@ public class SavedRequestAwareAuthenticationSuccessHandler extends SimpleUrlAuth
Authentication authentication) throws ServletException, IOException {
SavedRequest savedRequest = requestCache.getRequest(request, response);
- remeberMeService.createRemeberMe(authentication.getPrincipal().toString(), request, response);
-
+ remeberMeService.createRemeberMe(
+ authentication.getPrincipal().toString(), request, response);
+
if (savedRequest == null) {
super.onAuthenticationSuccess(request, response, authentication);
return;
}
String targetUrlParameter = getTargetUrlParameter();
- if (isAlwaysUseDefaultTargetUrl() || (targetUrlParameter != null && StringUtils.hasText(request.getParameter(targetUrlParameter)))) {
+ if (isAlwaysUseDefaultTargetUrl()
+ || (targetUrlParameter != null
+ && StringUtils.hasText(request.getParameter(targetUrlParameter)))) {
requestCache.removeRequest(request, response);
super.onAuthenticationSuccess(request, response, authentication);
@@ -82,16 +87,18 @@ public class SavedRequestAwareAuthenticationSuccessHandler extends SimpleUrlAuth
}
clearAuthenticationAttributes(request);
-
+
// Use the DefaultSavedRequest URL
String targetUrl = savedRequest.getRedirectUrl();
-
- //is cas login , with service parameter
- logger.info( request.getParameter(WebConstants.CAS_SERVICE_PARAMETER));
- if(request.getParameter(WebConstants.CAS_SERVICE_PARAMETER)!=null && request.getParameter(WebConstants.CAS_SERVICE_PARAMETER).startsWith("http")){
- targetUrl=WebContext.getHttpContextPath()+"/authorize/cas/login?service="+request.getParameter(WebConstants.CAS_SERVICE_PARAMETER);
+
+ // is cas login , with service parameter
+ logger.info("CAS " + request.getParameter(WebConstants.CAS_SERVICE_PARAMETER));
+ if (request.getParameter(WebConstants.CAS_SERVICE_PARAMETER) != null
+ && request.getParameter(WebConstants.CAS_SERVICE_PARAMETER).startsWith("http")) {
+ targetUrl = WebContext.getHttpContextPath() + "/authorize/cas/login?service="
+ + request.getParameter(WebConstants.CAS_SERVICE_PARAMETER);
}
-
+ targetUrl = targetUrl == null ? "/forwardindex" : targetUrl;
logger.debug("Redirecting to DefaultSavedRequest Url: " + targetUrl);
getRedirectStrategy().sendRedirect(request, response, targetUrl);
}
diff --git a/maxkey-core/src/main/java/org/maxkey/authn/realm/IAuthenticationServer.java b/maxkey-core/src/main/java/org/maxkey/authn/realm/IAuthenticationServer.java
index a9faa16e7..ae709d291 100644
--- a/maxkey-core/src/main/java/org/maxkey/authn/realm/IAuthenticationServer.java
+++ b/maxkey-core/src/main/java/org/maxkey/authn/realm/IAuthenticationServer.java
@@ -1,14 +1,12 @@
-/**
- *
- */
package org.maxkey.authn.realm;
/**
+ * IAuthenticationServer .
* @author Crystal.Sea
*
*/
public interface IAuthenticationServer {
- public boolean authenticate(String username, String password) ;
+ public boolean authenticate(String username, String password);
}
diff --git a/maxkey-core/src/main/java/org/maxkey/web/WebConstants.java b/maxkey-core/src/main/java/org/maxkey/web/WebConstants.java
index 18baf2933..6a04ea672 100644
--- a/maxkey-core/src/main/java/org/maxkey/web/WebConstants.java
+++ b/maxkey-core/src/main/java/org/maxkey/web/WebConstants.java
@@ -1,7 +1,7 @@
package org.maxkey.web;
/**
- * Web Application Constants define
+ * Web Application Constants define.
*
* @author Crystal.Sea
*
@@ -32,9 +32,7 @@ public class WebConstants {
public static final String CURRENT_MESSAGE = "current_message";
// SPRING_SECURITY_SAVED_REQUEST
- public static final String SPRING_PROCESS_SAVED_REQUEST = "SPRING_SECURITY_SAVED_REQUEST";
-
- public static final String FIRST_SAVED_REQUEST_PARAMETER = "first_saved_request_parameter";
+ public static final String FIRST_SAVED_REQUEST_PARAMETER = "SPRING_SECURITY_SAVED_REQUEST";
public static final String KAPTCHA_SESSION_KEY = "kaptcha_session_key";
diff --git a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/springframework/ui/velocity/VelocityEngineFactory.java b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/springframework/ui/velocity/VelocityEngineFactory.java
index eab9b6412..c89cc3cc0 100644
--- a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/springframework/ui/velocity/VelocityEngineFactory.java
+++ b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/springframework/ui/velocity/VelocityEngineFactory.java
@@ -71,7 +71,6 @@ import org.springframework.util.StringUtils;
* @see org.apache.velocity.app.VelocityEngine
* @deprecated as of Spring 4.3, in favor of FreeMarker
*/
-@Deprecated
public class VelocityEngineFactory {
protected final Log logger = LogFactory.getLog(getClass());
diff --git a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/springframework/ui/velocity/VelocityEngineFactoryBean.java b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/springframework/ui/velocity/VelocityEngineFactoryBean.java
index 7164847df..7c5de1f66 100644
--- a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/springframework/ui/velocity/VelocityEngineFactoryBean.java
+++ b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/springframework/ui/velocity/VelocityEngineFactoryBean.java
@@ -48,7 +48,6 @@ import org.springframework.context.ResourceLoaderAware;
* @see org.springframework.web.servlet.view.velocity.VelocityConfigurer
* @deprecated as of Spring 4.3, in favor of FreeMarker
*/
-@Deprecated
public class VelocityEngineFactoryBean extends VelocityEngineFactory
implements FactoryBean, InitializingBean, ResourceLoaderAware {
diff --git a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/springframework/ui/velocity/VelocityEngineUtils.java b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/springframework/ui/velocity/VelocityEngineUtils.java
index e5b06aae0..7167641d8 100644
--- a/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/springframework/ui/velocity/VelocityEngineUtils.java
+++ b/maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/springframework/ui/velocity/VelocityEngineUtils.java
@@ -32,7 +32,6 @@ import org.apache.velocity.exception.VelocityException;
* @since 22.01.2004
* @deprecated as of Spring 4.3, in favor of FreeMarker
*/
-@Deprecated
public abstract class VelocityEngineUtils {
/**
@@ -46,7 +45,6 @@ public abstract class VelocityEngineUtils {
* @deprecated Use {@link #mergeTemplate(VelocityEngine, String, String, Map, Writer)}
* instead, following Velocity 1.6's corresponding deprecation in its own API.
*/
- @Deprecated
public static void mergeTemplate(
VelocityEngine velocityEngine, String templateLocation, Map model, Writer writer)
throws VelocityException {
@@ -86,7 +84,6 @@ public abstract class VelocityEngineUtils {
* @deprecated Use {@link #mergeTemplateIntoString(VelocityEngine, String, String, Map)}
* instead, following Velocity 1.6's corresponding deprecation in its own API.
*/
- @Deprecated
public static String mergeTemplateIntoString(VelocityEngine velocityEngine, String templateLocation,
Map model) throws VelocityException {
diff --git a/maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtMvcConfig.java b/maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtMvcConfig.java
index 6d173c224..77615cc24 100644
--- a/maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtMvcConfig.java
+++ b/maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtMvcConfig.java
@@ -43,16 +43,21 @@ public class MaxKeyMgtMvcConfig implements WebMvcConfigurer {
.addPathPatterns("/orgs/**")
.addPathPatterns("/userinfo/**")
.addPathPatterns("/apps/**")
+ .addPathPatterns("/app/accounts/**")
.addPathPatterns("/groups/**")
.addPathPatterns("/groupMember/**")
.addPathPatterns("/groupPrivileges/**")
+ .addPathPatterns("/roles/**")
+ .addPathPatterns("/rolemembers/**")
+ .addPathPatterns("/resources/**")
+ .addPathPatterns("/permissions/**")
.addPathPatterns("/config/**")
.addPathPatterns("/logs/**")
;
+
_logger.debug("add PermissionAdapter");
registry.addInterceptor(historyLogsAdapter)
- .addPathPatterns("/users/*")
.addPathPatterns("/userinfo/**")
.addPathPatterns("/enterprises/**")
.addPathPatterns("/employees/**")
@@ -64,6 +69,7 @@ public class MaxKeyMgtMvcConfig implements WebMvcConfigurer {
.addPathPatterns("/approles/**")
;
_logger.debug("add HistoryLogsAdapter");
+
registry.addInterceptor(localeChangeInterceptor);
_logger.debug("add LocaleChangeInterceptor");
diff --git a/maxkey-web-maxkey/src/main/java/org/maxkey/web/endpoint/IndexEndpoint.java b/maxkey-web-maxkey/src/main/java/org/maxkey/web/endpoint/IndexEndpoint.java
index 1dea6680f..2b6abef45 100644
--- a/maxkey-web-maxkey/src/main/java/org/maxkey/web/endpoint/IndexEndpoint.java
+++ b/maxkey-web-maxkey/src/main/java/org/maxkey/web/endpoint/IndexEndpoint.java
@@ -1,5 +1,10 @@
package org.maxkey.web.endpoint;
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import org.maxkey.config.ApplicationConfig;
import org.maxkey.constants.ConstantsPasswordSetType;
import org.maxkey.domain.UserInfo;
@@ -25,9 +30,10 @@ public class IndexEndpoint {
@Autowired
@Qualifier("applicationConfig")
ApplicationConfig applicationConfig;
-
@RequestMapping(value={"/forwardindex"})
- public ModelAndView forwardindex() {
+ public ModelAndView forwardindex(HttpServletRequest request,
+ HttpServletResponse response) throws ServletException, IOException {
+
_logger.debug("IndexEndpoint /forwardindex.");
ModelAndView modelAndView=new ModelAndView();
Integer passwordSetType=(Integer)WebContext.getSession().getAttribute(WebConstants.CURRENT_LOGIN_USER_PASSWORD_SET_TYPE);
@@ -54,11 +60,14 @@ public class IndexEndpoint {
return modelAndView;
}
+
+
return new ModelAndView("index");
}
@RequestMapping(value={"/index"})
- public ModelAndView home() {
+ public ModelAndView home(HttpServletRequest request,
+ HttpServletResponse response) throws ServletException, IOException {
_logger.debug("IndexEndpoint /index.");
if(applicationConfig.getLoginConfig().getDefaultUri()!=null&&
diff --git a/maxkey-web-maxkey/src/main/java/org/maxkey/web/endpoint/LoginEndpoint.java b/maxkey-web-maxkey/src/main/java/org/maxkey/web/endpoint/LoginEndpoint.java
index b2923a34a..6753d0c1e 100644
--- a/maxkey-web-maxkey/src/main/java/org/maxkey/web/endpoint/LoginEndpoint.java
+++ b/maxkey-web-maxkey/src/main/java/org/maxkey/web/endpoint/LoginEndpoint.java
@@ -1,7 +1,9 @@
package org.maxkey.web.endpoint;
+import java.io.IOException;
import java.util.HashMap;
+import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -22,9 +24,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
-import org.springframework.security.web.savedrequest.RequestCache;
-import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.ModelAttribute;
@@ -148,18 +147,7 @@ public class LoginEndpoint {
modelAndView.addObject("ssopList", socialSignOnProviderService.getSocialSignOnProviders());
}
}
- //save first protected url
- SavedRequest firstSavedRequest = (SavedRequest)WebContext.getAttribute(WebConstants.FIRST_SAVED_REQUEST_PARAMETER);
- if(firstSavedRequest==null){
- RequestCache requestCache = new HttpSessionRequestCache();
- SavedRequest savedRequest =requestCache.getRequest(request, response);
- if(savedRequest!=null){
- _logger.debug("first request parameter "+savedRequest.getRedirectUrl());
- WebContext.setAttribute(WebConstants.FIRST_SAVED_REQUEST_PARAMETER, savedRequest);
- }
- }else {
- WebContext.setAttribute(WebConstants.SPRING_PROCESS_SAVED_REQUEST, firstSavedRequest);
- }
+
if(isAuthenticated){
return WebContext.redirect("/forwardindex");
@@ -169,12 +157,15 @@ public class LoginEndpoint {
}
@RequestMapping(value={"/logon.do"})
- public ModelAndView logon(@ModelAttribute("authentication") BasicAuthentication authentication) {
+ public ModelAndView logon(
+ HttpServletRequest request,
+ HttpServletResponse response,
+ @ModelAttribute("authentication") BasicAuthentication authentication) throws ServletException, IOException {
authenticationProvider.authenticate(authentication);
if(WebContext.isAuthenticated()){
- return WebContext.redirect("/forwardindex");
+ return WebContext.redirect("/forwardindex");
}else{
return WebContext.redirect("/login");
}
diff --git a/maxkey-web-maxkey/src/main/java/org/maxkey/web/interceptor/PermissionAdapter.java b/maxkey-web-maxkey/src/main/java/org/maxkey/web/interceptor/PermissionAdapter.java
index 899cb9540..c98bb4bab 100644
--- a/maxkey-web-maxkey/src/main/java/org/maxkey/web/interceptor/PermissionAdapter.java
+++ b/maxkey-web-maxkey/src/main/java/org/maxkey/web/interceptor/PermissionAdapter.java
@@ -4,12 +4,18 @@ import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+
+import org.maxkey.authn.SavedRequestAwareAuthenticationSuccessHandler;
import org.maxkey.config.ApplicationConfig;
+import org.maxkey.web.WebConstants;
import org.maxkey.web.WebContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
+import org.springframework.security.web.savedrequest.RequestCache;
+import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
/**
@@ -26,6 +32,11 @@ public class PermissionAdapter extends HandlerInterceptorAdapter {
@Qualifier("applicationConfig")
private ApplicationConfig applicationConfig;
+
+ @Autowired
+ @Qualifier("savedRequestSuccessHandler")
+ SavedRequestAwareAuthenticationSuccessHandler savedRequestSuccessHandler;
+
static ConcurrentHashMap navigationsMap = null;
/*
@@ -41,14 +52,34 @@ public class PermissionAdapter extends HandlerInterceptorAdapter {
HttpServletResponse response, Object handler)
throws Exception {
_logger.trace("PermissionAdapter preHandle");
+ //save first protected url
+ SavedRequest firstSavedRequest = (SavedRequest)WebContext.getAttribute(WebConstants.FIRST_SAVED_REQUEST_PARAMETER);
// 判断用户是否登录, 判断用户和角色,判断用户是否登录用户
if (WebContext.getAuthentication() == null
|| WebContext.getAuthentication().getAuthorities() == null) {
+ //保存未认证的请求信息
+ if(firstSavedRequest==null){
+ RequestCache requestCache = new HttpSessionRequestCache();
+ requestCache.saveRequest(request, response);
+ SavedRequest savedRequest =requestCache.getRequest(request, response);
+ if(savedRequest!=null){
+ _logger.debug("first request parameter savedRequest "+savedRequest.getRedirectUrl());
+ WebContext.setAttribute(WebConstants.FIRST_SAVED_REQUEST_PARAMETER, savedRequest);
+ savedRequestSuccessHandler.setRequestCache(requestCache);
+ }
+ }
+
_logger.trace("No Authentication ... forward to /login");
RequestDispatcher dispatcher = request.getRequestDispatcher("/login");
dispatcher.forward(request, response);
return false;
}
+
+ //认证完成,跳转到未认证请求
+ if(firstSavedRequest!=null) {
+ savedRequestSuccessHandler.onAuthenticationSuccess(request, response, WebContext.getAuthentication());
+ WebContext.removeAttribute(WebConstants.FIRST_SAVED_REQUEST_PARAMETER);
+ }
boolean hasAccess = true;
diff --git a/maxkey-web-maxkey/src/main/resources/spring/maxkey.xml b/maxkey-web-maxkey/src/main/resources/spring/maxkey.xml
index 37d5ba432..09962846e 100644
--- a/maxkey-web-maxkey/src/main/resources/spring/maxkey.xml
+++ b/maxkey-web-maxkey/src/main/resources/spring/maxkey.xml
@@ -185,6 +185,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/maxkey-web-maxkey/src/main/resources/templates/views/index.ftl b/maxkey-web-maxkey/src/main/resources/templates/views/index.ftl
index c1f85eca4..e164b6511 100644
--- a/maxkey-web-maxkey/src/main/resources/templates/views/index.ftl
+++ b/maxkey-web-maxkey/src/main/resources/templates/views/index.ftl
@@ -3,9 +3,11 @@
MaxKey
+
+
" />
-