From f04a0eed49d2cb83ffae4d53a8b0961313b58b30 Mon Sep 17 00:00:00 2001
From: mrz <17966059@qq.com>
Date: Tue, 19 Feb 2019 16:37:36 +0800
Subject: [PATCH] spring security 用户登录部分完善

---
 pom.xml                                                                                    |  6 ++++++
 src/main/java/com/tianbo/warehouse/WarehouseApplication.java                               |  4 +---
 src/main/java/com/tianbo/warehouse/controller/MainController.java                          |  5 ++---
 src/main/java/com/tianbo/warehouse/model/USERS.java                                        | 21 +++++++++++++++++++++
 src/main/java/com/tianbo/warehouse/security/CustomUserDetailService.java                   | 13 +++++++------
 src/main/java/com/tianbo/warehouse/security/MyAccessDecisionManager.java                   | 19 ++++++++++++-------
 src/main/java/com/tianbo/warehouse/security/MyInvocationSecurityMetadataSourceService.java |  4 ++++
 src/main/java/com/tianbo/warehouse/security/PasswordEncoderImp.java                        | 23 -----------------------
 src/main/java/com/tianbo/warehouse/security/WebSecurityConfig.java                         | 68 --------------------------------------------------------------------
 src/main/java/com/tianbo/warehouse/security/config/PasswordEncoderImp.java                 | 25 +++++++++++++++++++++++++
 src/main/java/com/tianbo/warehouse/security/config/SecurityProperties.java                 | 23 +++++++++++++++++++++++
 src/main/java/com/tianbo/warehouse/security/config/WebSecurityConfig.java                  | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/main/java/com/tianbo/warehouse/security/handel/MyAuthenticationFailHandler.java        | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/main/java/com/tianbo/warehouse/security/handel/MyAuthenticationSuccessHandler.java     | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/main/java/com/tianbo/warehouse/security/model/BrowserProperties.java                   | 34 ++++++++++++++++++++++++++++++++++
 src/main/java/com/tianbo/warehouse/security/model/LoginType.java                           |  6 ++++++
 src/main/java/com/tianbo/warehouse/service/imp/UserServiceImpl.java                        |  9 ++-------
 src/main/resources/application.properties                                                  | 73 ++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
 src/main/resources/static/index.html                                                       | 18 +-----------------
 19 files changed, 410 insertions(+), 159 deletions(-)
 delete mode 100644 src/main/java/com/tianbo/warehouse/security/PasswordEncoderImp.java
 delete mode 100644 src/main/java/com/tianbo/warehouse/security/WebSecurityConfig.java
 create mode 100644 src/main/java/com/tianbo/warehouse/security/config/PasswordEncoderImp.java
 create mode 100644 src/main/java/com/tianbo/warehouse/security/config/SecurityProperties.java
 create mode 100644 src/main/java/com/tianbo/warehouse/security/config/WebSecurityConfig.java
 create mode 100644 src/main/java/com/tianbo/warehouse/security/handel/MyAuthenticationFailHandler.java
 create mode 100644 src/main/java/com/tianbo/warehouse/security/handel/MyAuthenticationSuccessHandler.java
 create mode 100644 src/main/java/com/tianbo/warehouse/security/model/BrowserProperties.java
 create mode 100644 src/main/java/com/tianbo/warehouse/security/model/LoginType.java

diff --git a/pom.xml b/pom.xml
index eafaf65..0d7f637 100644
--- a/pom.xml
+++ b/pom.xml
@@ -92,6 +92,12 @@
 			<artifactId>druid-spring-boot-starter</artifactId>
 			<version>1.1.9</version>
 		</dependency>
+		<!-- mysql-->
+		<dependency>
+			<groupId>mysql</groupId>
+			<artifactId>mysql-connector-java</artifactId>
+		</dependency>
+		<!-- oracle-->
 		<dependency>
 			<groupId>com.oracle</groupId>
 			<artifactId>ojdbc6</artifactId>
diff --git a/src/main/java/com/tianbo/warehouse/WarehouseApplication.java b/src/main/java/com/tianbo/warehouse/WarehouseApplication.java
index 7e4f1e7..ac4b935 100644
--- a/src/main/java/com/tianbo/warehouse/WarehouseApplication.java
+++ b/src/main/java/com/tianbo/warehouse/WarehouseApplication.java
@@ -11,11 +11,9 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
 import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
 import org.springframework.scheduling.annotation.EnableScheduling;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-
 @SpringBootApplication
 @EnableScheduling
-@EnableEurekaClient
+//@EnableEurekaClient
 @MapperScan("com.tianbo.warehouse.dao")
 public class WarehouseApplication {
 
diff --git a/src/main/java/com/tianbo/warehouse/controller/MainController.java b/src/main/java/com/tianbo/warehouse/controller/MainController.java
index edd24ab..031a78e 100644
--- a/src/main/java/com/tianbo/warehouse/controller/MainController.java
+++ b/src/main/java/com/tianbo/warehouse/controller/MainController.java
@@ -15,9 +15,8 @@ public class MainController {
     UserService userService;
 
     @GetMapping("/error")
-    public List<USERS> error(){
-        List<USERS> usersList =userService.selectAllUser();
-        return usersList;
+    public String  error(){
+            return "error";
     }
 
     @GetMapping("/main")
diff --git a/src/main/java/com/tianbo/warehouse/model/USERS.java b/src/main/java/com/tianbo/warehouse/model/USERS.java
index c3facc5..ce87260 100644
--- a/src/main/java/com/tianbo/warehouse/model/USERS.java
+++ b/src/main/java/com/tianbo/warehouse/model/USERS.java
@@ -136,26 +136,47 @@ public class USERS  implements UserDetails{
     public void setPermissions(List<PERMISSION> permissions) {
         this.permissions = permissions;
     }
+
+    /**
+     * 账户未过期
+     * @return
+     */
     @Override
     public boolean isAccountNonExpired(){
         return true;
     }
 
+    /**
+     * 账户未锁定
+     * @return
+     */
     @Override
     public boolean isAccountNonLocked(){
         return true;
     }
 
+    /**密码未过期
+     *
+     * @return
+     */
     @Override
     public boolean isCredentialsNonExpired(){
         return true;
     }
 
+    /**
+     * //账户可用
+     * @return
+     */
     @Override
     public boolean isEnabled(){
         return true;
     }
 
+    /**
+     * user的权限列表
+     * @return
+     */
     @Override
     public Collection<? extends GrantedAuthority> getAuthorities(){
         List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
diff --git a/src/main/java/com/tianbo/warehouse/security/CustomUserDetailService.java b/src/main/java/com/tianbo/warehouse/security/CustomUserDetailService.java
index ce1dd18..62dc085 100644
--- a/src/main/java/com/tianbo/warehouse/security/CustomUserDetailService.java
+++ b/src/main/java/com/tianbo/warehouse/security/CustomUserDetailService.java
@@ -3,6 +3,7 @@ package com.tianbo.warehouse.security;
 import com.tianbo.warehouse.model.USERS;
 import com.tianbo.warehouse.service.UserService;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.core.userdetails.UserDetailsService;
 import org.springframework.security.core.userdetails.UsernameNotFoundException;
@@ -20,13 +21,13 @@ public class CustomUserDetailService implements UserDetailsService {
     @Override
     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
 
-        try {
-            USERS user = userService.loadByUsername(username);
-            return user;
-        } catch (UsernameNotFoundException e) {
 
-            e.printStackTrace();
+        USERS user = userService.loadByUsername(username);
+        if (user == null) {
+            throw new UsernameNotFoundException("用户名不存在");
+//            throw new BadCredentialsException("用户名不存在");
         }
-        return null;
+        return user;
+
     }
 }
diff --git a/src/main/java/com/tianbo/warehouse/security/MyAccessDecisionManager.java b/src/main/java/com/tianbo/warehouse/security/MyAccessDecisionManager.java
index 8a3bd5e..cf4d806 100644
--- a/src/main/java/com/tianbo/warehouse/security/MyAccessDecisionManager.java
+++ b/src/main/java/com/tianbo/warehouse/security/MyAccessDecisionManager.java
@@ -13,12 +13,17 @@ import java.util.Iterator;
 
 @Service
 public class MyAccessDecisionManager implements AccessDecisionManager{
-
-    // decide 方法是判定是否拥有权限的决策方法,
-    //authentication 是释CustomUserService中循环添加到 GrantedAuthority 对象中的权限信息集合.
-    //object 包含客户端发起的请求的requset信息,可转换为 HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
-    //configAttributes 为MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法返回的结果,此方法是为了判定用户请求的url 是否在权限表中,如果在权限表中,则返回给 decide 方法,用来判定用户是否有此权限。如果不在权限表中则放行。
-
+     /**
+     * decide方法接收三个参数,decide 方法是判定是否拥有权限的决策方法
+     * 其中第一个参数中保存了当前登录用户的角色信息,authentication 是释CustomUserService中循环添加到 GrantedAuthority 对象中的权限信息集合.
+     * object 包含客户端发起的请求的requset信息,可转换为 HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
+     * 第三个参数则是MyInvocationSecurityMetadataSourceService中的getAttributes方法传来的,表示当前请求需要的角色(可能有多个),此方法是为了判定用户请求的url 是否在权限表中,如果在权限表中,则返回给 decide 方法,用来判定用户是否有此权限。如果不在权限表中则放行。
+     * @param authentication
+     * @param object
+     * @param configAttributes
+     * @throws AccessDeniedException
+     * @throws InsufficientAuthenticationException
+     */
     @Override
     public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException{
 
@@ -37,7 +42,7 @@ public class MyAccessDecisionManager implements AccessDecisionManager{
                 }
             }
         }
-        throw new AccessDeniedException("no right");
+        throw new AccessDeniedException("权限不足!");
     }
 
     @Override
diff --git a/src/main/java/com/tianbo/warehouse/security/MyInvocationSecurityMetadataSourceService.java b/src/main/java/com/tianbo/warehouse/security/MyInvocationSecurityMetadataSourceService.java
index 6cc0a68..63c1516 100644
--- a/src/main/java/com/tianbo/warehouse/security/MyInvocationSecurityMetadataSourceService.java
+++ b/src/main/java/com/tianbo/warehouse/security/MyInvocationSecurityMetadataSourceService.java
@@ -13,6 +13,10 @@ import org.springframework.stereotype.Service;
 import javax.servlet.http.HttpServletRequest;
 import java.util.*;
 
+/**
+ * 本类的主要功能就是通过当前的请求地址,获取该地址需要的用户角色
+ * 如果getAttributes(Object o)方法返回null的话,意味着当前这个请求不需要任何角色就能访问,甚至不需要登录。
+ */
 @Service
 public class MyInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource{
 
diff --git a/src/main/java/com/tianbo/warehouse/security/PasswordEncoderImp.java b/src/main/java/com/tianbo/warehouse/security/PasswordEncoderImp.java
deleted file mode 100644
index da935c4..0000000
--- a/src/main/java/com/tianbo/warehouse/security/PasswordEncoderImp.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.tianbo.warehouse.security;
-
-import org.apache.commons.codec.digest.DigestUtils;
-import org.apache.tomcat.util.security.MD5Encoder;
-import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.stereotype.Service;
-
-@Service(value = "passwordEncodeService")
-public class PasswordEncoderImp implements PasswordEncoder{
-
-    @Override
-    public String encode(CharSequence charSequence) {
-        String enncodePassword = DigestUtils.md5Hex(charSequence.toString());
-        return enncodePassword;
-    }
-
-    @Override
-    public boolean matches(CharSequence rawPassword, String encodedPassword) {
-        //用户输入的登录密码
-        String endcodeInputPass = DigestUtils.md5Hex(rawPassword.toString());
-        return encodedPassword.equals(endcodeInputPass);
-    }
-}
diff --git a/src/main/java/com/tianbo/warehouse/security/WebSecurityConfig.java b/src/main/java/com/tianbo/warehouse/security/WebSecurityConfig.java
deleted file mode 100644
index 10826ea..0000000
--- a/src/main/java/com/tianbo/warehouse/security/WebSecurityConfig.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package com.tianbo.warehouse.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.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.core.userdetails.UserDetailsService;
-import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
-
-@Configuration
-@EnableWebSecurity
-public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
-
-    @Autowired
-    private MyFilterSecurityInterceptor myFilterSecurityInterceptor;
-
-    @Autowired
-    private  PasswordEncoder passwordEncoder;
-
-    @Qualifier("customuserservice")
-    @Autowired
-    private  UserDetailsService userDetailsService;
-
-    @Override
-    protected void configure(AuthenticationManagerBuilder  auth) throws Exception {
-        //user Details Service验证
-        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
-    }
-
-    @Override
-    protected void configure(HttpSecurity http) throws Exception {
-        http.authorizeRequests()
-                .antMatchers("/admin","/role").authenticated()
-                //管理页面只允许管理员角色访问  //任何请求,登录后可以访问
-                .anyRequest().permitAll() //其余的不需要验证
-                .and()
-                .formLogin()
-                .passwordParameter("password")
-                .usernameParameter("username")
-                //.loginProcessingUrl("/home")//登陆提交的处理url
-                .loginPage("/login")
-                .failureUrl("/error")
-                .permitAll()//登录页面用户任意访问
-                .successForwardUrl("/main")
-                .and()
-                .logout()
-                .logoutSuccessUrl("/?logout=true")
-                .permitAll()
-                .and()
-                .rememberMe()
-                .tokenValiditySeconds(604800)
-                //记住我功能,cookies有限期是一周
-                .rememberMeParameter("remeberme")
-                //登陆时是否激活记住我功能的参数名字,在登陆页面有展示
-                .rememberMeCookieName("workspace")
-                //cookies的名字,登陆后可以通过浏览器查看cookies名字
-                .and()
-                .cors()
-                .and()
-                .csrf().disable();
-
-        //http.addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class).csrf().disable();
-    }
-}
diff --git a/src/main/java/com/tianbo/warehouse/security/config/PasswordEncoderImp.java b/src/main/java/com/tianbo/warehouse/security/config/PasswordEncoderImp.java
new file mode 100644
index 0000000..23bf625
--- /dev/null
+++ b/src/main/java/com/tianbo/warehouse/security/config/PasswordEncoderImp.java
@@ -0,0 +1,25 @@
+package com.tianbo.warehouse.security.config;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.stereotype.Service;
+
+/**
+ * PasswordEncoder 是个接口,该接口下有两个方法,一个是encoder 一个是matches,前者用于加密,后者用于匹配校验.
+ */
+@Service(value = "passwordEncodeService")
+public class PasswordEncoderImp implements PasswordEncoder{
+
+    @Override
+    public String encode(CharSequence charSequence) {
+        String enncodePassword = DigestUtils.md5Hex(charSequence.toString());
+        return enncodePassword;
+    }
+
+    @Override
+    public boolean matches(CharSequence rawPassword, String encodedPassword) {
+        //用户输入的登录密码
+        String endcodeInputPass = DigestUtils.md5Hex(rawPassword.toString());
+        return encodedPassword.equals(endcodeInputPass);
+    }
+}
diff --git a/src/main/java/com/tianbo/warehouse/security/config/SecurityProperties.java b/src/main/java/com/tianbo/warehouse/security/config/SecurityProperties.java
new file mode 100644
index 0000000..5011903
--- /dev/null
+++ b/src/main/java/com/tianbo/warehouse/security/config/SecurityProperties.java
@@ -0,0 +1,23 @@
+package com.tianbo.warehouse.security.config;
+
+import com.tianbo.warehouse.security.model.BrowserProperties;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@ConfigurationProperties(prefix = "tianbo.security")
+@Component
+public class SecurityProperties {
+
+    /**
+     * 浏览器 属性类
+     */
+    private BrowserProperties browser = new BrowserProperties();
+
+    public BrowserProperties getBrowser() {
+        return browser;
+    }
+
+    public void setBrowser(BrowserProperties browser) {
+        this.browser = browser;
+    }
+}
diff --git a/src/main/java/com/tianbo/warehouse/security/config/WebSecurityConfig.java b/src/main/java/com/tianbo/warehouse/security/config/WebSecurityConfig.java
new file mode 100644
index 0000000..d9f4de1
--- /dev/null
+++ b/src/main/java/com/tianbo/warehouse/security/config/WebSecurityConfig.java
@@ -0,0 +1,82 @@
+package com.tianbo.warehouse.security.config;
+
+import com.tianbo.warehouse.security.handel.MyAuthenticationFailHandler;
+import com.tianbo.warehouse.security.handel.MyAuthenticationSuccessHandler;
+import com.tianbo.warehouse.security.MyFilterSecurityInterceptor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+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.core.userdetails.UserDetailsService;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+@Configuration
+@EnableWebSecurity
+@Order(1)
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+
+    @Autowired
+    private MyFilterSecurityInterceptor myFilterSecurityInterceptor;
+
+    @Autowired
+    private  PasswordEncoder passwordEncoder;
+
+    @Autowired
+    private MyAuthenticationSuccessHandler successHandler;
+
+    @Autowired
+    private MyAuthenticationFailHandler failHandler;
+
+    @Qualifier("customuserservice")
+    @Autowired
+    private  UserDetailsService userDetailsService;
+
+    @Override
+    protected void configure(AuthenticationManagerBuilder  auth) throws Exception {
+        //user Details Service验证
+        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
+    }
+
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        http.authorizeRequests()
+                .antMatchers("/admin","/role").authenticated()
+                //管理页面只允许管理员角色访问  //任何请求,登录后可以访问
+                .anyRequest().permitAll() //其余的不需要验证
+                .and()
+                .formLogin()
+                .passwordParameter("password")
+                .usernameParameter("username")
+                //登陆提交的处理url
+                //.loginProcessingUrl("/home")
+                .loginPage("/login")
+                .successHandler(successHandler)
+                .failureHandler(failHandler)
+//                .failureUrl("/error")
+                //登录页面用户任意访问
+                .permitAll()
+//                .successForwardUrl("/main")
+                .and()
+                .logout()
+                .logoutSuccessUrl("/?logout=true")
+                .permitAll()
+                .and()
+                .rememberMe()
+                .tokenValiditySeconds(604800)
+                //记住我功能,cookies有限期是一周
+                .rememberMeParameter("remeberme")
+                //登陆时是否激活记住我功能的参数名字,在登陆页面有展示
+                .rememberMeCookieName("workspace")
+                //cookies的名字,登陆后可以通过浏览器查看cookies名字
+                .and()
+                .cors()
+                .and()
+                .csrf().disable();
+
+        //http.addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class).csrf().disable();
+    }
+}
diff --git a/src/main/java/com/tianbo/warehouse/security/handel/MyAuthenticationFailHandler.java b/src/main/java/com/tianbo/warehouse/security/handel/MyAuthenticationFailHandler.java
new file mode 100644
index 0000000..9cf5c8a
--- /dev/null
+++ b/src/main/java/com/tianbo/warehouse/security/handel/MyAuthenticationFailHandler.java
@@ -0,0 +1,69 @@
+package com.tianbo.warehouse.security.handel;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.tianbo.warehouse.security.config.SecurityProperties;
+import com.tianbo.warehouse.security.model.LoginType;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.DefaultRedirectStrategy;
+import org.springframework.security.web.RedirectStrategy;
+import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * 自定义登录失败处理器
+ * Created by mrz.
+ */
+@Component
+public class MyAuthenticationFailHandler extends SimpleUrlAuthenticationFailureHandler {
+    protected final Log logger = LogFactory.getLog(this.getClass());
+    /**
+     * json 转换工具类
+     */
+    @Autowired
+    private ObjectMapper objectMapper;
+
+    private String defaultFailureUrl;
+    private boolean forwardToDestination = false;
+    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
+
+    @Autowired
+    private SecurityProperties securityProperties;
+
+    @Override
+    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
+
+        logger.info("登录失败");
+        //如果securityProperties中配置的是JSON就返回JSON
+        if (LoginType.JSON.equals(securityProperties.getBrowser().getLoginType())){
+            //设置状态码
+            response.setStatus(HttpStatus.UNAUTHORIZED.value());
+            //将 登录失败 信息打包成json格式返回
+            response.setContentType("application/json;charset=UTF-8");
+            response.getWriter().write(objectMapper.writeValueAsString(exception));
+        }
+
+        if (this.defaultFailureUrl == null) {
+            this.logger.debug("No failure URL set, sending 401 Unauthorized error");
+            response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());
+        } else {
+            this.saveException(request, exception);
+            if (this.forwardToDestination) {
+                this.logger.debug("Forwarding to " + this.defaultFailureUrl);
+                request.getRequestDispatcher(this.defaultFailureUrl).forward(request, response);
+            } else {
+                this.logger.debug("Redirecting to " + this.defaultFailureUrl);
+                this.redirectStrategy.sendRedirect(request, response, this.defaultFailureUrl);
+            }
+        }
+
+    }
+}
diff --git a/src/main/java/com/tianbo/warehouse/security/handel/MyAuthenticationSuccessHandler.java b/src/main/java/com/tianbo/warehouse/security/handel/MyAuthenticationSuccessHandler.java
new file mode 100644
index 0000000..eae111d
--- /dev/null
+++ b/src/main/java/com/tianbo/warehouse/security/handel/MyAuthenticationSuccessHandler.java
@@ -0,0 +1,67 @@
+package com.tianbo.warehouse.security.handel;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.tianbo.warehouse.security.model.LoginType;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import com.tianbo.warehouse.security.config.SecurityProperties;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
+import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
+import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
+import org.springframework.security.web.savedrequest.RequestCache;
+import org.springframework.security.web.savedrequest.SavedRequest;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * 登录成功后的返回处理
+ */
+@Component
+public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler{
+    protected final Log logger = LogFactory.getLog(this.getClass());
+
+    @Autowired
+    private ObjectMapper objectMapper;
+
+    private RequestCache requestCache = new HttpSessionRequestCache();
+
+    @Autowired
+    private SecurityProperties securityProperties;
+
+    @Override
+    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException {
+        logger.info("登录成功");
+        if (LoginType.JSON.equals(securityProperties.getBrowser().getLoginType())){
+            //将 authention 信息打包成json格式返回
+            response.setContentType("application/json;charset=UTF-8");
+            response.getWriter().write(objectMapper.writeValueAsString(authentication));
+        }else {
+            //走原来的处理流程
+            SavedRequest savedRequest = this.requestCache.getRequest(request, response);
+            if (savedRequest == null) {
+                super.onAuthenticationSuccess(request, response, authentication);
+            } else {
+                String targetUrlParameter = this.getTargetUrlParameter();
+                if (!this.isAlwaysUseDefaultTargetUrl() && (targetUrlParameter == null || !StringUtils.hasText(request.getParameter(targetUrlParameter)))) {
+                    this.clearAuthenticationAttributes(request);
+                    String targetUrl = savedRequest.getRedirectUrl();
+                    this.logger.debug("Redirecting to DefaultSavedRequest Url: " + targetUrl);
+                    this.getRedirectStrategy().sendRedirect(request, response, targetUrl);
+                } else {
+                    this.requestCache.removeRequest(request, response);
+                    super.onAuthenticationSuccess(request, response, authentication);
+                }
+            }
+        }
+
+    }
+
+
+}
diff --git a/src/main/java/com/tianbo/warehouse/security/model/BrowserProperties.java b/src/main/java/com/tianbo/warehouse/security/model/BrowserProperties.java
new file mode 100644
index 0000000..86c8ab6
--- /dev/null
+++ b/src/main/java/com/tianbo/warehouse/security/model/BrowserProperties.java
@@ -0,0 +1,34 @@
+package com.tianbo.warehouse.security.model;
+
+/**
+ * browser(浏览器)配置文件里的: fantJ.security.browser.loginPage 属性类
+ *
+ */
+public class BrowserProperties {
+    /**
+     *  loginPage 默认值  是login.html
+     *  如果 application.properties 里有对 fantJ.security.browser.loginPage 的声明,则获取该值
+     */
+    private String loginPage = "/browser-login.html";
+
+    /**
+     * 默认 返回 json 类型,声明登录返回格式
+     */
+    private LoginType loginType = LoginType.JSON;
+
+    public String getLoginPage() {
+        return loginPage;
+    }
+
+    public void setLoginPage(String loginPage) {
+        this.loginPage = loginPage;
+    }
+
+    public LoginType getLoginType() {
+        return loginType;
+    }
+
+    public void setLoginType(LoginType loginType) {
+        this.loginType = loginType;
+    }
+}
diff --git a/src/main/java/com/tianbo/warehouse/security/model/LoginType.java b/src/main/java/com/tianbo/warehouse/security/model/LoginType.java
new file mode 100644
index 0000000..a4b5eb1
--- /dev/null
+++ b/src/main/java/com/tianbo/warehouse/security/model/LoginType.java
@@ -0,0 +1,6 @@
+package com.tianbo.warehouse.security.model;
+
+public enum LoginType {
+    REDIRECT,
+    JSON
+}
diff --git a/src/main/java/com/tianbo/warehouse/service/imp/UserServiceImpl.java b/src/main/java/com/tianbo/warehouse/service/imp/UserServiceImpl.java
index 88b5ffa..cb3a2b2 100644
--- a/src/main/java/com/tianbo/warehouse/service/imp/UserServiceImpl.java
+++ b/src/main/java/com/tianbo/warehouse/service/imp/UserServiceImpl.java
@@ -51,14 +51,9 @@ public class UserServiceImpl implements UserService{
         List<USERS> list = usersMapper.selectAllUser();
         for (USERS user: list) {
             List<PERMISSION> permissionList = permissionMapper.findByUserId(user.getUserId());
-            if (permissionList!=null && permissionList.size()>0){
-                user.setPermissions(permissionList);
-            }
-
+            user.setPermissions(permissionList);
             List<ROLE> roleList = roleMapper.findRolesByUserId(user.getUserId());
-            if (roleList!=null && roleList.size()>0){
-                user.setRoles(roleList);
-            }
+            user.setRoles(roleList);
         }
         return list;
     }
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index e4d626c..413282f 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -2,29 +2,46 @@
 #服务端口
 server.port=7003
 server.servlet.context-path=${SERVER_CONTEXTPATH:}
-#eureka主机名,会在控制页面中显示
-eureka.instance.hostname=${spring.cloud.client.ip-address}
-#eureka服务器页面中status的请求路径
-eureka.instance.status-page-url=http://${eureka.instance.hostname}:${server.port}/index
-#eureka注册中心服务器地址
-eureka.client.service-url.defaultZone=http://10.50.3.82:19527/eureka/
+
+
 #服务名
-spring.application.name=imf-warehouse-reader
-eureka.instance.prefer-ip-address=true
-eureka.instance.instance-id=${spring.cloud.client.ip-address}:${server.port}
-eureka.client.registry-fetch-interval-seconds=30
-eureka.instance.lease-renewal-interval-in-seconds=15
-eureka.instance.lease-expiration-duration-in-seconds=45
+spring.application.name=tianbo.base.dev.devkit
+
 
 #springcloud 基本配置
 
+#eureka主机名,会在控制页面中显示
+spring.cloud.features.enabled=false
+spring.cloud.discovery.enabled=false
+spring.cloud.service-registry.auto-registration.enabled=false
+#eureka.instance.hostname=${spring.cloud.client.ip-address}
+#eureka服务器页面中status的请求路径
+#eureka.instance.status-page-url=http://${eureka.instance.hostname}:${server.port}/index
+#eureka注册中心服务器地址
+#eureka.client.service-url.defaultZone=http://10.50.3.82:19527/eureka/
+#eureka.instance.prefer-ip-address=true
+#eureka.instance.instance-id=${spring.cloud.client.ip-address}:${server.port}
+#eureka.client.registry-fetch-interval-seconds=30
+#eureka.instance.lease-renewal-interval-in-seconds=15
+#eureka.instance.lease-expiration-duration-in-seconds=45
 
-#spring.datasource.name=CGOETL
+#spring.datasource oracle
 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
-spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
-spring.datasource.url=jdbc:oracle:thin:@10.50.3.68:1521:CGODW
-spring.datasource.username=CGOETL
-spring.datasource.password=1q2w3e4r
+#spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
+#spring.datasource.url=jdbc:oracle:thin:@10.50.3.68:1521:CGODW
+#spring.datasource.username=CGOETL
+#spring.datasource.password=1q2w3e4r
+
+#spring datasource mysql
+spring.datasource.url=jdbc:mysql://127.0.0.1:3307/statistics
+spring.datasource.username=root
+spring.datasource.password=
+spring.datasource.driver-class-name=com.mysql.jdbc.Driver
+spring.datasource.max-idle=10
+spring.datasource.max-wait=10000
+spring.datasource.min-idle=5
+spring.datasource.initial-size=5
+
 #配置初始化大小/最小/最大
 spring.datasource.druid.initial-size=1
 spring.datasource.druid.min-idle=1
@@ -35,25 +52,31 @@ spring.datasource.druid.max-wait=60000
 spring.datasource.druid.min-evictable-idle-time-millis=300000
 #间隔多久进行一次检测,检测需要关闭的空闲连接
 spring.datasource.druid.time-between-eviction-runs-millis=60000
-spring.datasource.druid.validation-query=SELECT 'x' FROM DUAL
+#oracle
+#spring.datasource.druid.validation-query=SELECT 'x' FROM DUAL
+#mysql
+spring.datasource.druid.validation-query=SELECT 1 FROM DUAL
 spring.datasource.druid.test-while-idle=true
 spring.datasource.druid.test-on-borrow=false
 spring.datasource.druid.test-on-return=false
 spring.datasource.druid.default-auto-commit=true
 
-#security配置
-trace=true
+
 
 mybatis.mapper-locations=classpath:mapping/*.xml
 mybatis.type-aliases-package=com.tianbo.warehouse.model
-logging.level.com.tianbo.warehouse.dao=DEBUG
-logging.level.org.springframework.security =debug
-debug=true
-pagehelper.helper-dialect=oracle
+
+
+
+pagehelper.helper-dialect=mysql
 #pagehelper.auto-dialect=true
 #pagehelper.auto-runtime-dialect=true
 pagehelper.reasonable=true
 pagehelper.support-methods-arguments=true
 pagehelper.params=count=countSql
 
-
+#debug配置
+trace=false
+logging.level.com.tianbo.warehouse.dao=DEBUG
+logging.level.org.springframework.security =trace
+debug=false
\ No newline at end of file
diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html
index 8b7fa77..feab054 100644
--- a/src/main/resources/static/index.html
+++ b/src/main/resources/static/index.html
@@ -30,23 +30,7 @@
     </div>
 </nav>
 <div class="container">
-
-    <div class="starter-template">
-        <p th:if="${param.logout}" class="bg-warning">已成功注销</p><!-- 1 -->
-        <p th:if="${param.error}" class="bg-danger">有错误,请重试</p> <!-- 2 -->
-        <h2>使用账号密码登录</h2>
-        <form name="form" th:action="@{/login}" action="/login" method="POST"> <!-- 3 -->
-            <div class="form-group">
-                <label for="username">账号</label>
-                <input type="text" class="form-control" name="username" value="" placeholder="账号" />
-            </div>
-            <div class="form-group">
-                <label for="password">密码</label>
-                <input type="password" class="form-control" name="password" placeholder="密码" />
-            </div>
-            <input type="submit" id="login" value="Login" class="btn btn-primary" />
-        </form>
-    </div>
+    welcom
 </div>
 </body>
 </html>
\ No newline at end of file
--
libgit2 0.24.0