From cd16757f2cd963749850d6f8897381a8b7a849ef Mon Sep 17 00:00:00 2001
From: fengxiang <110431245@qq.com>
Date: Thu, 01 Feb 2018 15:09:43 +0800
Subject: [PATCH] 安全模块

---
 src/main/java/com/moral/security/CustomCorsFilter.java                                  |   33 +
 src/main/java/com/moral/config/MvcConfiguration.java                                    |    6 
 src/main/webapp/js/moralmap.js                                                          |   30 
 src/main/java/com/moral/security/model/token/JwtTokenFactory.java                       |   93 +++
 src/main/java/com/moral/security/auth/login/LoginAwareAuthenticationFailureHandler.java |   53 +
 src/main/java/com/moral/mapper/MonitorPointMapper.java                                  |    2 
 src/main/java/com/moral/security/auth/login/LoginProcessingFilter.java                  |   84 ++
 src/main/java/com/moral/security/exceptions/JwtExpiredTokenException.java               |   29 
 src/main/java/com/moral/security/common/ErrorCode.java                                  |   27 
 src/main/java/com/moral/service/DeviceService.java                                      |    3 
 src/main/java/com/moral/security/auth/JwtAuthenticationToken.java                       |   61 +
 src/main/java/com/moral/security/model/UserContext.java                                 |   58 +
 src/main/java/com/moral/entity/MonitorPoint.java                                        |    2 
 src/main/java/com/moral/security/auth/jwt/JwtAuthenticationProvider.java                |   68 ++
 src/main/resources/mapper/DeviceMapper.xml                                              |   14 
 src/main/java/com/moral/security/auth/jwt/verifier/TokenVerifier.java                   |   11 
 src/main/java/com/moral/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java        |   31 +
 src/main/java/com/moral/security/auth/login/LoginMode.java                              |    5 
 src/main/webapp/view/map.jsp                                                            |   10 
 src/main/java/com/moral/entity/Account.java                                             |   11 
 src/main/resources/system/sysConfig.properties                                          |    3 
 src/main/java/com/moral/security/auth/login/LoginAwareAuthenticationSuccessHandler.java |   74 ++
 src/main/java/com/moral/entity/Role.java                                                |    8 
 src/main/java/com/moral/security/model/token/JwtToken.java                              |    5 
 src/main/java/com/moral/common/util/Crypto.java                                         |    4 
 src/main/java/com/moral/security/RestAuthenticationEntryPoint.java                      |   26 
 src/main/java/com/moral/security/model/token/RawAccessJwtToken.java                     |   41 +
 src/main/java/com/moral/security/auth/jwt/verifier/BloomFilterTokenVerifier.java        |   18 
 src/main/java/com/moral/service/impl/DeviceServiceImpl.java                             |   14 
 src/main/java/com/moral/mapper/type/AdjustValueTypeHandle.java                          |    1 
 src/main/java/com/moral/security/config/PasswordEncoderConfig.java                      |   20 
 src/main/java/com/moral/security/endpoint/RefreshTokenEndpoint.java                     |   82 ++
 src/main/java/com/moral/security/model/token/RefreshToken.java                          |   65 ++
 src/main/java/com/moral/security/config/JwtSettings.java                                |   59 +
 src/main/java/com/moral/controller/MapController.java                                   |   56 +
 src/main/java/com/moral/mapper/DeviceMapper.java                                        |    1 
 src/main/java/com/moral/service/impl/MonitorPointServiceImpl.java                       |   26 
 src/main/java/com/moral/security/endpoint/ProfileEndpoint.java                          |   24 
 src/main/java/com/moral/service/AccountService.java                                     |    2 
 src/main/java/com/moral/service/impl/AccountServiceImpl.java                            |   21 
 src/main/java/com/moral/security/common/WebUtil.java                                    |   31 +
 src/main/java/com/moral/security/config/WebSecurityConfig.java                          |  118 +++
 src/main/java/com/moral/security/common/ErrorResponse.java                              |   52 +
 src/main/java/com/moral/security/auth/jwt/SkipPathRequestMatcher.java                   |   37 +
 /dev/null                                                                               |   89 --
 src/main/java/com/moral/security/auth/login/LoginAuthenticationProvider.java            |   74 ++
 src/main/java/com/moral/security/auth/jwt/extractor/TokenExtractor.java                 |   13 
 src/test/java/com/moral/JavaBeanToJsonOutPrint.java                                     |   13 
 src/main/java/com/moral/security/auth/login/LoginRequest.java                           |   40 +
 src/main/resources/mapper/MonitorPointMapper.xml                                        |   25 
 src/main/java/com/moral/security/model/Scopes.java                                      |   16 
 src/main/java/com/moral/security/exceptions/AuthMethodNotSupportedException.java        |   17 
 src/main/java/com/moral/security/model/token/AccessJwtToken.java                        |   30 
 src/main/java/com/moral/security/auth/jwt/JwtTokenAuthenticationProcessingFilter.java   |   64 ++
 src/main/java/com/moral/security/exceptions/InvalidJwtToken.java                        |   12 
 src/main/resources/application.yml                                                      |   12 
 56 files changed, 1,641 insertions(+), 183 deletions(-)

diff --git a/src/main/java/com/moral/common/util/Crypto.java b/src/main/java/com/moral/common/util/Crypto.java
index 2a8be1a..14b2996 100644
--- a/src/main/java/com/moral/common/util/Crypto.java
+++ b/src/main/java/com/moral/common/util/Crypto.java
@@ -29,4 +29,8 @@
         }
         return newstr;
     }
+    public static boolean checkpw(String plaintext, String hashed){
+            hashed = hashed == null?"":hashed;
+            return  hashed.equals(md5(plaintext));
+    }
 }
diff --git a/src/main/java/com/moral/config/MvcConfiguration.java b/src/main/java/com/moral/config/MvcConfiguration.java
index 7eff65c..7d63670 100644
--- a/src/main/java/com/moral/config/MvcConfiguration.java
+++ b/src/main/java/com/moral/config/MvcConfiguration.java
@@ -3,9 +3,7 @@
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.web.servlet.ViewResolver;
-import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
-import org.springframework.web.servlet.config.annotation.EnableWebMvc;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.springframework.web.servlet.config.annotation.*;
 import org.springframework.web.servlet.view.InternalResourceViewResolver;
 
 @Configuration
@@ -23,6 +21,4 @@
             DefaultServletHandlerConfigurer configurer) {
         configurer.enable();
     }
-
-
 }
diff --git a/src/main/java/com/moral/controller/MapController.java b/src/main/java/com/moral/controller/MapController.java
index c32d4b5..88281a4 100644
--- a/src/main/java/com/moral/controller/MapController.java
+++ b/src/main/java/com/moral/controller/MapController.java
@@ -2,15 +2,17 @@
 
 
 import com.alibaba.fastjson.JSONObject;
+import com.moral.common.bean.Constants;
 import com.moral.common.bean.PageBean;
+import com.moral.common.bean.PageResult;
 import com.moral.common.bean.ResultBean;
 import com.moral.entity.Account;
+import com.moral.entity.Device;
 import com.moral.entity.MapBounds;
 import com.moral.entity.MonitorPoint;
-import com.moral.service.AccountService;
-import com.moral.service.AreaService;
-import com.moral.service.MonitorPointService;
-import com.moral.service.SensorService;
+import com.moral.service.*;
+import lombok.extern.log4j.Log4j;
+import org.apache.log4j.Logger;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.*;
@@ -27,6 +29,9 @@
 @Controller
 @RequestMapping("map")
 public class MapController {
+    public  static Logger log = Logger.getLogger(MapController.class);
+    @Resource
+    DeviceService deviceService;
     @Resource
     AreaService areaService;
     @Resource
@@ -35,22 +40,33 @@
     SensorService sensorService;
     @Resource
     MonitorPointService monitorPointService;
+
     @RequestMapping(value = "/main-page", method = RequestMethod.GET)
     public String map(Model model,@RequestParam("areaCode")int code,@RequestParam("accountId")int accountId){
         Account account = accountService.getAccountById(accountId);
         String regionName = areaService.selectFullNameByCode(code);
-        Object sensors = sensorService.queryAll();
-        JSONObject params = new JSONObject();
-        params.put("regionCode",code);
-        params.put("regionName",regionName);
-        params.put("accountId", accountId);
-        params.put("orgId", account.getOrganizationId());
-        params.put("sensors", sensors);
-        String paramsJson = params.toJSONString();
-        model.addAttribute("mapParams",paramsJson);
-        return "map";
+        if(account!=null&&regionName!=null){
+            Object sensors = sensorService.queryAll();
+            JSONObject params = new JSONObject();
+            params.put("regionCode",code);
+            params.put("regionName",regionName);
+            params.put("accountId", accountId);
+            params.put("orgId", account.getOrganizationId());
+            params.put("sensors", sensors);
+            String paramsJson = params.toJSONString();
+            model.addAttribute("mapParams",paramsJson);
+            return "map";
+        } else {
+            StringBuilder msg = new StringBuilder();
+            msg.append(" param[0] areaCode:");
+            msg.append(code);
+            msg.append(" param[0] accountId:");
+            msg.append(accountId);
+            log.warn(msg);
+            return "401";
+        }
     }
-    @RequestMapping(value="/getmonitorpoints",method = RequestMethod.GET)
+    @RequestMapping(value="/get-monitorpoints",method = RequestMethod.GET)
     @ResponseBody
     public ResultBean getMonitorpointList(@RequestParam("orgId")String orgId,MapBounds mapBounds){
         ResultBean< List<MonitorPoint>> resultBean = new ResultBean();
@@ -62,4 +78,14 @@
         resultBean.setCode(ResultBean.SUCCESS);
         return resultBean;
     }
+    @RequestMapping(value = "get-devices-for-popup",method = RequestMethod.GET)
+    @ResponseBody
+    public PageResult getDevicesForPopup(
+            @RequestParam("orgId")Integer orgId,
+            String name,
+            Integer pageSize,
+            Integer pageNo
+    ){
+        return  deviceService.query(orgId,name,pageSize,pageNo);
+    }
 }
diff --git a/src/main/java/com/moral/entity/Account.java b/src/main/java/com/moral/entity/Account.java
index 02eb11e..1498df9 100644
--- a/src/main/java/com/moral/entity/Account.java
+++ b/src/main/java/com/moral/entity/Account.java
@@ -1,6 +1,8 @@
 package com.moral.entity;
 
+import java.util.Arrays;
 import java.util.Date;
+import java.util.List;
 
 import javax.persistence.Id;
 import javax.persistence.Transient;
@@ -71,7 +73,14 @@
 	private Date expireTime;
 
 	private String userName;
-
+	@Transient
+    private List<Role> Roles;
+	// TODO ������������
+	public List<Role> getRoles(){
+		Role role = new Role();
+		role.setName("temp");
+		return Arrays.asList(role);
+	}
 	@Transient
 	private Organization organization;
 
diff --git a/src/main/java/com/moral/entity/MonitorPoint.java b/src/main/java/com/moral/entity/MonitorPoint.java
index 3075b6a..5909997 100644
--- a/src/main/java/com/moral/entity/MonitorPoint.java
+++ b/src/main/java/com/moral/entity/MonitorPoint.java
@@ -96,6 +96,8 @@
      */
     private String description;
     @Transient
+    private Integer state;
+    @Transient
     private AreaNames areaNames;
     @Transient
     private Organization organization;
diff --git a/src/main/java/com/moral/entity/Role.java b/src/main/java/com/moral/entity/Role.java
new file mode 100644
index 0000000..4ec205b
--- /dev/null
+++ b/src/main/java/com/moral/entity/Role.java
@@ -0,0 +1,8 @@
+package com.moral.entity;
+
+import lombok.Data;
+
+@Data
+public class Role {
+   private String name;
+}
diff --git a/src/main/java/com/moral/mapper/DeviceMapper.java b/src/main/java/com/moral/mapper/DeviceMapper.java
index 0fbc5c4..1eba557 100644
--- a/src/main/java/com/moral/mapper/DeviceMapper.java
+++ b/src/main/java/com/moral/mapper/DeviceMapper.java
@@ -14,4 +14,5 @@
 	List<Map<String, Object>> getDeviceStatesByAccount(Map<String, Object> parameters);
     List<Device>  selectWithRelationData(Example example);
 	List<Map<String, Object>> getSensorsByDevice(@Param("mac")String mac);
+	List<Device> selectByOrgIdAndDevName(@Param("orgId")Integer orgId,@Param("devName")String devName);
 }
\ No newline at end of file
diff --git a/src/main/java/com/moral/mapper/MonitorPointMapper.java b/src/main/java/com/moral/mapper/MonitorPointMapper.java
index b0addba..f6244bc 100644
--- a/src/main/java/com/moral/mapper/MonitorPointMapper.java
+++ b/src/main/java/com/moral/mapper/MonitorPointMapper.java
@@ -11,5 +11,5 @@
 	List<MonitorPoint> selectWithAreaNameByExample(Example example);
 	List<MonitorPoint> getMonitorPointsByAreaName(Map<String, Object> parameters);
 
-    List<MonitorPoint> selectWithStateByMap(Map<String, Object> params);
+    List<MonitorPoint> selectByMap(Map<String, Object> params);
 }
\ No newline at end of file
diff --git a/src/main/java/com/moral/mapper/type/AdjustValueTypeHandle.java b/src/main/java/com/moral/mapper/type/AdjustValueTypeHandle.java
index 223d3a2..d853e1c 100644
--- a/src/main/java/com/moral/mapper/type/AdjustValueTypeHandle.java
+++ b/src/main/java/com/moral/mapper/type/AdjustValueTypeHandle.java
@@ -2,6 +2,7 @@
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.TypeReference;
+import com.alibaba.fastjson.serializer.SerializerFeature;
 import com.moral.common.json.BooleanValueFilter;
 import org.apache.ibatis.type.BaseTypeHandler;
 import org.apache.ibatis.type.JdbcType;
diff --git a/src/main/java/com/moral/security/AuthorizationServerConfiguration.java b/src/main/java/com/moral/security/AuthorizationServerConfiguration.java
deleted file mode 100644
index c0b338f..0000000
--- a/src/main/java/com/moral/security/AuthorizationServerConfiguration.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package com.moral.security;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.core.userdetails.UserDetailsService;
-import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
-import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
-import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
-import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
-import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
-import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;
-import org.springframework.security.oauth2.provider.token.TokenStore;
-
-@Configuration
-@EnableAuthorizationServer
-public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
-
-	private static String REALM = "MY_OAUTH_REALM";
-	
-	@Autowired
-    private UserDetailsService userDetailsService;
-	
-	@Autowired
-	private TokenStore tokenStore;
-
-	@Autowired
-	private UserApprovalHandler userApprovalHandler;
-
-	@Autowired
-	@Qualifier("authenticationManagerBean")
-	private AuthenticationManager authenticationManager;
-
-	@Override
-	public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
-
-		clients.inMemory()
-	        .withClient("my-trusted-client")//���������ID
-            .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
-            .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
-            .scopes("read", "write", "trust")//���������������������������
-            .secret("secret")//������
-            .accessTokenValiditySeconds(1200).//token������������1200���
-            refreshTokenValiditySeconds(6000);//������token������������6000���
-	}
-
-	@Override
-	public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
-		endpoints.tokenStore(tokenStore)
-		.userApprovalHandler(userApprovalHandler)
-		.authenticationManager(authenticationManager)
-		.userDetailsService(userDetailsService);
-	}
-
-	@Override
-	public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
-		oauthServer.realm(REALM + "/client");
-	}
-}
\ No newline at end of file
diff --git a/src/main/java/com/moral/security/CustomCorsFilter.java b/src/main/java/com/moral/security/CustomCorsFilter.java
new file mode 100644
index 0000000..1de04cb
--- /dev/null
+++ b/src/main/java/com/moral/security/CustomCorsFilter.java
@@ -0,0 +1,33 @@
+package com.moral.security;
+
+import java.util.Arrays;
+
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+
+/**
+ * CustomCorsFilter
+ * 
+ * @author vladimir.stankovic
+ *
+ * Aug 3, 2016
+ */
+public class CustomCorsFilter extends CorsFilter {
+
+    public CustomCorsFilter() {
+        super(configurationSource());
+    }
+
+    private static UrlBasedCorsConfigurationSource configurationSource() {
+        CorsConfiguration config = new CorsConfiguration();
+        config.setAllowCredentials(true);
+        config.addAllowedOrigin("*");
+        config.addAllowedHeader("*");
+        config.setMaxAge(36000L);
+        config.setAllowedMethods(Arrays.asList("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS"));
+        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+        source.registerCorsConfiguration("/**", config);
+        return source;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/moral/security/ResourceServerConfiguration.java b/src/main/java/com/moral/security/ResourceServerConfiguration.java
deleted file mode 100644
index edde722..0000000
--- a/src/main/java/com/moral/security/ResourceServerConfiguration.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.moral.security;
-
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
-import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
-import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
-import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler;
-
-@Configuration
-@EnableResourceServer
-public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
-
-	private static final String RESOURCE_ID = "my_rest_api";
-	
-	@Override
-	public void configure(ResourceServerSecurityConfigurer resources) {
-		resources.resourceId(RESOURCE_ID).stateless(false);
-	}
-
-	@Override
-	public void configure(HttpSecurity http) throws Exception {
-		http.anonymous().disable();
-		http.requestMatchers()
-			.antMatchers("/test/**")
-			.and()
-				.authorizeRequests()
-				.antMatchers("/test/**").permitAll()
-				.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
-
-		/*http.requestMatchers()
-		.antMatchers("/screen/**")
-		.and()
-		.authorizeRequests()
-		.antMatchers("/screen/**").permitAll()
-		.and()
-		.exceptionHandling()
-		.accessDeniedHandler(new OAuth2AccessDeniedHandler());*/
-
-		/*http.requestMatchers()
-		.antMatchers("/mobile/**")
-		.and()
-		.authorizeRequests()
-		.antMatchers("/mobile/**").permitAll()
-		.and()
-		.exceptionHandling()
-		.accessDeniedHandler(new OAuth2AccessDeniedHandler());*/
-	}
-}
\ No newline at end of file
diff --git a/src/main/java/com/moral/security/RestAuthenticationEntryPoint.java b/src/main/java/com/moral/security/RestAuthenticationEntryPoint.java
new file mode 100644
index 0000000..b9ceb05
--- /dev/null
+++ b/src/main/java/com/moral/security/RestAuthenticationEntryPoint.java
@@ -0,0 +1,26 @@
+package com.moral.security;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.AuthenticationEntryPoint;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * 
+ * @author vladimir.stankovic
+ *
+ * Aug 4, 2016
+ */
+@Component
+public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
+	@Override
+	public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException ex)
+			throws IOException, ServletException {
+		response.sendError(HttpStatus.UNAUTHORIZED.value(), "Unauthorized");
+	}
+}
diff --git a/src/main/java/com/moral/security/WebMvcConfiguration.java b/src/main/java/com/moral/security/WebMvcConfiguration.java
deleted file mode 100644
index c81dd9f..0000000
--- a/src/main/java/com/moral/security/WebMvcConfiguration.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.moral.security;
-
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.servlet.config.annotation.CorsRegistry;
-import org.springframework.web.servlet.config.annotation.EnableWebMvc;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
-
-@Configuration
-@EnableWebMvc
-public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
-
-    @Override
-    public void addCorsMappings(CorsRegistry registry) {
-        registry.addMapping("/**").allowedOrigins("*")
-                .allowedMethods("GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS")
-                .allowCredentials(false).maxAge(3600);
-
-//        registry.addMapping("/api/**")
-//                .allowedOrigins("http://192.168.1.97")
-//                .allowedMethods("GET", "POST")
-//                .allowCredentials(false).maxAge(3600);
-    }
-}
diff --git a/src/main/java/com/moral/security/WebSecurityConfiguration.java b/src/main/java/com/moral/security/WebSecurityConfiguration.java
deleted file mode 100644
index d54621f..0000000
--- a/src/main/java/com/moral/security/WebSecurityConfiguration.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package com.moral.security;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.security.SecurityProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.annotation.Order;
-import org.springframework.data.redis.connection.RedisConnectionFactory;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
-import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
-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.core.userdetails.UserDetailsService;
-import org.springframework.security.crypto.password.NoOpPasswordEncoder;
-import org.springframework.security.oauth2.provider.ClientDetailsService;
-import org.springframework.security.oauth2.provider.approval.ApprovalStore;
-import org.springframework.security.oauth2.provider.approval.TokenApprovalStore;
-import org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler;
-import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
-import org.springframework.security.oauth2.provider.token.TokenStore;
-import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
-import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
-
-@Configuration
-@EnableWebSecurity
-@EnableGlobalMethodSecurity(prePostEnabled = true)
-@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
-public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
-
-	@Autowired
-	private ClientDetailsService clientDetailsService;
-
-	@Autowired
-	private RedisConnectionFactory redisConnection;
-
-	@Autowired
-	private UserDetailsService userDetailsService;
-
-	@Override
-	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
-		auth.inMemoryAuthentication()
-				.withUser("bill").password("abc123").roles("ADMIN").and()
-				.withUser("bob").password("abc123").roles("USER");
-
-		auth.userDetailsService(userDetailsService).passwordEncoder(NoOpPasswordEncoder.getInstance());
-	}
-
-    @Override
-    protected void configure(HttpSecurity http) throws Exception {
-		http.csrf().disable(); //TODO ������������CSRF
-		http.anonymous().disable()
-	  	    .authorizeRequests()
-	  	    .antMatchers("/oauth/token").permitAll();
-    }
-
-    @Override
-    @Bean
-    public AuthenticationManager authenticationManagerBean() throws Exception {
-        return super.authenticationManagerBean();
-    }
-
-
-	@Bean
-	public TokenStore tokenStore() {
-		return new InMemoryTokenStore();
-		//return new RedisTokenStore(redisConnection);
-	}
-
-	@Bean
-	@Autowired
-	public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore){
-		TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
-		handler.setTokenStore(tokenStore);
-		handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
-		handler.setClientDetailsService(clientDetailsService);
-		return handler;
-	}
-	
-	@Bean
-	@Autowired
-	public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception {
-		TokenApprovalStore store = new TokenApprovalStore();
-		store.setTokenStore(tokenStore);
-		return store;
-	}
-}
diff --git a/src/main/java/com/moral/security/auth/JwtAuthenticationToken.java b/src/main/java/com/moral/security/auth/JwtAuthenticationToken.java
new file mode 100644
index 0000000..989f525
--- /dev/null
+++ b/src/main/java/com/moral/security/auth/JwtAuthenticationToken.java
@@ -0,0 +1,61 @@
+package com.moral.security.auth;
+
+import com.moral.security.model.UserContext;
+import com.moral.security.model.token.RawAccessJwtToken;
+import org.springframework.security.authentication.AbstractAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+
+import java.util.Collection;
+
+/**
+ * An {@link org.springframework.security.core.Authentication} implementation
+ * that is designed for simple presentation of JwtToken.
+ * 
+ * @author vladimir.stankovic
+ *
+ *         May 23, 2016
+ */
+public class JwtAuthenticationToken extends AbstractAuthenticationToken {
+    private static final long serialVersionUID = 2877954820905567501L;
+
+    private RawAccessJwtToken rawAccessToken;
+    private UserContext userContext;
+
+    public JwtAuthenticationToken(RawAccessJwtToken unsafeToken) {
+        super(null);
+        this.rawAccessToken = unsafeToken;
+        this.setAuthenticated(false);
+    }
+
+    public JwtAuthenticationToken(UserContext userContext, Collection<? extends GrantedAuthority> authorities) {
+        super(authorities);
+        this.eraseCredentials();
+        this.userContext = userContext;
+        super.setAuthenticated(true);
+    }
+
+    @Override
+    public void setAuthenticated(boolean authenticated) {
+        if (authenticated) {
+            throw new IllegalArgumentException(
+                    "Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");
+        }
+        super.setAuthenticated(false);
+    }
+
+    @Override
+    public Object getCredentials() {
+        return rawAccessToken;
+    }
+
+    @Override
+    public UserContext getPrincipal() {
+        return this.userContext;
+    }
+
+    @Override
+    public void eraseCredentials() {        
+        super.eraseCredentials();
+        this.rawAccessToken = null;
+    }
+}
diff --git a/src/main/java/com/moral/security/auth/jwt/JwtAuthenticationProvider.java b/src/main/java/com/moral/security/auth/jwt/JwtAuthenticationProvider.java
new file mode 100644
index 0000000..3afe42a
--- /dev/null
+++ b/src/main/java/com/moral/security/auth/jwt/JwtAuthenticationProvider.java
@@ -0,0 +1,68 @@
+package com.moral.security.auth.jwt;
+
+import com.moral.security.auth.JwtAuthenticationToken;
+import com.moral.security.auth.login.LoginMode;
+import com.moral.security.config.JwtSettings;
+import com.moral.security.model.UserContext;
+import com.moral.security.model.token.JwtToken;
+import com.moral.security.model.token.RawAccessJwtToken;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jws;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * An {@link AuthenticationProvider} implementation that will use provided
+ * instance of {@link JwtToken} to perform authentication.
+ * 
+ * @author vladimir.stankovic
+ *
+ * Aug 5, 2016
+ */
+@Component
+@SuppressWarnings("unchecked")
+public class JwtAuthenticationProvider implements AuthenticationProvider {
+    private final JwtSettings jwtSettings;
+    
+    @Autowired
+    public JwtAuthenticationProvider(JwtSettings jwtSettings) {
+        this.jwtSettings = jwtSettings;
+    }
+
+    /**
+     * ���������������������������������������������������������
+     * @param authentication
+     * @return
+     * @throws AuthenticationException
+     */
+    @Override
+    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
+        RawAccessJwtToken rawAccessToken = (RawAccessJwtToken) authentication.getCredentials();
+
+        Jws<Claims> jwsClaims = rawAccessToken.parseClaims(jwtSettings.getTokenSigningKey());
+        String subject = jwsClaims.getBody().getSubject();
+        Integer orgId =  Integer.valueOf(jwsClaims.getBody().get("oid").toString());
+        LoginMode mode = LoginMode.valueOf(jwsClaims.getBody().get("mode").toString());
+        List<String> scopes = jwsClaims.getBody().get("scopes", List.class);
+        List<GrantedAuthority> authorities = scopes.stream()
+            .map(SimpleGrantedAuthority::new)
+            .collect(Collectors.toList());
+        
+        UserContext context = UserContext.create(subject,mode,orgId,authorities);
+        
+        return new JwtAuthenticationToken(context, context.getAuthorities());
+    }
+
+    @Override
+    public boolean supports(Class<?> authentication) {
+        return (JwtAuthenticationToken.class.isAssignableFrom(authentication));
+    }
+}
diff --git a/src/main/java/com/moral/security/auth/jwt/JwtTokenAuthenticationProcessingFilter.java b/src/main/java/com/moral/security/auth/jwt/JwtTokenAuthenticationProcessingFilter.java
new file mode 100644
index 0000000..4fb6f49
--- /dev/null
+++ b/src/main/java/com/moral/security/auth/jwt/JwtTokenAuthenticationProcessingFilter.java
@@ -0,0 +1,64 @@
+package com.moral.security.auth.jwt;
+
+import com.moral.security.auth.JwtAuthenticationToken;
+import com.moral.security.auth.jwt.extractor.TokenExtractor;
+import com.moral.security.config.WebSecurityConfig;
+import com.moral.security.model.token.RawAccessJwtToken;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
+import org.springframework.security.web.authentication.AuthenticationFailureHandler;
+import org.springframework.security.web.util.matcher.RequestMatcher;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * Performs validation of provided JWT Token.
+ * 
+ * @author vladimir.stankovic
+ *
+ * Aug 5, 2016
+ */
+public class JwtTokenAuthenticationProcessingFilter extends AbstractAuthenticationProcessingFilter {
+    private final AuthenticationFailureHandler failureHandler;
+    private final TokenExtractor tokenExtractor;
+    
+    @Autowired
+    public JwtTokenAuthenticationProcessingFilter(AuthenticationFailureHandler failureHandler,
+            TokenExtractor tokenExtractor, RequestMatcher matcher) {
+        super(matcher);
+        this.failureHandler = failureHandler;
+        this.tokenExtractor = tokenExtractor;
+    }
+
+    @Override
+    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
+            throws AuthenticationException, IOException, ServletException {
+        String tokenPayload = request.getHeader(WebSecurityConfig.AUTHENTICATION_HEADER_NAME);
+        RawAccessJwtToken token = new RawAccessJwtToken(tokenExtractor.extract(tokenPayload));
+        return getAuthenticationManager().authenticate(new JwtAuthenticationToken(token));
+    }
+
+    @Override
+    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
+                                            Authentication authResult) throws IOException, ServletException {
+        SecurityContext context = SecurityContextHolder.createEmptyContext();
+        context.setAuthentication(authResult);
+        SecurityContextHolder.setContext(context);
+        chain.doFilter(request, response);
+    }
+
+    @Override
+    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
+                                              AuthenticationException failed) throws IOException, ServletException {
+        SecurityContextHolder.clearContext();
+        failureHandler.onAuthenticationFailure(request, response, failed);
+    }
+}
diff --git a/src/main/java/com/moral/security/auth/jwt/SkipPathRequestMatcher.java b/src/main/java/com/moral/security/auth/jwt/SkipPathRequestMatcher.java
new file mode 100644
index 0000000..7c747d8
--- /dev/null
+++ b/src/main/java/com/moral/security/auth/jwt/SkipPathRequestMatcher.java
@@ -0,0 +1,37 @@
+package com.moral.security.auth.jwt;
+
+import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.security.web.util.matcher.OrRequestMatcher;
+import org.springframework.security.web.util.matcher.RequestMatcher;
+import org.springframework.util.Assert;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * SkipPathRequestMatcher
+ * 
+ * @author vladimir.stankovic
+ *
+ * Aug 19, 2016
+ */
+public class SkipPathRequestMatcher implements RequestMatcher {
+    private OrRequestMatcher matchers;
+    private RequestMatcher processingMatcher;
+    
+    public SkipPathRequestMatcher(List<String> pathsToSkip, String processingPath) {
+        Assert.notNull(pathsToSkip);
+        List<RequestMatcher> m = pathsToSkip.stream().map(path -> new AntPathRequestMatcher(path)).collect(Collectors.toList());
+        matchers = new OrRequestMatcher(m);
+        processingMatcher = new AntPathRequestMatcher(processingPath);
+    }
+
+    @Override
+    public boolean matches(HttpServletRequest request) {
+        if (matchers.matches(request)) {
+            return false;
+        }
+        return processingMatcher.matches(request) ? true : false;
+    }
+}
diff --git a/src/main/java/com/moral/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java b/src/main/java/com/moral/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java
new file mode 100644
index 0000000..bf2fc27
--- /dev/null
+++ b/src/main/java/com/moral/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java
@@ -0,0 +1,31 @@
+package com.moral.security.auth.jwt.extractor;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.security.authentication.AuthenticationServiceException;
+import org.springframework.stereotype.Component;
+
+/**
+ * An implementation of {@link TokenExtractor} extracts token from
+ * Authorization: Bearer scheme.
+ * 
+ * @author vladimir.stankovic
+ *
+ * Aug 5, 2016
+ */
+@Component
+public class JwtHeaderTokenExtractor implements TokenExtractor {
+    public static String HEADER_PREFIX = "Bearer ";
+
+    @Override
+    public String extract(String header) {
+        if (StringUtils.isBlank(header)) {
+            throw new AuthenticationServiceException("Authorization header cannot be blank!");
+        }
+
+        if (header.length() < HEADER_PREFIX.length()) {
+            throw new AuthenticationServiceException("Invalid authorization header size.");
+        }
+
+        return header.substring(HEADER_PREFIX.length(), header.length());
+    }
+}
diff --git a/src/main/java/com/moral/security/auth/jwt/extractor/TokenExtractor.java b/src/main/java/com/moral/security/auth/jwt/extractor/TokenExtractor.java
new file mode 100644
index 0000000..79cf7d4
--- /dev/null
+++ b/src/main/java/com/moral/security/auth/jwt/extractor/TokenExtractor.java
@@ -0,0 +1,13 @@
+package com.moral.security.auth.jwt.extractor;
+
+/**
+ * Implementations of this interface should always return raw base-64 encoded
+ * representation of JWT Token.
+ * 
+ * @author vladimir.stankovic
+ *
+ * Aug 5, 2016
+ */
+public interface TokenExtractor {
+    public String extract(String payload);
+}
diff --git a/src/main/java/com/moral/security/auth/jwt/verifier/BloomFilterTokenVerifier.java b/src/main/java/com/moral/security/auth/jwt/verifier/BloomFilterTokenVerifier.java
new file mode 100644
index 0000000..d2ed3c2
--- /dev/null
+++ b/src/main/java/com/moral/security/auth/jwt/verifier/BloomFilterTokenVerifier.java
@@ -0,0 +1,18 @@
+package com.moral.security.auth.jwt.verifier;
+
+import org.springframework.stereotype.Component;
+
+/**
+ * BloomFilterTokenVerifier
+ * 
+ * @author vladimir.stankovic
+ *
+ * Aug 17, 2016
+ */
+@Component
+public class BloomFilterTokenVerifier implements TokenVerifier {
+    @Override
+    public boolean verify(String jti) {
+        return true;
+    }
+}
diff --git a/src/main/java/com/moral/security/auth/jwt/verifier/TokenVerifier.java b/src/main/java/com/moral/security/auth/jwt/verifier/TokenVerifier.java
new file mode 100644
index 0000000..0e6d014
--- /dev/null
+++ b/src/main/java/com/moral/security/auth/jwt/verifier/TokenVerifier.java
@@ -0,0 +1,11 @@
+package com.moral.security.auth.jwt.verifier;
+
+/**
+ * 
+ * @author vladimir.stankovic
+ *
+ * Aug 17, 2016
+ */
+public interface TokenVerifier {
+    public boolean verify(String jti);
+}
diff --git a/src/main/java/com/moral/security/auth/login/LoginAuthenticationProvider.java b/src/main/java/com/moral/security/auth/login/LoginAuthenticationProvider.java
new file mode 100644
index 0000000..307d880
--- /dev/null
+++ b/src/main/java/com/moral/security/auth/login/LoginAuthenticationProvider.java
@@ -0,0 +1,74 @@
+package com.moral.security.auth.login;
+
+import com.moral.entity.Account;
+import com.moral.security.model.UserContext;
+import com.moral.service.AccountService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.InsufficientAuthenticationException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.stereotype.Component;
+import org.springframework.util.Assert;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author vladimir.stankovic
+ * <p>
+ * Aug 3, 2016
+ */
+@Component
+public class LoginAuthenticationProvider implements AuthenticationProvider {
+    private final BCryptPasswordEncoder encoder;
+    private final AccountService accountService;
+
+    @Autowired
+    public LoginAuthenticationProvider(final AccountService accountService, final BCryptPasswordEncoder encoder) {
+        this.accountService = accountService;
+        this.encoder = encoder;
+    }
+
+    /**
+     * ������������������������
+     *
+     * @param authentication
+     * @return
+     * @throws AuthenticationException
+     */
+    @Override
+    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
+        Assert.notNull(authentication, "No authentication data provided");
+
+        String accountName = (String) authentication.getPrincipal();
+        String password = (String) authentication.getCredentials();
+        LoginMode mode = (LoginMode) authentication.getDetails();
+        Account account = accountService.queryAccountByName(accountName).orElseThrow(() -> new UsernameNotFoundException("User not found: " + accountName));
+        if (!encoder.matches(password, account.getPassword())) {
+            throw new BadCredentialsException("Authentication Failed. Username or Password not valid.");
+        }
+
+        if (account.getRoles() == null) {
+            throw new InsufficientAuthenticationException("User has no roles assigned");
+        }
+        List<GrantedAuthority> authorities = account.getRoles().stream()
+                .map(authority -> new SimpleGrantedAuthority(authority.getName()))
+                .collect(Collectors.toList());
+
+        UserContext userContext = UserContext.create(account.getAccountName(),mode,account.getOrganizationId(),authorities);
+
+        return new UsernamePasswordAuthenticationToken(userContext, null, userContext.getAuthorities());
+    }
+
+    @Override
+    public boolean supports(Class<?> authentication) {
+        return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
+    }
+}
diff --git a/src/main/java/com/moral/security/auth/login/LoginAwareAuthenticationFailureHandler.java b/src/main/java/com/moral/security/auth/login/LoginAwareAuthenticationFailureHandler.java
new file mode 100644
index 0000000..60c94ae
--- /dev/null
+++ b/src/main/java/com/moral/security/auth/login/LoginAwareAuthenticationFailureHandler.java
@@ -0,0 +1,53 @@
+package com.moral.security.auth.login;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.moral.security.common.ErrorCode;
+import com.moral.security.common.ErrorResponse;
+import com.moral.security.exceptions.AuthMethodNotSupportedException;
+import com.moral.security.exceptions.JwtExpiredTokenException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.authentication.AuthenticationFailureHandler;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * 
+ * @author vladimir.stankovic
+ *
+ * Aug 3, 2016
+ */
+@Component
+public class LoginAwareAuthenticationFailureHandler implements AuthenticationFailureHandler {
+    private final ObjectMapper mapper;
+    
+    @Autowired
+    public LoginAwareAuthenticationFailureHandler(ObjectMapper mapper) {
+        this.mapper = mapper;
+    }	
+    
+	@Override
+	public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
+                                        AuthenticationException e) throws IOException, ServletException {
+		
+		response.setStatus(HttpStatus.UNAUTHORIZED.value());
+		response.setContentType(MediaType.APPLICATION_JSON_VALUE);
+		
+		if (e instanceof BadCredentialsException) {
+			mapper.writeValue(response.getWriter(), ErrorResponse.of("Invalid username or password", ErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED));
+		} else if (e instanceof JwtExpiredTokenException) {
+			mapper.writeValue(response.getWriter(), ErrorResponse.of("Token has expired", ErrorCode.JWT_TOKEN_EXPIRED, HttpStatus.UNAUTHORIZED));
+		} else if (e instanceof AuthMethodNotSupportedException) {
+		    mapper.writeValue(response.getWriter(), ErrorResponse.of(e.getMessage(), ErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED));
+		}
+
+		mapper.writeValue(response.getWriter(), ErrorResponse.of("Authentication failed", ErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED));
+	}
+}
diff --git a/src/main/java/com/moral/security/auth/login/LoginAwareAuthenticationSuccessHandler.java b/src/main/java/com/moral/security/auth/login/LoginAwareAuthenticationSuccessHandler.java
new file mode 100644
index 0000000..02c6d29
--- /dev/null
+++ b/src/main/java/com/moral/security/auth/login/LoginAwareAuthenticationSuccessHandler.java
@@ -0,0 +1,74 @@
+package com.moral.security.auth.login;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.moral.security.model.UserContext;
+import com.moral.security.model.token.JwtToken;
+import com.moral.security.model.token.JwtTokenFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.web.WebAttributes;
+import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * AjaxAwareAuthenticationSuccessHandler
+ * 
+ * @author vladimir.stankovic
+ *
+ *         Aug 3, 2016
+ */
+@Component
+public class LoginAwareAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
+    private final ObjectMapper mapper;
+    private final JwtTokenFactory tokenFactory;
+
+    @Autowired
+    public LoginAwareAuthenticationSuccessHandler(final ObjectMapper mapper, final JwtTokenFactory tokenFactory) {
+        this.mapper = mapper;
+        this.tokenFactory = tokenFactory;
+    }
+
+    @Override
+    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
+                                        Authentication authentication) throws IOException, ServletException {
+        UserContext userContext = (UserContext) authentication.getPrincipal();
+        
+        JwtToken accessToken = tokenFactory.createAccessJwtToken(userContext);
+        JwtToken refreshToken = tokenFactory.createRefreshToken(userContext);
+        
+        Map<String, String> tokenMap = new HashMap<String, String>();
+        tokenMap.put("token", accessToken.getToken());
+        tokenMap.put("refreshToken", refreshToken.getToken());
+
+        response.setStatus(HttpStatus.OK.value());
+        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
+        mapper.writeValue(response.getWriter(), tokenMap);
+
+        clearAuthenticationAttributes(request);
+    }
+
+    /**
+     * Removes temporary authentication-related data which may have been stored
+     * in the session during the authentication process..
+     * 
+     */
+    protected final void clearAuthenticationAttributes(HttpServletRequest request) {
+        HttpSession session = request.getSession(false);
+
+        if (session == null) {
+            return;
+        }
+
+        session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
+    }
+}
diff --git a/src/main/java/com/moral/security/auth/login/LoginMode.java b/src/main/java/com/moral/security/auth/login/LoginMode.java
new file mode 100644
index 0000000..4681349
--- /dev/null
+++ b/src/main/java/com/moral/security/auth/login/LoginMode.java
@@ -0,0 +1,5 @@
+package com.moral.security.auth.login;
+
+public enum LoginMode {
+    Web,Screen,Andriod,Apple
+}
diff --git a/src/main/java/com/moral/security/auth/login/LoginProcessingFilter.java b/src/main/java/com/moral/security/auth/login/LoginProcessingFilter.java
new file mode 100644
index 0000000..6f411ea
--- /dev/null
+++ b/src/main/java/com/moral/security/auth/login/LoginProcessingFilter.java
@@ -0,0 +1,84 @@
+package com.moral.security.auth.login;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.moral.security.common.WebUtil;
+import com.moral.security.exceptions.AuthMethodNotSupportedException;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpMethod;
+import org.springframework.security.authentication.AuthenticationServiceException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
+import org.springframework.security.web.authentication.AuthenticationFailureHandler;
+import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * AjaxLoginProcessingFilter
+ * 
+ * @author vladimir.stankovic
+ *
+ * Aug 3, 2016
+ */
+public class LoginProcessingFilter extends AbstractAuthenticationProcessingFilter {
+    private static Logger logger = LoggerFactory.getLogger(LoginProcessingFilter.class);
+
+    private final AuthenticationSuccessHandler successHandler;
+    private final AuthenticationFailureHandler failureHandler;
+
+    private final ObjectMapper objectMapper;
+    
+    public LoginProcessingFilter(String defaultProcessUrl, AuthenticationSuccessHandler successHandler,
+                                     AuthenticationFailureHandler failureHandler, ObjectMapper mapper) {
+        super(defaultProcessUrl);
+        this.successHandler = successHandler;
+        this.failureHandler = failureHandler;
+        this.objectMapper = mapper;
+    }
+
+    @Override
+    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
+            throws AuthenticationException, IOException, ServletException {
+        if (!HttpMethod.POST.name().equals(request.getMethod())) {
+            if(logger.isDebugEnabled()) {
+                logger.debug("Authentication method not supported. Request method: " + request.getMethod());
+            }
+            throw new AuthMethodNotSupportedException("Authentication method not supported");
+        }
+
+        LoginRequest loginRequest = objectMapper.readValue(request.getReader(), LoginRequest.class);
+        
+        if (StringUtils.isBlank(loginRequest.getUsername())
+                || StringUtils.isBlank(loginRequest.getPassword())
+                || loginRequest.getMode() == null) {
+            throw new AuthenticationServiceException("Username or Password not provided");
+        }
+
+        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword());
+        // ������������������������������������������������
+        token.setDetails(loginRequest.getMode());
+        return this.getAuthenticationManager().authenticate(token);
+    }
+
+    @Override
+    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
+                                            Authentication authResult) throws IOException, ServletException {
+        successHandler.onAuthenticationSuccess(request, response, authResult);
+    }
+
+    @Override
+    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
+                                              AuthenticationException failed) throws IOException, ServletException {
+        SecurityContextHolder.clearContext();
+        failureHandler.onAuthenticationFailure(request, response, failed);
+    }
+}
diff --git a/src/main/java/com/moral/security/auth/login/LoginRequest.java b/src/main/java/com/moral/security/auth/login/LoginRequest.java
new file mode 100644
index 0000000..be34bf8
--- /dev/null
+++ b/src/main/java/com/moral/security/auth/login/LoginRequest.java
@@ -0,0 +1,40 @@
+package com.moral.security.auth.login;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Model intended to be used for AJAX based authentication.
+ * 
+ * @author vladimir.stankovic
+ *
+ * Aug 3, 2016
+ */
+
+public class LoginRequest {
+    private String username;
+    private String password;
+
+    public LoginMode getMode() {
+        return mode;
+    }
+
+    private LoginMode mode;
+
+    @JsonCreator
+    public LoginRequest(@JsonProperty("username") String username,
+                        @JsonProperty("password") String password,
+                        @JsonProperty("mode") LoginMode mode) {
+        this.username = username;
+        this.password = password;
+        this.mode = mode;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+}
diff --git a/src/main/java/com/moral/security/common/ErrorCode.java b/src/main/java/com/moral/security/common/ErrorCode.java
new file mode 100644
index 0000000..db6750d
--- /dev/null
+++ b/src/main/java/com/moral/security/common/ErrorCode.java
@@ -0,0 +1,27 @@
+package com.moral.security.common;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+
+/**
+ * Enumeration of REST Error types.
+ * 
+ * @author vladimir.stankovic
+ *
+ *         Aug 3, 2016
+ */
+public enum ErrorCode {
+    GLOBAL(2),
+
+    AUTHENTICATION(10), JWT_TOKEN_EXPIRED(11);
+    
+    private int errorCode;
+
+    private ErrorCode(int errorCode) {
+        this.errorCode = errorCode;
+    }
+
+    @JsonValue
+    public int getErrorCode() {
+        return errorCode;
+    }
+}
diff --git a/src/main/java/com/moral/security/common/ErrorResponse.java b/src/main/java/com/moral/security/common/ErrorResponse.java
new file mode 100644
index 0000000..ec30c90
--- /dev/null
+++ b/src/main/java/com/moral/security/common/ErrorResponse.java
@@ -0,0 +1,52 @@
+package com.moral.security.common;
+
+import org.springframework.http.HttpStatus;
+
+import java.util.Date;
+
+/**
+ * Error model for interacting with client.
+ * 
+ * @author vladimir.stankovic
+ *
+ * Aug 3, 2016
+ */
+public class ErrorResponse {
+    // HTTP Response Status Code
+    private final HttpStatus status;
+
+    // General Error message
+    private final String message;
+
+    // Error code
+    private final ErrorCode errorCode;
+
+    private final Date timestamp;
+
+    protected ErrorResponse(final String message, final ErrorCode errorCode, HttpStatus status) {
+        this.message = message;
+        this.errorCode = errorCode;
+        this.status = status;
+        this.timestamp = new Date();
+    }
+
+    public static ErrorResponse of(final String message, final ErrorCode errorCode, HttpStatus status) {
+        return new ErrorResponse(message, errorCode, status);
+    }
+
+    public Integer getStatus() {
+        return status.value();
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public ErrorCode getErrorCode() {
+        return errorCode;
+    }
+
+    public Date getTimestamp() {
+        return timestamp;
+    }
+}
diff --git a/src/main/java/com/moral/security/common/WebUtil.java b/src/main/java/com/moral/security/common/WebUtil.java
new file mode 100644
index 0000000..2a1e822
--- /dev/null
+++ b/src/main/java/com/moral/security/common/WebUtil.java
@@ -0,0 +1,31 @@
+package com.moral.security.common;
+
+import org.springframework.security.web.savedrequest.SavedRequest;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 
+ * @author vladimir.stankovic
+ *
+ * Aug 3, 2016
+ */
+public class WebUtil {
+    private static final String XML_HTTP_REQUEST = "XMLHttpRequest";
+    private static final String X_REQUESTED_WITH = "X-Requested-With";
+
+    private static final String CONTENT_TYPE = "Content-type";
+    private static final String CONTENT_TYPE_JSON = "application/json";
+
+    public static boolean isAjax(HttpServletRequest request) {
+        return XML_HTTP_REQUEST.equals(request.getHeader(X_REQUESTED_WITH));
+    }
+
+    public static boolean isAjax(SavedRequest request) {
+        return request.getHeaderValues(X_REQUESTED_WITH).contains(XML_HTTP_REQUEST);
+    }
+
+    public static boolean isContentTypeJson(SavedRequest request) {
+        return request.getHeaderValues(CONTENT_TYPE).contains(CONTENT_TYPE_JSON);
+    }
+}
diff --git a/src/main/java/com/moral/security/config/JwtSettings.java b/src/main/java/com/moral/security/config/JwtSettings.java
new file mode 100644
index 0000000..fc96aac
--- /dev/null
+++ b/src/main/java/com/moral/security/config/JwtSettings.java
@@ -0,0 +1,59 @@
+package com.moral.security.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ConfigurationProperties(prefix = "moral.security.jwt")
+public class JwtSettings {
+    /**
+     * {@link JwtToken} will expire after this time.
+     */
+    private Integer tokenExpirationTime;
+
+    /**
+     * Token issuer.
+     */
+    private String tokenIssuer;
+    
+    /**
+     * Key is used to sign {@link JwtToken}.
+     */
+    private String tokenSigningKey;
+    
+    /**
+     * {@link JwtToken} can be refreshed during this timeframe.
+     */
+    private Integer refreshTokenExpTime;
+    
+    public Integer getRefreshTokenExpTime() {
+        return refreshTokenExpTime;
+    }
+
+    public void setRefreshTokenExpTime(Integer refreshTokenExpTime) {
+        this.refreshTokenExpTime = refreshTokenExpTime;
+    }
+
+    public Integer getTokenExpirationTime() {
+        return tokenExpirationTime;
+    }
+    
+    public void setTokenExpirationTime(Integer tokenExpirationTime) {
+        this.tokenExpirationTime = tokenExpirationTime;
+    }
+    
+    public String getTokenIssuer() {
+        return tokenIssuer;
+    }
+    public void setTokenIssuer(String tokenIssuer) {
+        this.tokenIssuer = tokenIssuer;
+    }
+    
+    public String getTokenSigningKey() {
+        return tokenSigningKey;
+    }
+    
+    public void setTokenSigningKey(String tokenSigningKey) {
+        this.tokenSigningKey = tokenSigningKey;
+    }
+}
diff --git a/src/main/java/com/moral/security/config/PasswordEncoderConfig.java b/src/main/java/com/moral/security/config/PasswordEncoderConfig.java
new file mode 100644
index 0000000..12de433
--- /dev/null
+++ b/src/main/java/com/moral/security/config/PasswordEncoderConfig.java
@@ -0,0 +1,20 @@
+package com.moral.security.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+
+/**
+ * PasswordEncoderConfig
+ * 
+ * @author vladimir.stankovic
+ *
+ * Dec 27, 2016
+ */
+@Configuration
+public class PasswordEncoderConfig {
+    @Bean
+    protected BCryptPasswordEncoder passwordEncoder() {
+        return new BCryptPasswordEncoder();
+    }
+}
diff --git a/src/main/java/com/moral/security/config/WebSecurityConfig.java b/src/main/java/com/moral/security/config/WebSecurityConfig.java
new file mode 100644
index 0000000..d6b75e9
--- /dev/null
+++ b/src/main/java/com/moral/security/config/WebSecurityConfig.java
@@ -0,0 +1,118 @@
+package com.moral.security.config;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.moral.security.CustomCorsFilter;
+import com.moral.security.RestAuthenticationEntryPoint;
+import com.moral.security.auth.login.LoginAuthenticationProvider;
+import com.moral.security.auth.login.LoginProcessingFilter;
+import com.moral.security.auth.jwt.JwtAuthenticationProvider;
+import com.moral.security.auth.jwt.JwtTokenAuthenticationProcessingFilter;
+import com.moral.security.auth.jwt.SkipPathRequestMatcher;
+import com.moral.security.auth.jwt.extractor.TokenExtractor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+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.config.http.SessionCreationPolicy;
+import org.springframework.security.web.authentication.AuthenticationFailureHandler;
+import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * WebSecurityConfig
+ * 
+ * @author vladimir.stankovic
+ *
+ * Aug 3, 2016
+ */
+@Configuration
+@EnableWebSecurity
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+    public static final String AUTHENTICATION_HEADER_NAME = "X-Authorization";
+    public static final String AUTHENTICATION_URL = "/auth/login";
+    public static final String REFRESH_TOKEN_URL = "/auth/token";
+    public static final String API_ROOT_URL = "/*/**";
+
+    @Autowired
+    private RestAuthenticationEntryPoint authenticationEntryPoint;
+    @Autowired
+    private AuthenticationSuccessHandler successHandler;
+    @Autowired
+    private AuthenticationFailureHandler failureHandler;
+    @Autowired
+    private LoginAuthenticationProvider ajaxAuthenticationProvider;
+    @Autowired
+    private JwtAuthenticationProvider jwtAuthenticationProvider;
+
+    @Autowired
+    private TokenExtractor tokenExtractor;
+
+    @Autowired
+    private AuthenticationManager authenticationManager;
+
+    @Autowired
+    private ObjectMapper objectMapper;
+
+    protected LoginProcessingFilter buildLoginProcessingFilter(String loginEntryPoint) throws Exception {
+        LoginProcessingFilter filter = new LoginProcessingFilter(loginEntryPoint, successHandler, failureHandler, objectMapper);
+        filter.setAuthenticationManager(this.authenticationManager);
+        return filter;
+    }
+
+    protected JwtTokenAuthenticationProcessingFilter buildJwtTokenAuthenticationProcessingFilter(List<String> pathsToSkip, String pattern) throws Exception {
+        SkipPathRequestMatcher matcher = new SkipPathRequestMatcher(pathsToSkip, pattern);
+        JwtTokenAuthenticationProcessingFilter filter
+            = new JwtTokenAuthenticationProcessingFilter(failureHandler, tokenExtractor, matcher);
+        filter.setAuthenticationManager(this.authenticationManager);
+        return filter;
+    }
+
+    @Bean
+    @Override
+    public AuthenticationManager authenticationManagerBean() throws Exception {
+        return super.authenticationManagerBean();
+    }
+
+    @Override
+    protected void configure(AuthenticationManagerBuilder auth) {
+        auth.authenticationProvider(ajaxAuthenticationProvider);
+        auth.authenticationProvider(jwtAuthenticationProvider);
+    }
+    
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        List<String> permitAllEndpointList = Arrays.asList(
+            AUTHENTICATION_URL,
+            REFRESH_TOKEN_URL
+        );
+
+        http
+            .csrf().disable() // We don't need CSRF for JWT based authentication
+            .exceptionHandling()
+            .authenticationEntryPoint(this.authenticationEntryPoint)
+
+            .and()
+                .sessionManagement()
+                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
+
+            .and()
+                .authorizeRequests()
+                .antMatchers(permitAllEndpointList.toArray(new String[permitAllEndpointList.size()]))
+                .permitAll()
+            .and()
+                .authorizeRequests()
+                .antMatchers(API_ROOT_URL).authenticated() // Protected API End-points
+            .and()
+                .addFilterBefore(new CustomCorsFilter(), UsernamePasswordAuthenticationFilter.class)
+                .addFilterBefore(buildLoginProcessingFilter(AUTHENTICATION_URL), UsernamePasswordAuthenticationFilter.class)
+                .addFilterBefore(buildJwtTokenAuthenticationProcessingFilter(permitAllEndpointList,
+                API_ROOT_URL), UsernamePasswordAuthenticationFilter.class);
+    }
+}
diff --git a/src/main/java/com/moral/security/endpoint/ProfileEndpoint.java b/src/main/java/com/moral/security/endpoint/ProfileEndpoint.java
new file mode 100644
index 0000000..9349580
--- /dev/null
+++ b/src/main/java/com/moral/security/endpoint/ProfileEndpoint.java
@@ -0,0 +1,24 @@
+package com.moral.security.endpoint;
+
+import com.moral.security.auth.JwtAuthenticationToken;
+import com.moral.security.model.UserContext;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * End-point for retrieving logged-in user details.
+ * 
+ * @author vladimir.stankovic
+ *
+ * Aug 4, 2016
+ */
+@RestController
+public class ProfileEndpoint {
+    @RequestMapping(value="/user-context", method=RequestMethod.GET)
+    public @ResponseBody
+    UserContext get(JwtAuthenticationToken token) {
+        return  token.getPrincipal();
+    }
+}
diff --git a/src/main/java/com/moral/security/endpoint/RefreshTokenEndpoint.java b/src/main/java/com/moral/security/endpoint/RefreshTokenEndpoint.java
new file mode 100644
index 0000000..f965e0f
--- /dev/null
+++ b/src/main/java/com/moral/security/endpoint/RefreshTokenEndpoint.java
@@ -0,0 +1,82 @@
+package com.moral.security.endpoint;
+
+import com.moral.entity.Account;
+import com.moral.security.auth.JwtAuthenticationToken;
+import com.moral.security.auth.login.LoginMode;
+import com.moral.security.model.token.JwtTokenFactory;
+import com.moral.security.auth.jwt.extractor.TokenExtractor;
+import com.moral.security.auth.jwt.verifier.TokenVerifier;
+import com.moral.security.config.JwtSettings;
+import com.moral.security.config.WebSecurityConfig;
+import com.moral.security.exceptions.InvalidJwtToken;
+import com.moral.security.model.UserContext;
+import com.moral.security.model.token.JwtToken;
+import com.moral.security.model.token.RawAccessJwtToken;
+import com.moral.security.model.token.RefreshToken;
+import com.moral.service.AccountService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.http.MediaType;
+import org.springframework.security.authentication.InsufficientAuthenticationException;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * RefreshTokenEndpoint
+ * 
+ * @author vladimir.stankovic
+ *
+ * Aug 17, 2016
+ */
+@RestController
+public class RefreshTokenEndpoint {
+    @Autowired
+    private JwtTokenFactory tokenFactory;
+    @Autowired
+    private JwtSettings jwtSettings;
+    @Autowired
+    private AccountService accountService;
+    @Autowired
+    private TokenVerifier tokenVerifier;
+    @Autowired
+    @Qualifier("jwtHeaderTokenExtractor") private TokenExtractor tokenExtractor;
+    
+    @RequestMapping(value="/auth/token", method= RequestMethod.GET, produces={ MediaType.APPLICATION_JSON_VALUE })
+    public @ResponseBody
+    JwtToken refreshToken(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
+        String tokenPayload = tokenExtractor.extract(request.getHeader(WebSecurityConfig.AUTHENTICATION_HEADER_NAME));
+        
+        RawAccessJwtToken rawToken = new RawAccessJwtToken(tokenPayload);
+        RefreshToken refreshToken = RefreshToken.create(rawToken, jwtSettings.getTokenSigningKey()).orElseThrow(() -> new InvalidJwtToken());
+
+        String jti = refreshToken.getJti();
+        if (!tokenVerifier.verify(jti)) {
+            throw new InvalidJwtToken();
+        }
+        String subject = refreshToken.getSubject();
+        // ���refresh token��� ������������������
+        LoginMode mode = LoginMode.valueOf(refreshToken.getClaims().getBody().get("mode").toString());
+        Account account = accountService.queryAccountByName(subject).orElseThrow(() -> new UsernameNotFoundException("User not found: " + subject));
+
+        if (account.getRoles() == null) throw new InsufficientAuthenticationException("User has no roles assigned");
+        List<GrantedAuthority> authorities = account.getRoles().stream()
+                .map(authority -> new SimpleGrantedAuthority(authority.getName()))
+                .collect(Collectors.toList());
+
+        UserContext userContext = UserContext.create(account.getAccountName(),mode,account.getOrganizationId(),authorities);
+
+        return tokenFactory.createAccessJwtToken(userContext);
+    }
+}
diff --git a/src/main/java/com/moral/security/exceptions/AuthMethodNotSupportedException.java b/src/main/java/com/moral/security/exceptions/AuthMethodNotSupportedException.java
new file mode 100644
index 0000000..9b6db5c
--- /dev/null
+++ b/src/main/java/com/moral/security/exceptions/AuthMethodNotSupportedException.java
@@ -0,0 +1,17 @@
+package com.moral.security.exceptions;
+
+import org.springframework.security.authentication.AuthenticationServiceException;
+
+/**
+ * 
+ * @author vladimir.stankovic
+ *
+ * Aug 4, 2016
+ */
+public class AuthMethodNotSupportedException extends AuthenticationServiceException {
+    private static final long serialVersionUID = 3705043083010304496L;
+
+    public AuthMethodNotSupportedException(String msg) {
+        super(msg);
+    }
+}
diff --git a/src/main/java/com/moral/security/exceptions/InvalidJwtToken.java b/src/main/java/com/moral/security/exceptions/InvalidJwtToken.java
new file mode 100644
index 0000000..d4c64ec
--- /dev/null
+++ b/src/main/java/com/moral/security/exceptions/InvalidJwtToken.java
@@ -0,0 +1,12 @@
+package com.moral.security.exceptions;
+
+/**
+ * JwtTokenNotValid
+ * 
+ * @author vladimir.stankovic
+ *
+ * Aug 17, 2016
+ */
+public class InvalidJwtToken extends RuntimeException {
+    private static final long serialVersionUID = -294671188037098603L;
+}
diff --git a/src/main/java/com/moral/security/exceptions/JwtExpiredTokenException.java b/src/main/java/com/moral/security/exceptions/JwtExpiredTokenException.java
new file mode 100644
index 0000000..0259570
--- /dev/null
+++ b/src/main/java/com/moral/security/exceptions/JwtExpiredTokenException.java
@@ -0,0 +1,29 @@
+package com.moral.security.exceptions;
+
+import com.moral.security.model.token.JwtToken;
+import org.springframework.security.core.AuthenticationException;
+
+/**
+ * 
+ * @author vladimir.stankovic
+ *
+ * Aug 3, 2016
+ */
+public class JwtExpiredTokenException extends AuthenticationException {
+    private static final long serialVersionUID = -5959543783324224864L;
+    
+    private JwtToken token;
+
+    public JwtExpiredTokenException(String msg) {
+        super(msg);
+    }
+
+    public JwtExpiredTokenException(JwtToken token, String msg, Throwable t) {
+        super(msg, t);
+        this.token = token;
+    }
+
+    public String token() {
+        return this.token.getToken();
+    }
+}
diff --git a/src/main/java/com/moral/security/model/Scopes.java b/src/main/java/com/moral/security/model/Scopes.java
new file mode 100644
index 0000000..b6dbc24
--- /dev/null
+++ b/src/main/java/com/moral/security/model/Scopes.java
@@ -0,0 +1,16 @@
+package com.moral.security.model;
+
+/**
+ * Scopes
+ * 
+ * @author vladimir.stankovic
+ *
+ * Aug 18, 2016
+ */
+public enum Scopes {
+    REFRESH_TOKEN;
+    
+    public String authority() {
+        return "ROLE_" + this.name();
+    }
+}
diff --git a/src/main/java/com/moral/security/model/UserContext.java b/src/main/java/com/moral/security/model/UserContext.java
new file mode 100644
index 0000000..cc9e8b1
--- /dev/null
+++ b/src/main/java/com/moral/security/model/UserContext.java
@@ -0,0 +1,58 @@
+package com.moral.security.model;
+
+import com.moral.security.auth.login.LoginMode;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.security.core.GrantedAuthority;
+
+import java.util.List;
+
+/**
+ * 
+ * @author vladimir.stankovic
+ *
+ * Aug 4, 2016
+ */
+public class UserContext {
+    private final String username;
+
+    public LoginMode getMode() {
+        return mode;
+    }
+
+    private final LoginMode mode;
+
+    public Integer getOrganizationId() {
+        return organizationId;
+    }
+
+    private final Integer organizationId;
+    private final List<GrantedAuthority> authorities;
+
+    private UserContext(String username, LoginMode mode, Integer organizationId, List<GrantedAuthority> authorities) {
+        this.username = username;
+        this.mode = mode;
+        this.organizationId = organizationId;
+        this.authorities = authorities;
+    }
+
+    /**
+     *
+     * @param username ���������
+     * @param mode   ������������
+     * @param organizationId  ������������
+     * @param authorities  ������������
+     * @return
+     */
+    public static UserContext create(String username,LoginMode mode,Integer organizationId, List<GrantedAuthority> authorities) {
+        if (StringUtils.isBlank(username)) throw new IllegalArgumentException("Username is blank: " + username);
+        return new UserContext(username, mode, organizationId, authorities);
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public List<GrantedAuthority> getAuthorities() {
+        return authorities;
+    }
+}
diff --git a/src/main/java/com/moral/security/model/token/AccessJwtToken.java b/src/main/java/com/moral/security/model/token/AccessJwtToken.java
new file mode 100644
index 0000000..28f2d96
--- /dev/null
+++ b/src/main/java/com/moral/security/model/token/AccessJwtToken.java
@@ -0,0 +1,30 @@
+package com.moral.security.model.token;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import io.jsonwebtoken.Claims;
+
+/**
+ * Raw representation of JWT Token.
+ * 
+ * @author vladimir.stankovic
+ *
+ *         May 31, 2016
+ */
+public final class AccessJwtToken implements JwtToken {
+    private final String rawToken;
+    @JsonIgnore
+    private Claims claims;
+
+    protected AccessJwtToken(final String token, Claims claims) {
+        this.rawToken = token;
+        this.claims = claims;
+    }
+
+    public String getToken() {
+        return this.rawToken;
+    }
+
+    public Claims getClaims() {
+        return claims;
+    }
+}
diff --git a/src/main/java/com/moral/security/model/token/JwtToken.java b/src/main/java/com/moral/security/model/token/JwtToken.java
new file mode 100644
index 0000000..dc47498
--- /dev/null
+++ b/src/main/java/com/moral/security/model/token/JwtToken.java
@@ -0,0 +1,5 @@
+package com.moral.security.model.token;
+
+public interface JwtToken {
+    String getToken();
+}
diff --git a/src/main/java/com/moral/security/model/token/JwtTokenFactory.java b/src/main/java/com/moral/security/model/token/JwtTokenFactory.java
new file mode 100644
index 0000000..6db2228
--- /dev/null
+++ b/src/main/java/com/moral/security/model/token/JwtTokenFactory.java
@@ -0,0 +1,93 @@
+package com.moral.security.model.token;
+
+import com.moral.security.config.JwtSettings;
+import com.moral.security.model.Scopes;
+import com.moral.security.model.UserContext;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+/**
+ * Factory class that should be always used to create {@link JwtToken}.
+ * 
+ * @author vladimir.stankovic
+ *
+ * May 31, 2016
+ */
+@Component
+public class JwtTokenFactory {
+    private final JwtSettings settings;
+
+    @Autowired
+    public JwtTokenFactory(JwtSettings settings) {
+        this.settings = settings;
+    }
+
+    /**
+     * Factory method for issuing new JWT Tokens.
+     * 
+     * @param userContext
+     * @return
+     */
+    public AccessJwtToken createAccessJwtToken(UserContext userContext) {
+        if (StringUtils.isBlank(userContext.getUsername()))
+            throw new IllegalArgumentException("Cannot create JWT Token without username");
+
+        if (userContext.getAuthorities() == null || userContext.getAuthorities().isEmpty()) 
+            throw new IllegalArgumentException("User doesn't have any privileges");
+
+        Claims claims = Jwts.claims().setSubject(userContext.getUsername());
+        claims.put("oid",userContext.getOrganizationId());
+        claims.put("mode",userContext.getMode());
+        claims.put("scopes", userContext.getAuthorities().stream().map(s -> s.toString()).collect(Collectors.toList()));
+
+        LocalDateTime currentTime = LocalDateTime.now();
+        
+        String token = Jwts.builder()
+          .setClaims(claims)
+          .setIssuer(settings.getTokenIssuer())
+          .setIssuedAt(Date.from(currentTime.atZone(ZoneId.systemDefault()).toInstant()))
+          .setExpiration(Date.from(currentTime
+              .plusMinutes(settings.getTokenExpirationTime())
+              .atZone(ZoneId.systemDefault()).toInstant()))
+          .signWith(SignatureAlgorithm.HS512, settings.getTokenSigningKey())
+        .compact();
+
+        return new AccessJwtToken(token, claims);
+    }
+
+    public JwtToken createRefreshToken(UserContext userContext) {
+        if (StringUtils.isBlank(userContext.getUsername())) {
+            throw new IllegalArgumentException("Cannot create JWT Token without username");
+        }
+
+        LocalDateTime currentTime = LocalDateTime.now();
+
+        Claims claims = Jwts.claims().setSubject(userContext.getUsername());
+        claims.put("mode",userContext.getMode());
+//      claims.put("scopes", Arrays.asList(Scopes.REFRESH_TOKEN.authority()));
+        
+        String token = Jwts.builder()
+          .setClaims(claims)
+          .setIssuer(settings.getTokenIssuer())
+          .setId(UUID.randomUUID().toString())
+          .setIssuedAt(Date.from(currentTime.atZone(ZoneId.systemDefault()).toInstant()))
+          .setExpiration(Date.from(currentTime
+              .plusMinutes(settings.getRefreshTokenExpTime())
+              .atZone(ZoneId.systemDefault()).toInstant()))
+          .signWith(SignatureAlgorithm.HS512, settings.getTokenSigningKey())
+        .compact();
+
+        return new AccessJwtToken(token, claims);
+    }
+}
diff --git a/src/main/java/com/moral/security/model/token/RawAccessJwtToken.java b/src/main/java/com/moral/security/model/token/RawAccessJwtToken.java
new file mode 100644
index 0000000..b1d2bff
--- /dev/null
+++ b/src/main/java/com/moral/security/model/token/RawAccessJwtToken.java
@@ -0,0 +1,41 @@
+package com.moral.security.model.token;
+
+import com.moral.security.exceptions.JwtExpiredTokenException;
+import io.jsonwebtoken.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.authentication.BadCredentialsException;
+
+public class RawAccessJwtToken implements JwtToken {
+    private static Logger logger = LoggerFactory.getLogger(RawAccessJwtToken.class);
+            
+    private String token;
+    
+    public RawAccessJwtToken(String token) {
+        this.token = token;
+    }
+
+    /**
+     * Parses and validates JWT Token signature.
+     * 
+     * @throws BadCredentialsException
+     * @throws JwtExpiredTokenException
+     * 
+     */
+    public Jws<Claims> parseClaims(String signingKey) {
+        try {
+            return Jwts.parser().setSigningKey(signingKey).parseClaimsJws(this.token);
+        } catch (UnsupportedJwtException | MalformedJwtException | IllegalArgumentException | SignatureException ex) {
+            logger.error("Invalid JWT Token", ex);
+            throw new BadCredentialsException("Invalid JWT token: ", ex);
+        } catch (ExpiredJwtException expiredEx) {
+            logger.info("JWT Token is expired", expiredEx);
+            throw new JwtExpiredTokenException(this, "JWT Token expired", expiredEx);
+        }
+    }
+
+    @Override
+    public String getToken() {
+        return token;
+    }
+}
diff --git a/src/main/java/com/moral/security/model/token/RefreshToken.java b/src/main/java/com/moral/security/model/token/RefreshToken.java
new file mode 100644
index 0000000..0f67cd0
--- /dev/null
+++ b/src/main/java/com/moral/security/model/token/RefreshToken.java
@@ -0,0 +1,65 @@
+package com.moral.security.model.token;
+
+import com.moral.security.model.Scopes;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jws;
+import org.springframework.security.authentication.BadCredentialsException;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * RefreshToken
+ * 
+ * @author vladimir.stankovic
+ *
+ * Aug 19, 2016
+ */
+@SuppressWarnings("unchecked")
+public class RefreshToken implements JwtToken {
+    private Jws<Claims> claims;
+
+    private RefreshToken(Jws<Claims> claims) {
+        this.claims = claims;
+    }
+
+    /**
+     * Creates and validates Refresh token 
+     * 
+     * @param token
+     * @param signingKey
+     * 
+     * @throws BadCredentialsException
+     * @throws JwtExpiredTokenException
+     * 
+     * @return
+     */
+    public static Optional<RefreshToken> create(RawAccessJwtToken token, String signingKey) {
+        Jws<Claims> claims = token.parseClaims(signingKey);
+
+        List<String> scopes = claims.getBody().get("scopes", List.class);
+        if (scopes == null || scopes.isEmpty() 
+                || !scopes.stream().filter(scope -> Scopes.REFRESH_TOKEN.authority().equals(scope)).findFirst().isPresent()) {
+            return Optional.empty();
+        }
+
+        return Optional.of(new RefreshToken(claims));
+    }
+
+    @Override
+    public String getToken() {
+        return null;
+    }
+
+    public Jws<Claims> getClaims() {
+        return claims;
+    }
+    
+    public String getJti() {
+        return claims.getBody().getId();
+    }
+    
+    public String getSubject() {
+        return claims.getBody().getSubject();
+    }
+}
diff --git a/src/main/java/com/moral/service/AccountService.java b/src/main/java/com/moral/service/AccountService.java
index 289adcf..68e8371 100644
--- a/src/main/java/com/moral/service/AccountService.java
+++ b/src/main/java/com/moral/service/AccountService.java
@@ -2,6 +2,7 @@
 
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 
 import com.moral.common.bean.PageBean;
 import com.moral.entity.Account;
@@ -24,4 +25,5 @@
 
 	Integer getAccountCountByAccountName(String accountName);
 
+	Optional<Account> queryAccountByName(String accountName);
 }
diff --git a/src/main/java/com/moral/service/DeviceService.java b/src/main/java/com/moral/service/DeviceService.java
index e40048a..707b487 100644
--- a/src/main/java/com/moral/service/DeviceService.java
+++ b/src/main/java/com/moral/service/DeviceService.java
@@ -3,6 +3,7 @@
 import java.util.List;
 import java.util.Map;
 import com.moral.common.bean.PageBean;
+import com.moral.common.bean.PageResult;
 import com.moral.entity.Device;
 
 public interface DeviceService {
@@ -17,6 +18,8 @@
 
 	Device getDeviceByMac(String mac);
 
+    PageResult query(Integer orgId, String deviceName,Integer pageSize,Integer pageNo);
+
     PageBean queryByPageBean(PageBean pageBean);
 
 	void deleteByIds(Integer[] ids);
diff --git a/src/main/java/com/moral/service/impl/AccountServiceImpl.java b/src/main/java/com/moral/service/impl/AccountServiceImpl.java
index be7b39a..d441f1f 100644
--- a/src/main/java/com/moral/service/impl/AccountServiceImpl.java
+++ b/src/main/java/com/moral/service/impl/AccountServiceImpl.java
@@ -7,15 +7,11 @@
 import static org.apache.commons.lang3.StringUtils.isNumeric;
 import static org.springframework.util.ObjectUtils.isEmpty;
 
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 import javax.annotation.Resource;
 
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.ObjectUtils;
@@ -38,7 +34,8 @@
 
 @Service
 public class AccountServiceImpl implements AccountService {
-
+    @Resource
+	private  BCryptPasswordEncoder encoder;
 	@Resource
 	private AccountMapper accountMapper;
 
@@ -47,7 +44,7 @@
 
 	@Resource
 	private OrganizationMapper organizationMapper;
-	
+
 	@Override
 	public Map<String, Object> screenLogin(Map<String, Object> parameters) {
 		Map<String, Object> result = new HashMap<String, Object>();
@@ -147,7 +144,7 @@
 		if (ObjectUtils.isEmpty(account.getId())) {
 			account.setIsDelete(Constants.IS_DELETE_FALSE);
 			account.setCreateTime(new Date());
-			account.setPassword(Crypto.md5(ResourceUtil.getValue("password")));
+			account.setPassword(encoder.encode(ResourceUtil.getValue("password")));
 			return accountMapper.insertSelective(account);
 		} else {
 			return accountMapper.updateByPrimaryKeySelective(account);
@@ -171,4 +168,10 @@
 		return accountMapper.selectCount(account);
 	}
 
+	@Override
+	public Optional<Account> queryAccountByName(String accountName) {
+		Account account = new Account();
+		account.setAccountName(accountName);
+		return Optional.ofNullable(accountMapper.selectOne(account));
+	}
 }
diff --git a/src/main/java/com/moral/service/impl/DeviceServiceImpl.java b/src/main/java/com/moral/service/impl/DeviceServiceImpl.java
index 78cbbd7..eefb269 100644
--- a/src/main/java/com/moral/service/impl/DeviceServiceImpl.java
+++ b/src/main/java/com/moral/service/impl/DeviceServiceImpl.java
@@ -4,8 +4,10 @@
 
 import javax.annotation.Resource;
 
+import com.github.pagehelper.Page;
 import com.moral.common.bean.Constants;
 import com.moral.common.bean.PageBean;
+import com.moral.common.bean.PageResult;
 import com.moral.common.util.ExampleUtil;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -102,6 +104,18 @@
 	}
 
 	@Override
+	public PageResult query(Integer orgId, String deviceName, Integer pageSize, Integer pageNo) {
+		if(!ObjectUtils.isEmpty(pageSize)&&!ObjectUtils.isEmpty(pageNo)){
+			PageHelper.startPage(pageNo,pageSize);
+		}
+		List list = deviceMapper.selectByOrgIdAndDevName(orgId,deviceName);
+		if(list instanceof Page){
+			return new PageResult(((Page) list).getTotal(),list);
+		}
+		return new PageResult(null,list);
+	}
+
+	@Override
 	public PageBean queryByPageBean(PageBean pageBean) {
 		Example example = ExampleUtil.generateExample(ENTITY_CLASS,pageBean);
 		List<Example.Criteria> criteriaList = example.getOredCriteria();
diff --git a/src/main/java/com/moral/service/impl/MonitorPointServiceImpl.java b/src/main/java/com/moral/service/impl/MonitorPointServiceImpl.java
index fc0db0d..79cf204 100644
--- a/src/main/java/com/moral/service/impl/MonitorPointServiceImpl.java
+++ b/src/main/java/com/moral/service/impl/MonitorPointServiceImpl.java
@@ -9,11 +9,9 @@
 import com.github.pagehelper.PageHelper;
 import com.moral.common.bean.Constants;
 import com.moral.common.bean.PageBean;
-import com.moral.common.util.ExampleUtil;
-import com.moral.common.util.MyBatisBaseMapUtil;
+import com.moral.common.util.*;
 import org.springframework.stereotype.Service;
 
-import com.moral.common.util.ValidateUtil;
 import com.moral.entity.MonitorPoint;
 import com.moral.mapper.MonitorPointMapper;
 import com.moral.service.MonitorPointService;
@@ -24,6 +22,8 @@
 public class MonitorPointServiceImpl implements MonitorPointService {
     @Resource
     private MonitorPointMapper monitorPointMapper;
+    @Resource
+    RedisUtils redisUtils;
     private static Class ENTITY_CLASS = MonitorPoint.class;
     @Override
     public List<MonitorPoint> getMonitorPointsByAreaName(Map<String, Object> parameters) {
@@ -32,7 +32,25 @@
     }
     @Override
     public List<MonitorPoint> queryWithStateByMap(Map<String, Object> params){
-        return monitorPointMapper.selectWithStateByMap(params);
+        List<MonitorPoint> monitorPointList = monitorPointMapper.selectByMap(params);
+        for(MonitorPoint monitorPoint:monitorPointList){
+            loadStateFromRedis(monitorPoint);
+        }
+        return monitorPointList;
+    }
+    private void loadStateFromRedis(MonitorPoint monitorPoint){
+        StringBuilder key = new StringBuilder();
+        key.append("*_").append(monitorPoint.getId()).append("_*");
+        List<Map> stateList = redisUtils.getList(key.toString(),Map.class);
+        int state = -1;
+        if(stateList!=null){
+            for (Map deviceState:stateList){
+                int s =  Integer.parseInt(deviceState.get("state").toString());
+                state = s>state&&s<4?s:state;
+            }
+        }
+        state = state==-1?4:state;
+        monitorPoint.setState(state);
     }
     @Override
     public PageBean queryByPageBean(PageBean pageBean) {
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index b76fb92..f15aa45 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -3,8 +3,15 @@
   session-timeout: 30
   tomcat.max-threads: 0
   tomcat.uri-encoding: UTF-8
-
+spring.profiles: default
+moral.security.jwt:
+    tokenExpirationTime: 15 # Number of minutes
+    refreshTokenExpTime: 60 # Minutes
+    tokenIssuer: http://monitor.7drlb.com
+    tokenSigningKey: xm9EV6Hy5RAFL8EEACIDAwQus
 spring:
+  thymeleaf:
+    cache: false
   datasource:
     url: jdbc:mysql://47.96.19.115:3306/monitor_db?characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC
     username: root
@@ -64,4 +71,5 @@
 
 mybatis:
   mapper-locations: classpath*:/mapper/*Mapper.xml
-  config-location: classpath:/mapper/mybatis-config.xml
\ No newline at end of file
+  config-location: classpath:/mapper/mybatis-config.xml
+
diff --git a/src/main/resources/mapper/DeviceMapper.xml b/src/main/resources/mapper/DeviceMapper.xml
index fbe298a..cb2cba0 100644
--- a/src/main/resources/mapper/DeviceMapper.xml
+++ b/src/main/resources/mapper/DeviceMapper.xml
@@ -81,7 +81,7 @@
 	  </if>
 	  )
   </select>
-	<select id="getDeviceStatesByAccount" resultType="map">
+	<select id="getDeviceStatesByAccount" resultType="java.util.Map">
 		SELECT
 			COUNT( d.state ) count,
 			d.state 
@@ -98,8 +98,16 @@
 		</if>
 		GROUP BY d.state
 	</select>
-
-	<select id="getSensorsByDevice" resultType="map">
+	<select id="selectByOrgIdAndDevName" resultMap="BaseResultMap">
+        SELECT * from device dev
+        left join monitor_point mpt on dev.monitor_point_id = mpt.id
+        where
+		mpt.organization_id =  #{orgId}
+        <if test="devName!=null and ''!=devName">
+        and dev.name like #{devName}
+		</if>
+	</select>
+	<select id="getSensorsByDevice" resultType="java.util.Map">
 		SELECT
 			s.`key`,
 			s.`name` 
diff --git a/src/main/resources/mapper/MonitorPointMapper.xml b/src/main/resources/mapper/MonitorPointMapper.xml
index 652012a..ee6e6af 100644
--- a/src/main/resources/mapper/MonitorPointMapper.xml
+++ b/src/main/resources/mapper/MonitorPointMapper.xml
@@ -13,6 +13,7 @@
     <result column="address" jdbcType="VARCHAR" property="address" />
     <result column="is_delete" jdbcType="CHAR" property="isDelete" />
     <result column="description" jdbcType="VARCHAR" property="description" />
+	  <result column="state" jdbcType="INTEGER" property="state" />
 	<!-- ������������������������������ -->
     <association property="areaNames" javaType="com.moral.entity.AreaNames">
 	  <result column="province_name" property="provinceName" jdbcType="VARCHAR" />
@@ -100,10 +101,8 @@
 			AND mp.city_code = c.city_code
 		</if>
 	</select>
-	<select id="selectWithStateByMap" parameterType="java.util.Map" resultMap="BaseResultMap">
-
-		SELECT mpt.*,MAX(dev.state) as state from monitor_point mpt
-		LEFT JOIN device dev on dev.monitor_point_id = mpt.id
+	<select id="selectByMap" parameterType="java.util.Map" resultMap="BaseResultMap">
+		SELECT mpt.* from monitor_point mpt
 		<where>
 			<if test="@com.moral.common.bean.Constants@isNotSpecialOrgId(orgId)">
 				mpt.organization_id = #{orgId,jdbcType=VARCHAR}
@@ -113,25 +112,7 @@
             AND mpt.longitude > #{mapBounds.Le,jdbcType=NUMERIC}
             AND mpt.latitude  < #{mapBounds.Fe,jdbcType=NUMERIC}
             AND mpt.latitude  > #{mapBounds.Ke,jdbcType=NUMERIC}
-		    and state<4
-			GROUP BY mpt.`id`
      		 ]]>
-		</where>
-		UNION
-		SELECT mpt.*,MAX(dev.state) as state from monitor_point mpt
-		LEFT JOIN device dev on dev.monitor_point_id = mpt.id
-		<where>
-			<if test="@com.moral.common.bean.Constants@isNotSpecialOrgId(orgId)">
-				mpt.organization_id = #{orgId,jdbcType=VARCHAR}
-			</if>
-			<![CDATA[
-			AND mpt.longitude < #{mapBounds.Ge,jdbcType=NUMERIC}
-            AND mpt.longitude > #{mapBounds.Le,jdbcType=NUMERIC}
-            AND mpt.latitude  < #{mapBounds.Fe,jdbcType=NUMERIC}
-            AND mpt.latitude  > #{mapBounds.Ke,jdbcType=NUMERIC}
-		    and state>3
-			GROUP BY mpt.`id`
-            ]]>
 		</where>
 	</select>
 </mapper>
\ No newline at end of file
diff --git a/src/main/resources/system/sysConfig.properties b/src/main/resources/system/sysConfig.properties
index cbc54af..d2a12c9 100644
--- a/src/main/resources/system/sysConfig.properties
+++ b/src/main/resources/system/sysConfig.properties
@@ -26,4 +26,5 @@
 e18-standard=9
 e19-standard=50
 orgId=-1
-password=123456
\ No newline at end of file
+password=123456
+noFilters=login
\ No newline at end of file
diff --git a/src/main/webapp/js/moralmap.js b/src/main/webapp/js/moralmap.js
index e26429f..c28f4b8 100644
--- a/src/main/webapp/js/moralmap.js
+++ b/src/main/webapp/js/moralmap.js
@@ -360,29 +360,19 @@
 				var pageSize = option["pageSize"] || 20;
 				var pageNo = option["pageNo"] || 1;
 				var url = option['url'];
-				url += "&page=" + pageNo;
-				url += "&rows=" + pageSize;
+				url += "&pageNo=" + pageNo;
+				url += "&pageSize=" + pageSize;
+				console.log(url);
 				$.ajax({
 					type: "get",
 					cache: false,
 					url: url,
 					async: true,
-					success: function(data) {
-						if(data) {
-							if(typeof data !== 'object' && typeof data === 'string') {
-								try {
-									data = $.parseJSON(data);
-								} catch(e) {
-									return;
-								}
-							}
-							var rows = null;
-							if(data['rows'] != undefined) {
-								rows = data['rows'];
-							} else {
-								rows = data;
-							}
-							if(rows.length == 0) {
+					success: function(res) {
+						if(res!=null&&res.total!=null) {
+							debugger;
+							var rows = res.data;
+							if(rows==null||rows.length == 0) {
 								$(option['id']).html("������������������������������");
 								return;
 							}
@@ -417,7 +407,7 @@
 								outHtml += li;
 							}
 							outHtml += "</ul>";
-							var total = data['total'];
+							var total = res['total'];
 							var totalPage = Math.ceil(total / pageSize);
 							if(totalPage > 1) {
 								outHtml += "<div id='page' class='page_div'></div>";
@@ -494,7 +484,7 @@
 	//��������������� ������Mark������
 	moralMap.Monitorpoint = function(option) {
 		var icon = {};
-		icon["stateIcons"] = ["img/ico00.png", "img/ico01.png", "img/ico02.png", "img/ico03.png", "img/ico04.png"];
+		icon["stateIcons"] = ["/img/ico00.png", "/img/ico01.png", "/img/ico02.png", "/img/ico03.png", "/img/ico04.png"];
 		icon["width"] = 50;
 		icon["height"] = 50;
 		option["icon"] = icon;
diff --git a/src/main/webapp/view/map.jsp b/src/main/webapp/view/map.jsp
index 77896b8..6473019 100644
--- a/src/main/webapp/view/map.jsp
+++ b/src/main/webapp/view/map.jsp
@@ -264,7 +264,7 @@
 	function showEqus(obj) {
 		var params = moralMap['params'];
 		var mpoint = obj.currentTarget.getOption();
-		var url = 'equipment/findAllEqu?mpId=' + mpoint['id'] + "&orgId=" + params['orgId'];
+		var url = 'get-devices?mpId=' + mpoint['id'] + "&orgId=" + params['orgId'];
 		listView.load(url); 
 		moralMap.showPopupbox("#popup_box");
 	}
@@ -371,7 +371,7 @@
 //	     if(endZoom>=moralMap.getZooMConfine()){//������������������������
 //	     		loadOverlays("getequipments",addOverEquipments);
 //	     }else{
-//				loadOverlays("getmonitorpoints",addOverMpoints);
+//				loadOverlays("get-monitorpoints",addOverMpoints);
 //	     }
 //	     moralMap.closePopupbox("#popup_box");
 	});
@@ -383,7 +383,7 @@
 	     if(endZoom>=moralMap.getZooMConfine()){//������������������������
 	     		loadOverlays("getequipments",addOverEquipments);
 	     }else{
-				loadOverlays("getmonitorpoints",addOverMpoints);
+				loadOverlays("get-monitorpoints",addOverMpoints);
 	     }
 	     moralMap.closePopupbox("#popup_box");
 	});
@@ -392,7 +392,7 @@
 	     if(endZoom>=moralMap.getZooMConfine()){//������������������������
 	     		loadOverlays("getequipments",addOverEquipments);
 	     }else{
-				loadOverlays("getmonitorpoints",addOverMpoints);
+				loadOverlays("get-monitorpoints",addOverMpoints);
 	     }
 	     moralMap.closePopupbox("#popup_box");
 	});
@@ -401,7 +401,7 @@
 		function(e) {
 			var param = encodeURI($("#searchParam").val());
 			moralMap.showPopupbox("#popup_box");
-			var url = 'equipment/findAllEqu?name=' + param + "&orgId=" + params['orgId'];
+			var url = 'get-devices-for-popup?name=' + param + "&orgId=" + params['orgId'];
 			listView.load(url); 
 		}
 	)
diff --git a/src/test/java/com/moral/JavaBeanToJsonOutPrint.java b/src/test/java/com/moral/JavaBeanToJsonOutPrint.java
index fbc1ff3..8b9de9d 100644
--- a/src/test/java/com/moral/JavaBeanToJsonOutPrint.java
+++ b/src/test/java/com/moral/JavaBeanToJsonOutPrint.java
@@ -6,8 +6,11 @@
 import com.moral.entity.Device;
 import com.moral.entity.DeviceAdjustValue;
 import com.moral.entity.alarm.AlarmConfig;
+import com.moral.security.auth.login.LoginMode;
+import com.moral.security.model.UserContext;
 import org.junit.Test;
 
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
@@ -15,7 +18,7 @@
 public class JavaBeanToJsonOutPrint {
     @Test
     public void jsonOutPrintTest(){
-        DeviceAdjustValue adjustValue = new DeviceAdjustValue();
+        UserContext userContext = UserContext.create("312", LoginMode.Andriod,1,new ArrayList<>());
 //        adjustValue.setCreateTime(new Date());
 //        adjustValue.setUpdateTime(new Date());
 //        adjustValue.setId(0);
@@ -23,12 +26,10 @@
 //        value.put("e1", (float) 1.2);
 //        adjustValue.setValue(value);
         String json = "{\"createTime\":1516342989358,\"deviceId\":null,\"id\":0,\"updateTime\":1516342989358,\"value\":{\"e1\":1.2}}";
-        Map map = JSON.parseObject("{\"e1\":0.0}");
-//        String json = JSON.toJSONString(new Device(),
-//                SerializerFeature.WriteMapNullValue
-//                );
+//        Map map = JSON.parseObject("{\"e1\":0.0}");
+        String json1 = JSON.toJSONString(userContext);
         System.out.printf("\n\n\n\n");
-        System.out.printf(json);
+        System.out.printf(json1);
         System.out.printf("\n\n\n\n");
     }
 }

--
Gitblit v1.8.0