增加了操作员登陆实现
diff --git a/sql/init_test.sql b/sql/init_test.sql
index c13e4cf..3a210ae 100644
--- a/sql/init_test.sql
+++ b/sql/init_test.sql
@@ -1,4 +1,15 @@
 insert into tb_apiclient(appid, secret, status, roles)
 values ('100001', 'oUw2NmA09ficiVWD4TUQLDOkPyzQa3VzbjjsW0B2qTk=', 'normal', 'ROLE_THIRD_ADMIN');
+INSERT INTO tb_operator(
+	operid, closedate, opendate, opercode, opername, operpwd, opertype, status)
+	VALUES ('LOR2IwRkbOjp+sVG9KR2BpHZbwGKepS4', '20500101', '20190101', 'system', '系统管理员', '$2a$10$Ex9xp11.vCaD8D0a7ahiUOKqDij1TcCUBwRAmrqXeDvAkmzLibn4.', '', 'normal');
+
+INSERT INTO tb_role(
+	role_id, createtime, editflag, lastsaved, role_code, role_desc, role_name)
+	VALUES ('d1yctWs5+ks0iQN3m9bUvRHus6HbKbrs', '20190101000000', 0, '', 'ROLE_ADMIN', '超级管理员', '超级管理员');
+
+INSERT INTO tb_oper_role(
+	id, operid, role_id)
+	VALUES ('1', 'LOR2IwRkbOjp+sVG9KR2BpHZbwGKepS4', 'd1yctWs5+ks0iQN3m9bUvRHus6HbKbrs');
 
 commit;
\ No newline at end of file
diff --git a/src/main/java/com/supwisdom/dlpay/framework/domain/TOperator.java b/src/main/java/com/supwisdom/dlpay/framework/domain/TOperator.java
index 1da944b..83885d3 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/domain/TOperator.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/domain/TOperator.java
@@ -26,7 +26,7 @@
   @Column(name="OPERNAME", nullable = false, length = 100)
   private String opername;
 
-  @Column(name="OPERPWD", nullable = false, length = 32)
+  @Column(name="OPERPWD", nullable = false, length = 80)
   private String operpwd;
 
   @Column(name="STATUS", nullable = false, length = 32)
diff --git a/src/main/kotlin/com/supwisdom/dlpay/framework/controller/security_controller.kt b/src/main/kotlin/com/supwisdom/dlpay/framework/controller/security_controller.kt
index 3e13e8b..e1c06aa 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/framework/controller/security_controller.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/framework/controller/security_controller.kt
@@ -13,10 +13,13 @@
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.http.HttpStatus
 import org.springframework.http.ResponseEntity
+import org.springframework.security.core.context.SecurityContextHolder
+import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler
 import org.springframework.social.connect.web.HttpSessionSessionStrategy
 import org.springframework.stereotype.Controller
 import org.springframework.web.bind.annotation.*
 import org.springframework.web.context.request.ServletWebRequest
+import sun.plugin.liveconnect.SecurityContextHelper
 import java.util.*
 import javax.imageio.ImageIO
 import javax.servlet.http.HttpServletRequest
@@ -117,15 +120,23 @@
 @Controller
 class WebHomeController {
 
-    @GetMapping("/{index}")
+    @GetMapping("/index")
     fun homeView() = "index"
 
     @GetMapping("/login")
     fun loginView() = "login"
 
     @PostMapping("/login/form")
-    fun loginForm(form: LoginForm): String {
-        println(form.username)
-        return "index"
+    fun loginForm(form: LoginForm): ResponseEntity<Any> {
+        return ResponseEntity.ok(ResponseBodyBuilder.create()
+                .success())
+    }
+
+    @GetMapping("/logout")
+    fun logout(request: HttpServletRequest, response: HttpServletResponse): String {
+        SecurityContextHolder.getContext().authentication?.also {
+            SecurityContextLogoutHandler().logout(request, response, it)
+        }
+        return "redirect:/login?logout"
     }
 }
diff --git a/src/main/kotlin/com/supwisdom/dlpay/security.kt b/src/main/kotlin/com/supwisdom/dlpay/security.kt
index 6fd99ab..7998f23 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/security.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/security.kt
@@ -2,23 +2,38 @@
 
 import com.supwisdom.dlpay.framework.core.JwtConfig
 import com.supwisdom.dlpay.framework.core.JwtTokenUtil
+import com.supwisdom.dlpay.framework.dao.OperRoleDao
+import com.supwisdom.dlpay.framework.dao.OperatorDao
 import com.supwisdom.dlpay.framework.security.ValidateCodeSecurityConfig
+import com.supwisdom.dlpay.framework.util.StringUtil
 import org.jose4j.jwt.consumer.InvalidJwtException
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.context.annotation.Bean
 import org.springframework.context.annotation.Configuration
 import org.springframework.core.annotation.Order
 import org.springframework.http.HttpStatus
+import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException
+import org.springframework.security.authentication.AuthenticationProvider
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
+import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider
+import org.springframework.security.authentication.jaas.AuthorityGranter
 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.core.Authentication
+import org.springframework.security.core.AuthenticationException
+import org.springframework.security.core.GrantedAuthority
+import org.springframework.security.core.authority.AuthorityUtils
 import org.springframework.security.core.authority.SimpleGrantedAuthority
 import org.springframework.security.core.context.SecurityContextHolder
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
+import org.springframework.security.web.authentication.AuthenticationFailureHandler
+import org.springframework.security.web.authentication.AuthenticationSuccessHandler
 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
 import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl
 import org.springframework.security.web.util.matcher.AntPathRequestMatcher
+import org.springframework.stereotype.Component
 import org.springframework.web.filter.OncePerRequestFilter
 import javax.servlet.FilterChain
 import javax.servlet.http.HttpServletRequest
@@ -45,21 +60,50 @@
     }
 }
 
+@Component
+class OperatorAuthenticationProvider : AuthenticationProvider {
+    @Autowired
+    lateinit var operatorDao: OperatorDao
+
+    @Autowired
+    lateinit var operRoleDao: OperRoleDao
+
+    override fun authenticate(authentication: Authentication?): Authentication {
+        return authentication?.let {
+            val oper = operatorDao.findByOpercode(it.name)
+                    ?: throw AuthenticationCredentialsNotFoundException("操作员不存在或密码错误")
+            if (BCryptPasswordEncoder().matches(it.credentials.toString(), oper.password)) {
+                val roles = operRoleDao.getRolecodeByOperid(oper.operid)
+                if (roles.size > 0) {
+                    oper.authorities = roles.mapNotNull { role ->
+                        role?.let {
+                            SimpleGrantedAuthority(role)
+                        }
+                    }
+                } else {
+                    oper.authorities = listOf()
+                }
+                return UsernamePasswordAuthenticationToken(authentication.name, authentication.credentials,
+                        oper.authorities)
+            } else {
+                throw AuthenticationCredentialsNotFoundException("操作员不存在或密码错误")
+            }
+        } ?: throw AuthenticationCredentialsNotFoundException("操作员不存在或密码错误")
+    }
+
+    override fun supports(authentication: Class<*>?): Boolean {
+        return authentication?.equals(UsernamePasswordAuthenticationToken::class.java)
+                ?: false
+    }
+}
+
 @EnableWebSecurity
 class WebSecurityConfig {
 
-//    @Bean
-//    fun daoProvider(detailsService: UserDetailsService): DaoAuthenticationProvider {
-//        return DaoAuthenticationProvider().also {
-//            it.setUserDetailsService(detailsService)
-//        }
-//    }
-//
-//    @Bean
-//    fun providerManager(daoProvider: DaoAuthenticationProvider): ProviderManager {
-//        return ProviderManager(listOf(daoProvider))
-//    }
-
+    @Bean
+    fun passwordEncoder(): BCryptPasswordEncoder {
+        return BCryptPasswordEncoder()
+    }
 
     companion object {
         @Configuration
@@ -69,13 +113,13 @@
             @Autowired
             lateinit var jwtConfig: JwtConfig
 
-
             override fun configure(http: HttpSecurity) {
                 // 设置 API 访问权限管理
                 http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                         .and()
                         .addFilterAfter(ApiJwtAuthenticationFilter(JwtTokenUtil(jwtConfig)),
                                 UsernamePasswordAuthenticationFilter::class.java)
+                        .antMatcher("/api/**")
                         .authorizeRequests()
                         .antMatchers("/api/auth/**").permitAll()
                         .antMatchers("/api/notify/**").permitAll()
@@ -84,6 +128,7 @@
                         .antMatchers("/api/deposit/**").hasRole("THIRD_DEPOSIT")
                         .antMatchers("/api/user/**").hasRole("THIRD_ADMIN")
                         .antMatchers("/api/shop/**").hasRole("THIRD_SHOP")
+                        .anyRequest().hasRole("THIRD_COMMON")
                         .and()
                         .csrf().ignoringAntMatchers("/api/**")
             }
@@ -95,14 +140,10 @@
             lateinit var dataSource: DataSource
             @Autowired
             lateinit var validateCodeSecurityConfig: ValidateCodeSecurityConfig
-//            @Autowired
-//            lateinit var userDetailsService: OperatorDetailService
-//            @Autowired
-//            lateinit var myAuthenticationFailureHandler: AuthenticationFailureHandler
-//            @Autowired
-//            lateinit var myAuthenticationSuccessHandler: AuthenticationSuccessHandler
-//            @Autowired
-//            lateinit var myInvalidSessionStrategy: InvalidSessionStrategy
+            @Autowired
+            lateinit var authenticationFailureHandler: AuthenticationFailureHandler
+            @Autowired
+            lateinit var authenticationSuccessHandler: AuthenticationSuccessHandler
 
 
             @Bean
@@ -121,6 +162,7 @@
                         .antMatchers("/login", "/login/form").permitAll()
                         .antMatchers("/static/**").permitAll()
                         .antMatchers("/code/image").permitAll()
+                        .antMatchers("/**").hasAnyRole("USER", "ADMIN")
                         .anyRequest().authenticated()
                         .and()
                         .sessionManagement()
@@ -129,6 +171,8 @@
                         .formLogin()
                         .loginPage("/login")
                         .loginProcessingUrl("/login/form")
+                        .successHandler(authenticationSuccessHandler)
+                        .failureHandler(authenticationFailureHandler)
                         .and()
                         .logout()
                         .logoutRequestMatcher(AntPathRequestMatcher("/logout"))
diff --git a/src/test/kotlin/com/supwisdom/dlpay/password_test.kt b/src/test/kotlin/com/supwisdom/dlpay/password_test.kt
new file mode 100644
index 0000000..a89d759
--- /dev/null
+++ b/src/test/kotlin/com/supwisdom/dlpay/password_test.kt
@@ -0,0 +1,27 @@
+package com.supwisdom.dlpay
+
+import org.junit.Test
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
+import org.springframework.security.crypto.password.DelegatingPasswordEncoder
+import org.springframework.security.crypto.password.PasswordEncoder
+import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder
+import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder
+import java.util.*
+
+
+class PasswordTest {
+    private fun encodePassword(pswd: String) {
+        val encoders = HashMap<String, PasswordEncoder>()
+        encoders["bcrypt"] = BCryptPasswordEncoder()
+        encoders["pbkdf2"] = Pbkdf2PasswordEncoder()
+        encoders["scrypt"] = SCryptPasswordEncoder()
+        val passwordEncoder = DelegatingPasswordEncoder("bcrypt", encoders)
+        println(passwordEncoder.encode(pswd))
+
+    }
+
+    @Test
+    fun testPassword() {
+        encodePassword("123456")
+    }
+}
\ No newline at end of file