From 34fd8233bab7c8a00211644579942086deea722f Mon Sep 17 00:00:00 2001
From: zhaoxiaohao <913652501@qq.com>
Date: Mon, 10 Aug 2020 18:23:41 +0800
Subject: [PATCH] 添加 token 失效和token 超时的功能
---
kidgrow-web/kidgrow-web-manager/src/main/resources/static/pages/opration/doctor_form.html | 75 ++++++++++--------
kidgrow-commons/kidgrow-authclient-spring-boot-starter/src/main/java/com/kidgrow/authclient/store/CustomRedisTokenStore.java | 12 +-
kidgrow-uaa/kidgrow-uaa-server/src/main/java/com/kidgrow/oauth2/config/SecurityConfig.java | 27 ++++++
kidgrow-uaa/kidgrow-uaa-server/src/main/java/com/kidgrow/oauth2/handler/SingleTokenServices.java | 9 +-
kidgrow-uaa/kidgrow-uaa-server/src/main/java/com/kidgrow/oauth2/config/AuthorizationServerConfig.java | 46 ++++++++++-
kidgrow-web/kidgrow-web-manager/src/main/resources/static/module/apiUrl.js | 1
kidgrow-web/kidgrow-web-manager/src/main/resources/static/assets/js/common.js | 15 +++
kidgrow-web/kidgrow-web-manager/src/main/resources/static/module/admin.js | 17 +++
8 files changed, 148 insertions(+), 54 deletions(-)
diff --git a/kidgrow-commons/kidgrow-authclient-spring-boot-starter/src/main/java/com/kidgrow/authclient/store/CustomRedisTokenStore.java b/kidgrow-commons/kidgrow-authclient-spring-boot-starter/src/main/java/com/kidgrow/authclient/store/CustomRedisTokenStore.java
index 0976a50..f47a4a9 100644
--- a/kidgrow-commons/kidgrow-authclient-spring-boot-starter/src/main/java/com/kidgrow/authclient/store/CustomRedisTokenStore.java
+++ b/kidgrow-commons/kidgrow-authclient-spring-boot-starter/src/main/java/com/kidgrow/authclient/store/CustomRedisTokenStore.java
@@ -291,12 +291,12 @@
}
conn.rPush(clientId, serializedAccessToken);
if (token.getExpiration() != null) {
- int seconds = token.getExpiresIn();
- conn.expire(accessKey, seconds);
- conn.expire(authKey, seconds);
- conn.expire(authToAccessKey, seconds);
- conn.expire(clientId, seconds);
- conn.expire(approvalKey, seconds);
+// int seconds = token.getExpiresIn();
+// conn.expire(accessKey, seconds);
+// conn.expire(authKey, seconds);
+// conn.expire(authToAccessKey, seconds);
+// conn.expire(clientId, seconds);
+// conn.expire(approvalKey, seconds);
}
//关闭Token刷新
// OAuth2RefreshToken refreshToken = token.getRefreshToken();
diff --git a/kidgrow-uaa/kidgrow-uaa-server/src/main/java/com/kidgrow/oauth2/config/AuthorizationServerConfig.java b/kidgrow-uaa/kidgrow-uaa-server/src/main/java/com/kidgrow/oauth2/config/AuthorizationServerConfig.java
index aca478e..84121f2 100644
--- a/kidgrow-uaa/kidgrow-uaa-server/src/main/java/com/kidgrow/oauth2/config/AuthorizationServerConfig.java
+++ b/kidgrow-uaa/kidgrow-uaa-server/src/main/java/com/kidgrow/oauth2/config/AuthorizationServerConfig.java
@@ -3,19 +3,27 @@
import com.kidgrow.oauth2.handler.SingleTokenServices;
import com.kidgrow.oauth2.service.impl.RedisClientDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper;
import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
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.OAuth2Authentication;
import org.springframework.security.oauth2.provider.code.RandomValueAuthorizationCodeServices;
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
@@ -42,8 +50,9 @@
/**
* 注入authenticationManager 来支持 password grant type
*/
- @Autowired
- private AuthenticationManager authenticationManager;
+// @Autowired
+// private AuthenticationManager authenticationManager;
+
@Resource
private UserDetailsService userDetailsService;
@@ -69,6 +78,11 @@
@Autowired
private RandomValueAuthorizationCodeServices authorizationCodeServices;
+ @Autowired
+ private AuthenticationProvider daoAuhthenticationOauthProvider;
+ @Autowired
+ private SingleTokenServices tokenServices;
+
/**
* 配置身份认证器,配置认证方式,TokenStore,TokenGranter,OAuth2RequestFactory
@@ -88,15 +102,35 @@
}
endpoints
//扩展tokenServices
-// .tokenServices(tokenServices(endpoints))
.tokenServices(KidgrowTokenServices())
- .authenticationManager(authenticationManager)
+ .authenticationManager(new AuthenticationManager(){
+ @Override
+ public Authentication authenticate(Authentication authentication) throws AuthenticationException {
+ String token = (String) authentication.getPrincipal();
+ OAuth2Authentication auth = tokenServices.loadAuthentication(token);
+ if (auth == null) {
+ throw new InvalidTokenException("Invalid token: " + token);
+ }
+ return daoAuhthenticationOauthProvider.authenticate(authentication);
+ }
+ })
.userDetailsService(userDetailsService)
-// .tokenStore(tokenStore)
.authorizationCodeServices(authorizationCodeServices)
.exceptionTranslator(webResponseExceptionTranslator);
- }
+ }
+ @Bean
+ DaoAuthenticationProvider daoAuthenticationProvider(){
+
+ DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
+
+ daoAuthenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());
+
+ daoAuthenticationProvider.setUserDetailsService(userDetailsService);
+
+ return daoAuthenticationProvider;
+
+ }
@Bean
@Primary
diff --git a/kidgrow-uaa/kidgrow-uaa-server/src/main/java/com/kidgrow/oauth2/config/SecurityConfig.java b/kidgrow-uaa/kidgrow-uaa-server/src/main/java/com/kidgrow/oauth2/config/SecurityConfig.java
index 105d3ff..03c15b8 100644
--- a/kidgrow-uaa/kidgrow-uaa-server/src/main/java/com/kidgrow/oauth2/config/SecurityConfig.java
+++ b/kidgrow-uaa/kidgrow-uaa-server/src/main/java/com/kidgrow/oauth2/config/SecurityConfig.java
@@ -1,6 +1,7 @@
package com.kidgrow.oauth2.config;
import com.kidgrow.common.constant.SecurityConstants;
+//import com.kidgrow.oauth2.handler.InMemoryAuthenticationProvider;
import com.kidgrow.oauth2.mobile.MobileAuthenticationSecurityConfig;
import com.kidgrow.oauth2.openid.OpenIdAuthenticationSecurityConfig;
import com.kidgrow.common.config.DefaultPasswordConfig;
@@ -9,19 +10,26 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.ProviderManager;
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
+import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutHandler;
+import org.springframework.security.web.header.HeaderWriterFilter;
+import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
import javax.annotation.Resource;
+import java.util.Arrays;
/**
@@ -63,6 +71,9 @@
@Autowired
private MobileAuthenticationSecurityConfig mobileAuthenticationSecurityConfig;
+// @Autowired
+// InMemoryAuthenticationProvider inMemoryAuthenticationProvider;
+
/**
* 这一步的配置是必不可少的,否则SpringBoot会自动配置一个AuthenticationManager,覆盖掉内存中的用户
* @return 认证管理对象
@@ -72,6 +83,22 @@
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
+// @Bean
+// @Override
+// public AuthenticationManager authenticationManagerBean() throws Exception {
+// // 认证管理器中只提供我需要的两个第一个是自定义认证,第二个是数据库认证,需要经过两层认证才能通过,默认的
+//
+// // 构造函数不提供自定义认证Provider,那么默认提供DaoAuthenticationProvider
+//
+// ProviderManager authenticationManager = new ProviderManager(Arrays.asList(inMemoryAuthenticationProvider, daoAuthenticationProvider()));
+//
+// // 不擦除认证密码,擦除会导致TokenBasedRememberMeServices因为找不到Credentials再调用UserDetailsService而抛出UsernameNotFoundException
+//
+// authenticationManager.setEraseCredentialsAfterAuthentication(false);
+//
+// return authenticationManager;
+// }
+
@Override
protected void configure(HttpSecurity http) throws Exception {
diff --git a/kidgrow-uaa/kidgrow-uaa-server/src/main/java/com/kidgrow/oauth2/handler/SingleTokenServices.java b/kidgrow-uaa/kidgrow-uaa-server/src/main/java/com/kidgrow/oauth2/handler/SingleTokenServices.java
index 1c97969..4fe6897 100644
--- a/kidgrow-uaa/kidgrow-uaa-server/src/main/java/com/kidgrow/oauth2/handler/SingleTokenServices.java
+++ b/kidgrow-uaa/kidgrow-uaa-server/src/main/java/com/kidgrow/oauth2/handler/SingleTokenServices.java
@@ -19,6 +19,7 @@
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.token.*;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
+//import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
@@ -30,7 +31,7 @@
@Deprecated
public class SingleTokenServices implements AuthorizationServerTokenServices, ResourceServerTokenServices, ConsumerTokenServices, InitializingBean {
private int refreshTokenValiditySeconds = 2592000;
- private int accessTokenValiditySeconds = 3600;//43200
+ private int accessTokenValiditySeconds = 10800;//43200 //登录时,给的默认值;一段时间后,用的查询数据库中的oauth_client_details的表的access_token_validity;
private boolean supportRefreshToken = false;
private boolean reuseRefreshToken = true;
private TokenStore tokenStore;
@@ -166,14 +167,14 @@
public OAuth2Authentication loadAuthentication(String accessTokenValue) throws AuthenticationException, InvalidTokenException {
OAuth2AccessToken accessToken = this.tokenStore.readAccessToken(accessTokenValue);
if (accessToken == null) {
- throw new InvalidTokenException("Invalid access token: " + accessTokenValue);
+ throw new InvalidTokenException("Invalid access token:1 " + accessTokenValue);
} else if (accessToken.isExpired()) {
this.tokenStore.removeAccessToken(accessToken);
throw new InvalidTokenException("Access token expired: " + accessTokenValue);
} else {
OAuth2Authentication result = this.tokenStore.readAuthentication(accessToken);
if (result == null) {
- throw new InvalidTokenException("Invalid access token: " + accessTokenValue);
+ throw new InvalidTokenException("Invalid access token:2 " + accessTokenValue);
} else {
if (this.clientDetailsService != null) {
String clientId = result.getOAuth2Request().getClientId();
@@ -193,7 +194,7 @@
public String getClientId(String tokenValue) {
OAuth2Authentication authentication = this.tokenStore.readAuthentication(tokenValue);
if (authentication == null) {
- throw new InvalidTokenException("Invalid access token: " + tokenValue);
+ throw new InvalidTokenException("Invalid access token:3 " + tokenValue);
} else {
OAuth2Request clientAuth = authentication.getOAuth2Request();
if (clientAuth == null) {
diff --git a/kidgrow-web/kidgrow-web-manager/src/main/resources/static/assets/js/common.js b/kidgrow-web/kidgrow-web-manager/src/main/resources/static/assets/js/common.js
index 5ffbfdb..cbad2c2 100644
--- a/kidgrow-web/kidgrow-web-manager/src/main/resources/static/assets/js/common.js
+++ b/kidgrow-web/kidgrow-web-manager/src/main/resources/static/assets/js/common.js
@@ -294,9 +294,18 @@
function permissionsInput(res,config) {
if(!strUtil.isEmpty(res)&&res.code==401){
config.removeToken();
- layer.msg('登录过期', {icon: 2, time: 1500}, function () {
- location.replace('/login.html');
- }, 1000);
+ console.log(res);
+ debugger
+ if(res.msg.includes("Access token expired")){
+ layer.msg('登录过期11', {icon: 2, time: 1500}, function () {
+ location.replace('/login.html');
+ }, 5000);
+ }else{
+ layer.msg('您的账号在其他地方登陆,请重新登录或修改密码', {icon: 2, time: 1500}, function () {
+ location.replace('/login.html');
+ }, 5000);
+ }
+
return;
}
var needpPermissions = $(".permissions");
diff --git a/kidgrow-web/kidgrow-web-manager/src/main/resources/static/module/admin.js b/kidgrow-web/kidgrow-web-manager/src/main/resources/static/module/admin.js
index 46ba519..4f39373 100644
--- a/kidgrow-web/kidgrow-web-manager/src/main/resources/static/module/admin.js
+++ b/kidgrow-web/kidgrow-web-manager/src/main/resources/static/module/admin.js
@@ -128,9 +128,20 @@
if (jsonRs) {
if (jsonRs.code == 401) {
config.removeToken();
- layer.msg('登录过期', {icon: 2, time: 1500}, function () {
- location.replace('/login.html');
- }, 1000);
+ // var json=JSON.stringify(jsonRs)
+ // console.log(json,"jsonjsonjsonjsonjsonjsonjson")
+ debugger
+ var msg=jsonRs.msg;
+ if(msg.includes("Access token expired")){
+ layer.msg('登录过期', {icon: 2, time: 1500}, function () {
+ location.replace('/login.html');
+ }, 5000);
+ }else if(msg.includes("Invalid access token")){
+ layer.msg('您的账号在其他地方登陆,请重新登录或修改密码', {icon: 2, time: 1500}, function () {
+ location.replace('/login.html');
+ }, 5000);
+ }
+
return;
} else if (jsonRs.code == 403) {
layer.msg('没有权限', {icon: 2});
diff --git a/kidgrow-web/kidgrow-web-manager/src/main/resources/static/module/apiUrl.js b/kidgrow-web/kidgrow-web-manager/src/main/resources/static/module/apiUrl.js
index cbd2e25..d0ea846 100644
--- a/kidgrow-web/kidgrow-web-manager/src/main/resources/static/module/apiUrl.js
+++ b/kidgrow-web/kidgrow-web-manager/src/main/resources/static/module/apiUrl.js
@@ -2,5 +2,6 @@
// var my_api_server_url = 'http://192.168.2.240:8888/';
var my_api_server_url = 'http://127.0.0.1:8888/';
// var my_api_server_url = 'http://uat-zuul.kidgrow.cloud/';
+// var my_api_server_url = 'https://zuul.kidgrow.cloud/';
//var my_api_server_url = 'http://123.57.164.62:8888/';
diff --git a/kidgrow-web/kidgrow-web-manager/src/main/resources/static/pages/opration/doctor_form.html b/kidgrow-web/kidgrow-web-manager/src/main/resources/static/pages/opration/doctor_form.html
index ba26922..0aca3c9 100644
--- a/kidgrow-web/kidgrow-web-manager/src/main/resources/static/pages/opration/doctor_form.html
+++ b/kidgrow-web/kidgrow-web-manager/src/main/resources/static/pages/opration/doctor_form.html
@@ -233,7 +233,7 @@
});
// 回显user数据
var doctor = admin.getTempData('t_doctor');
- if (doctor.roles) {
+ if (doctor!=null&&doctor.roles) {
formSelects.value('roleId', doctor.roles);
}
@@ -252,7 +252,7 @@
// 正则验证格式
eval("var reg = /^1[34578]\\d{9}$/;");
- var flag=RegExp(reg).test(content)
+ var flag = RegExp(reg).test(content)
return flag;
}
//判断用户名是否被使用
@@ -367,7 +367,7 @@
//职称添加数据
var getZhiCheng = function () {
admin.req('api-user/sysdictionaries/findAll', JSON.stringify({
- dictionariesClassId: "1248150699682988034"
+ dictionariesClassId: "DOCTOR_RANK"
}), function (data) {
layer.closeAll('loading');
if (0 === data.code) {
@@ -459,7 +459,7 @@
$("#username").blur(function () {
username_is_usered("username");
})
-
+
//医生类型的选择事件
// form.on('select(doctorType)', function (data) {
// // console.log("eeeeeeeeeeeeeeeee");
@@ -476,14 +476,14 @@
// })
};
$("#doctorTel-add").blur(function () {
- $("#username").val($("#doctorTel-add").val())
- var doctorTel_add = $("#doctorTel-add").val();
- debugger
- if (!validatorTel(doctorTel_add)) {
- layer.msg("请输入正确的手机号");
- }
- username_is_usered("username");
- })
+ $("#username").val($("#doctorTel-add").val())
+ var doctorTel_add = $("#doctorTel-add").val();
+ debugger
+ if (!validatorTel(doctorTel_add)) {
+ layer.msg("请输入正确的手机号");
+ }
+ username_is_usered("username");
+ })
//自动完成-医院名称
autocomplete.render({
elem: $('#hospitalName')[0],
@@ -502,28 +502,39 @@
form.on('select(doctorType)', function (data) {
var doctor = admin.getTempData('t_doctor');
var doctorType = $('#doctorType').val();
- if (doctor.doctorType == 2 && doctorType == 2) {
- $(".account").hide();
- $("#roleId_div").hide()
- } else if (doctor.doctorType == 2 && doctorType != 2) {
- $(".account").show();
- $("#password_div").show();
- $("#passwordSure_div").show();
- $("#roleId_div").show()
- if (doctor.username == null) {
- $("#username").val(doctor.doctorTel);
- form.render();
+ if (doctor == null) {
+ if (doctorType != 2) {
+ $(".account").show();
+ $("#password_div").show();
+ $("#passwordSure_div").show();
+ $("#roleId_div").show()
+ }else{
+ $(".account").hide();
+ $("#roleId_div").hide()
}
- } else if (doctor.doctorType != 2 && doctorType != 2) {
- $(".account").show();
- $("#password_div").hide();
- $("#passwordSure_div").hide();
- $("#roleId_div").show()
- } else if (doctor.doctorType != 2 && doctorType == 2) {
- $(".account").hide();
- $("#roleId_div").hide()
+ } else {
+ if (doctor.doctorType == 2 && doctorType == 2) {
+ $(".account").hide();
+ $("#roleId_div").hide()
+ } else if (doctor.doctorType == 2 && doctorType != 2) {
+ $(".account").show();
+ $("#password_div").show();
+ $("#passwordSure_div").show();
+ $("#roleId_div").show()
+ if (doctor.username == null) {
+ $("#username").val(doctor.doctorTel);
+ form.render();
+ }
+ } else if (doctor.doctorType != 2 && doctorType != 2) {
+ $(".account").show();
+ $("#password_div").hide();
+ $("#passwordSure_div").hide();
+ $("#roleId_div").show()
+ } else if (doctor.doctorType != 2 && doctorType == 2) {
+ $(".account").hide();
+ $("#roleId_div").hide()
+ }
}
-
})
//数据的回显
var doctor = admin.getTempData('t_doctor');
--
Gitblit v1.8.0