Merge pull request #5965 from EightMonth/springboot3_sas

新增token校验、客户端便捷工具类、修复登录缺乏租户信息、强退功能失效
pull/6161/head
JEECG 2024-03-12 14:27:11 +08:00 committed by GitHub
commit d684c09392
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 260 additions and 13 deletions

View File

@ -1,5 +1,6 @@
package org.jeecg.common.api; package org.jeecg.common.api;
import com.alibaba.fastjson.JSONObject;
import org.jeecg.common.system.vo.*; import org.jeecg.common.system.vo.*;
import java.util.List; import java.util.List;
@ -154,4 +155,11 @@ public interface CommonAPI {
*/ */
void updateUserDepart(String username,String orgCode,Integer loginTenantId); void updateUserDepart(String username,String orgCode,Integer loginTenantId);
/**
*
* @param username
* @return
*/
JSONObject setLoginTenant(String username);
} }

View File

@ -78,7 +78,7 @@ public interface CommonConstant {
/** 登录用户Shiro权限缓存KEY前缀 */ /** 登录用户Shiro权限缓存KEY前缀 */
public static String PREFIX_USER_SHIRO_CACHE = "shiro:cache:org.jeecg.config.shiro.ShiroRealm.authorizationCache:"; public static String PREFIX_USER_SHIRO_CACHE = "shiro:cache:org.jeecg.config.shiro.ShiroRealm.authorizationCache:";
/** 登录用户Token令牌缓存KEY前缀 */ /** 登录用户Token令牌缓存KEY前缀 */
String PREFIX_USER_TOKEN = "prefix_user_token:"; String PREFIX_USER_TOKEN = "token::jeecg-client::";
// /** Token缓存时间3600秒即一小时 */ // /** Token缓存时间3600秒即一小时 */
// int TOKEN_EXPIRE_TIME = 3600; // int TOKEN_EXPIRE_TIME = 3600;

View File

@ -12,13 +12,20 @@ import com.google.common.base.Joiner;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jakarta.servlet.ServletResponse; import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession; import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.CommonAPI;
import org.jeecg.common.api.vo.Result; import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.DataBaseConstant; import org.jeecg.common.constant.DataBaseConstant;
@ -31,7 +38,17 @@ import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.SpringContextUtils; import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.oConvertUtils; import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.security.utils.SecureUtil; import org.jeecg.config.security.utils.SecureUtil;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.core.*;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.context.AuthorizationServerContextHolder;
import org.springframework.security.oauth2.server.authorization.token.DefaultOAuth2TokenContext;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenContext;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator;
/** /**
* @Author Scott * @Author Scott
@ -45,6 +62,8 @@ public class JwtUtil {
public static final long EXPIRE_TIME = (7 * 12) * 60 * 60 * 1000; public static final long EXPIRE_TIME = (7 * 12) * 60 * 60 * 1000;
static final String WELL_NUMBER = SymbolConstant.WELL_NUMBER + SymbolConstant.LEFT_CURLY_BRACKET; static final String WELL_NUMBER = SymbolConstant.WELL_NUMBER + SymbolConstant.LEFT_CURLY_BRACKET;
public static final String DEFAULT_CLIENT = "jeecg-client";
/** /**
* *
* @param response * @param response
@ -80,10 +99,9 @@ public class JwtUtil {
public static boolean verify(String token, String username, String secret) { public static boolean verify(String token, String username, String secret) {
try { try {
// 根据密码生成JWT效验器 // 根据密码生成JWT效验器
Algorithm algorithm = Algorithm.HMAC256(secret); JwtDecoder jwtDecoder = SpringContextUtils.getBean(JwtDecoder.class);
JWTVerifier verifier = JWT.require(algorithm).withClaim("username", username).build();
// 效验TOKEN // 效验TOKEN
DecodedJWT jwt = verifier.verify(token); jwtDecoder.decode(token);
return true; return true;
} catch (Exception exception) { } catch (Exception exception) {
return false; return false;
@ -98,7 +116,7 @@ public class JwtUtil {
public static String getUsername(String token) { public static String getUsername(String token) {
try { try {
DecodedJWT jwt = JWT.decode(token); DecodedJWT jwt = JWT.decode(token);
LoginUser loginUser = SecureUtil.currentUser(); LoginUser loginUser = JSONObject.parseObject(jwt.getClaim("sub").asString(), LoginUser.class);
return loginUser.getUsername(); return loginUser.getUsername();
} catch (JWTDecodeException e) { } catch (JWTDecodeException e) {
return null; return null;
@ -106,7 +124,7 @@ public class JwtUtil {
} }
/** /**
* ,5min * ,5min
* *
* @param username * @param username
* @param secret * @param secret

View File

@ -0,0 +1,90 @@
package org.jeecg.config.security;
import lombok.AllArgsConstructor;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat;
import org.springframework.security.oauth2.server.authorization.settings.TokenSettings;
import org.springframework.stereotype.Component;
import java.time.Duration;
import java.util.Set;
/**
* spring authorization server 便
* @author eightmonth@qq.com
* @date 2024/3/7 11:22
*/
@Component
@AllArgsConstructor
public class ClientService {
private RegisteredClientRepository registeredClientRepository;
/**
* token
* accessToken
*/
public void updateTokenValidation(String clientId, Long accessTokenValidation, Long refreshTokenValidation){
RegisteredClient registeredClient = findByClientId(clientId);
RegisteredClient.Builder builder = RegisteredClient.from(registeredClient);
TokenSettings tokenSettings = TokenSettings.builder()
.idTokenSignatureAlgorithm(SignatureAlgorithm.RS256)
.accessTokenTimeToLive(Duration.ofSeconds(accessTokenValidation))
.accessTokenFormat(OAuth2TokenFormat.SELF_CONTAINED)
.reuseRefreshTokens(true)
.refreshTokenTimeToLive(Duration.ofSeconds(refreshTokenValidation))
.authorizationCodeTimeToLive(Duration.ofSeconds(accessTokenValidation))
.deviceCodeTimeToLive(Duration.ofSeconds(accessTokenValidation))
.build();
builder.tokenSettings(tokenSettings);
registeredClientRepository.save(builder.build());
}
/**
*
* @param clientId
* @param grantTypes
*/
public void updateGrantType(String clientId, Set<AuthorizationGrantType> grantTypes) {
RegisteredClient registeredClient = findByClientId(clientId);
RegisteredClient.Builder builder = RegisteredClient.from(registeredClient);
for (AuthorizationGrantType grantType : grantTypes) {
builder.authorizationGrantType(grantType);
}
registeredClientRepository.save(builder.build());
}
/**
* uri
* @param clientId
* @param redirectUris
*/
public void updateRedirectUris(String clientId, String redirectUris) {
RegisteredClient registeredClient = findByClientId(clientId);
RegisteredClient.Builder builder = RegisteredClient.from(registeredClient);
builder.redirectUri(redirectUris);
registeredClientRepository.save(builder.build());
}
/**
*
* @param clientId
* @param scopes
*/
public void updateScopes(String clientId, Set<String> scopes) {
RegisteredClient registeredClient = findByClientId(clientId);
RegisteredClient.Builder builder = RegisteredClient.from(registeredClient);
for (String scope : scopes) {
builder.scope(scope);
}
registeredClientRepository.save(builder.build());
}
public RegisteredClient findByClientId(String clientId) {
return registeredClientRepository.findByClientId(clientId);
}
}

View File

@ -12,6 +12,7 @@ import org.springframework.util.StringUtils;
import java.util.Set; import java.util.Set;
/** /**
* spring authorization server@PreAuthorize
* @author EightMonth * @author EightMonth
* @date 2024/1/10 17:00 * @date 2024/1/10 17:00
*/ */

View File

@ -9,6 +9,9 @@ import org.springframework.util.Assert;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/**
* spring authorization server redis
*/
@Component @Component
@RequiredArgsConstructor @RequiredArgsConstructor
public class JeecgRedisOAuth2AuthorizationConsentService implements OAuth2AuthorizationConsentService { public class JeecgRedisOAuth2AuthorizationConsentService implements OAuth2AuthorizationConsentService {

View File

@ -24,6 +24,7 @@ import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
* spring authorization serverredis
* @author EightMonth * @author EightMonth
*/ */
@Component @Component

View File

@ -0,0 +1,49 @@
package org.jeecg.config.security;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import org.jeecg.common.system.util.JwtUtil;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
import org.springframework.security.oauth2.server.resource.BearerTokenErrors;
import org.springframework.security.oauth2.server.resource.web.DefaultBearerTokenResolver;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
import java.util.Objects;
/**
* 退使token
* @author eightmonth@qq.com
* @date 2024/3/7 17:30
*/
@Component
@AllArgsConstructor
public class RedisTokenValidationFilter extends OncePerRequestFilter {
private OAuth2AuthorizationService authorizationService;
private JwtDecoder jwtDecoder;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// 从请求中获取token
DefaultBearerTokenResolver defaultBearerTokenResolver = new DefaultBearerTokenResolver();
String token = defaultBearerTokenResolver.resolve(request);
if (Objects.nonNull(token)) {
// 检查认证信息是否已被清除如果已被清除则令该token失效
OAuth2Authorization oAuth2Authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN);
if (Objects.isNull(oAuth2Authorization)) {
throw new OAuth2AuthenticationException(BearerTokenErrors.invalidToken("认证信息已失效,请重新登录"));
}
}
filterChain.doFilter(request, response);
}
}

View File

@ -37,6 +37,7 @@ import org.springframework.security.oauth2.server.authorization.settings.Authori
import org.springframework.security.oauth2.server.authorization.token.*; import org.springframework.security.oauth2.server.authorization.token.*;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher; import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher;
import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfiguration;
@ -49,6 +50,7 @@ import java.util.Arrays;
import java.util.UUID; import java.util.UUID;
/** /**
* spring authorization server
* @author eightmonth@qq.com * @author eightmonth@qq.com
* @date 2024/1/2 9:29 * @date 2024/1/2 9:29
*/ */
@ -66,6 +68,7 @@ public class SecurityConfig {
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)
throws Exception { throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
// 注册自定义登录类型
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class) http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
.tokenEndpoint(tokenEndpoint -> tokenEndpoint.accessTokenRequestConverter(new PasswordGrantAuthenticationConvert()) .tokenEndpoint(tokenEndpoint -> tokenEndpoint.accessTokenRequestConverter(new PasswordGrantAuthenticationConvert())
.authenticationProvider(new PasswordGrantAuthenticationProvider(authorizationService, tokenGenerator()))) .authenticationProvider(new PasswordGrantAuthenticationProvider(authorizationService, tokenGenerator())))
@ -172,7 +175,7 @@ public class SecurityConfig {
} }
/** /**
* *
*/ */
@Bean @Bean
public RegisteredClientRepository registeredClientRepository() { public RegisteredClientRepository registeredClientRepository() {

View File

@ -16,6 +16,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
* APP
* @author EightMonth * @author EightMonth
* @date 2024/1/1 * @date 2024/1/1
*/ */

View File

@ -1,5 +1,6 @@
package org.jeecg.config.security.app; package org.jeecg.config.security.app;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.CommonAPI; import org.jeecg.common.api.CommonAPI;
import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.CommonConstant;
@ -40,6 +41,7 @@ import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
/** /**
* APP
* @author EightMonth * @author EightMonth
* @date 2024/1/1 * @date 2024/1/1
*/ */
@ -85,7 +87,7 @@ public class AppGrantAuthenticationProvider implements AuthenticationProvider {
String captcha = (String) additionalParameter.get("captcha"); String captcha = (String) additionalParameter.get("captcha");
String checkKey = (String) additionalParameter.get("checkKey"); String checkKey = (String) additionalParameter.get("checkKey");
// 检查登录失败次数
if(isLoginFailOvertimes(username)){ if(isLoginFailOvertimes(username)){
throw new JeecgBootException("该用户登录失败次数过多请于10分钟后再次登录"); throw new JeecgBootException("该用户登录失败次数过多请于10分钟后再次登录");
} }
@ -112,6 +114,7 @@ public class AppGrantAuthenticationProvider implements AuthenticationProvider {
throw new JeecgBootException("非法登录"); throw new JeecgBootException("非法登录");
} }
// 通过用户名获取用户信息
LoginUser loginUser = commonAPI.getUserByName(username); LoginUser loginUser = commonAPI.getUserByName(username);
// 检查用户可行性 // 检查用户可行性
checkUserIsEffective(loginUser); checkUserIsEffective(loginUser);
@ -180,6 +183,7 @@ public class AppGrantAuthenticationProvider implements AuthenticationProvider {
OAuth2Authorization authorization = authorizationBuilder.build(); OAuth2Authorization authorization = authorizationBuilder.build();
// 保存认证信息至redis
authorizationService.save(authorization); authorizationService.save(authorization);
// 登录成功删除redis中的验证码 // 登录成功删除redis中的验证码
@ -187,7 +191,12 @@ public class AppGrantAuthenticationProvider implements AuthenticationProvider {
redisUtil.del(CommonConstant.LOGIN_FAIL + username); redisUtil.del(CommonConstant.LOGIN_FAIL + username);
baseCommonService.addLog("用户名: " + username + ",登录成功!", CommonConstant.LOG_TYPE_1, null,loginUser); baseCommonService.addLog("用户名: " + username + ",登录成功!", CommonConstant.LOG_TYPE_1, null,loginUser);
Map<String, Object> addition = new HashMap<>(); JSONObject addition = new JSONObject(new LinkedHashMap<>());
// 设置租户
JSONObject jsonObject = commonAPI.setLoginTenant(username);
addition.putAll(jsonObject.getInnerMap());
// 设置登录用户信息 // 设置登录用户信息
addition.put("userInfo", loginUser); addition.put("userInfo", loginUser);
addition.put("sysAllDictItems", commonAPI.queryAllDictItems()); addition.put("sysAllDictItems", commonAPI.queryAllDictItems());
@ -207,6 +216,7 @@ public class AppGrantAuthenticationProvider implements AuthenticationProvider {
addition.put("multi_depart", 2); addition.put("multi_depart", 2);
} }
// 返回access_token、refresh_token以及其它信息给到前端
return new OAuth2AccessTokenAuthenticationToken(registeredClient, clientPrincipal, accessToken, refreshToken, addition); return new OAuth2AccessTokenAuthenticationToken(registeredClient, clientPrincipal, accessToken, refreshToken, addition);
} }

View File

@ -8,6 +8,7 @@ import org.springframework.security.oauth2.server.authorization.authentication.O
import java.util.Map; import java.util.Map;
/** /**
* APPtokenspring authorization serverconvert使
* @author EightMonth * @author EightMonth
* @date 2024/1/1 * @date 2024/1/1
*/ */

View File

@ -17,6 +17,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
*
* @author EightMonth * @author EightMonth
* @date 2024/1/1 * @date 2024/1/1
*/ */

View File

@ -1,5 +1,6 @@
package org.jeecg.config.security.password; package org.jeecg.config.security.password;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.CommonAPI; import org.jeecg.common.api.CommonAPI;
import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.CommonConstant;
@ -41,6 +42,7 @@ import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
/** /**
*
* @author EightMonth * @author EightMonth
* @date 2024/1/1 * @date 2024/1/1
*/ */
@ -86,7 +88,7 @@ public class PasswordGrantAuthenticationProvider implements AuthenticationProvid
String captcha = (String) additionalParameter.get("captcha"); String captcha = (String) additionalParameter.get("captcha");
String checkKey = (String) additionalParameter.get("checkKey"); String checkKey = (String) additionalParameter.get("checkKey");
// 检查登录失败次数
if(isLoginFailOvertimes(username)){ if(isLoginFailOvertimes(username)){
throw new JeecgBootException("该用户登录失败次数过多请于10分钟后再次登录"); throw new JeecgBootException("该用户登录失败次数过多请于10分钟后再次登录");
} }
@ -113,6 +115,7 @@ public class PasswordGrantAuthenticationProvider implements AuthenticationProvid
throw new JeecgBootException("非法登录"); throw new JeecgBootException("非法登录");
} }
// 通过用户名获取用户信息
LoginUser loginUser = commonAPI.getUserByName(username); LoginUser loginUser = commonAPI.getUserByName(username);
// 检查用户可行性 // 检查用户可行性
checkUserIsEffective(loginUser); checkUserIsEffective(loginUser);
@ -181,6 +184,7 @@ public class PasswordGrantAuthenticationProvider implements AuthenticationProvid
OAuth2Authorization authorization = authorizationBuilder.build(); OAuth2Authorization authorization = authorizationBuilder.build();
// 保存认证信息至redis
authorizationService.save(authorization); authorizationService.save(authorization);
// 登录成功删除redis中的验证码 // 登录成功删除redis中的验证码
@ -188,7 +192,12 @@ public class PasswordGrantAuthenticationProvider implements AuthenticationProvid
redisUtil.del(CommonConstant.LOGIN_FAIL + username); redisUtil.del(CommonConstant.LOGIN_FAIL + username);
baseCommonService.addLog("用户名: " + username + ",登录成功!", CommonConstant.LOG_TYPE_1, null,loginUser); baseCommonService.addLog("用户名: " + username + ",登录成功!", CommonConstant.LOG_TYPE_1, null,loginUser);
Map<String, Object> addition = new HashMap<>(); JSONObject addition = new JSONObject(new LinkedHashMap<>());
// 设置租户
JSONObject jsonObject = commonAPI.setLoginTenant(username);
addition.putAll(jsonObject.getInnerMap());
// 设置登录用户信息 // 设置登录用户信息
addition.put("userInfo", loginUser); addition.put("userInfo", loginUser);
addition.put("sysAllDictItems", commonAPI.queryAllDictItems()); addition.put("sysAllDictItems", commonAPI.queryAllDictItems());
@ -208,6 +217,7 @@ public class PasswordGrantAuthenticationProvider implements AuthenticationProvid
addition.put("multi_depart", 2); addition.put("multi_depart", 2);
} }
// 返回access_token、refresh_token以及其它信息给到前端
return new OAuth2AccessTokenAuthenticationToken(registeredClient, clientPrincipal, accessToken, refreshToken, addition); return new OAuth2AccessTokenAuthenticationToken(registeredClient, clientPrincipal, accessToken, refreshToken, addition);
} }

View File

@ -8,6 +8,7 @@ import org.springframework.security.oauth2.server.authorization.authentication.O
import java.util.Map; import java.util.Map;
/** /**
* tokenspring authorization serverconvert使
* @author EightMonth * @author EightMonth
* @date 2024/1/1 * @date 2024/1/1
*/ */

View File

@ -16,6 +16,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
*
* @author EightMonth * @author EightMonth
* @date 2024/1/1 * @date 2024/1/1
*/ */

View File

@ -1,5 +1,6 @@
package org.jeecg.config.security.phone; package org.jeecg.config.security.phone;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.CommonAPI; import org.jeecg.common.api.CommonAPI;
import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.CommonConstant;
@ -40,6 +41,7 @@ import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
/** /**
*
* @author EightMonth * @author EightMonth
* @date 2024/1/1 * @date 2024/1/1
*/ */
@ -87,6 +89,7 @@ public class PhoneGrantAuthenticationProvider implements AuthenticationProvider
// 验证码 // 验证码
String captcha = (String) additionalParameter.get("captcha"); String captcha = (String) additionalParameter.get("captcha");
// 通过手机号获取用户信息
LoginUser loginUser = commonAPI.getUserByPhone(phone); LoginUser loginUser = commonAPI.getUserByPhone(phone);
// 检查用户可行性 // 检查用户可行性
checkUserIsEffective(loginUser); checkUserIsEffective(loginUser);
@ -166,11 +169,17 @@ public class PhoneGrantAuthenticationProvider implements AuthenticationProvider
OAuth2Authorization authorization = authorizationBuilder.build(); OAuth2Authorization authorization = authorizationBuilder.build();
// 保存认证信息至redis
authorizationService.save(authorization); authorizationService.save(authorization);
baseCommonService.addLog("用户名: " + loginUser.getUsername() + ",登录成功!", CommonConstant.LOG_TYPE_1, null,loginUser); baseCommonService.addLog("用户名: " + loginUser.getUsername() + ",登录成功!", CommonConstant.LOG_TYPE_1, null,loginUser);
Map<String, Object> addition = new HashMap<>(); JSONObject addition = new JSONObject(new LinkedHashMap<>());
// 设置租户
JSONObject jsonObject = commonAPI.setLoginTenant(loginUser.getUsername());
addition.putAll(jsonObject.getInnerMap());
// 设置登录用户信息 // 设置登录用户信息
addition.put("userInfo", loginUser); addition.put("userInfo", loginUser);
addition.put("sysAllDictItems", commonAPI.queryAllDictItems()); addition.put("sysAllDictItems", commonAPI.queryAllDictItems());
@ -190,6 +199,7 @@ public class PhoneGrantAuthenticationProvider implements AuthenticationProvider
addition.put("multi_depart", 2); addition.put("multi_depart", 2);
} }
// 返回access_token、refresh_token以及其它信息给到前端
return new OAuth2AccessTokenAuthenticationToken(registeredClient, clientPrincipal, accessToken, refreshToken, addition); return new OAuth2AccessTokenAuthenticationToken(registeredClient, clientPrincipal, accessToken, refreshToken, addition);
} }

View File

@ -8,6 +8,7 @@ import org.springframework.security.oauth2.server.authorization.authentication.O
import java.util.Map; import java.util.Map;
/** /**
* tokenspring authorization serverconvert使
* @author EightMonth * @author EightMonth
* @date 2024/1/1 * @date 2024/1/1
*/ */

View File

@ -16,6 +16,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
* github使
* @author EightMonth * @author EightMonth
* @date 2024/1/1 * @date 2024/1/1
*/ */

View File

@ -1,5 +1,6 @@
package org.jeecg.config.security.social; package org.jeecg.config.security.social;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT; import com.auth0.jwt.JWT;
import com.auth0.jwt.interfaces.DecodedJWT; import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -38,6 +39,7 @@ import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
/** /**
* github使
* @author EightMonth * @author EightMonth
* @date 2024/1/1 * @date 2024/1/1
*/ */
@ -84,6 +86,7 @@ public class SocialGrantAuthenticationProvider implements AuthenticationProvider
DecodedJWT jwt = JWT.decode(token); DecodedJWT jwt = JWT.decode(token);
String username = jwt.getClaim("username").asString(); String username = jwt.getClaim("username").asString();
// 通过手机号获取用户信息
LoginUser loginUser = commonAPI.getUserByName(username); LoginUser loginUser = commonAPI.getUserByName(username);
// 检查用户可行性 // 检查用户可行性
checkUserIsEffective(loginUser); checkUserIsEffective(loginUser);
@ -152,11 +155,17 @@ public class SocialGrantAuthenticationProvider implements AuthenticationProvider
OAuth2Authorization authorization = authorizationBuilder.build(); OAuth2Authorization authorization = authorizationBuilder.build();
// 保存认证信息至redis
authorizationService.save(authorization); authorizationService.save(authorization);
baseCommonService.addLog("用户名: " + loginUser.getUsername() + ",登录成功!", CommonConstant.LOG_TYPE_1, null,loginUser); baseCommonService.addLog("用户名: " + loginUser.getUsername() + ",登录成功!", CommonConstant.LOG_TYPE_1, null,loginUser);
Map<String, Object> addition = new HashMap<>(); JSONObject addition = new JSONObject(new LinkedHashMap<>());
// 设置租户
JSONObject jsonObject = commonAPI.setLoginTenant(loginUser.getUsername());
addition.putAll(jsonObject.getInnerMap());
// 设置登录用户信息 // 设置登录用户信息
addition.put("userInfo", loginUser); addition.put("userInfo", loginUser);
addition.put("sysAllDictItems", commonAPI.queryAllDictItems()); addition.put("sysAllDictItems", commonAPI.queryAllDictItems());
@ -176,6 +185,7 @@ public class SocialGrantAuthenticationProvider implements AuthenticationProvider
addition.put("multi_depart", 2); addition.put("multi_depart", 2);
} }
// 返回access_token、refresh_token以及其它信息给到前端
return new OAuth2AccessTokenAuthenticationToken(registeredClient, clientPrincipal, accessToken, refreshToken, addition); return new OAuth2AccessTokenAuthenticationToken(registeredClient, clientPrincipal, accessToken, refreshToken, addition);
} }

View File

@ -8,6 +8,7 @@ import org.springframework.security.oauth2.server.authorization.authentication.O
import java.util.Map; import java.util.Map;
/** /**
* tokenspring authorization serverconvert使github使
* @author EightMonth * @author EightMonth
* @date 2024/1/1 * @date 2024/1/1
*/ */

View File

@ -2,14 +2,20 @@ package org.jeecg.config.security.utils;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.SpringContextUtils;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
/** /**
*
* @author EightMonth * @author EightMonth
* @date 2024/1/10 17:03 * @date 2024/1/10 17:03
*/ */
public class SecureUtil { public class SecureUtil {
/**
*
* @return
*/
public static LoginUser currentUser() { public static LoginUser currentUser() {
String name = SecurityContextHolder.getContext().getAuthentication().getName(); String name = SecurityContextHolder.getContext().getAuthentication().getName();
return JSONObject.parseObject(name, LoginUser.class); return JSONObject.parseObject(name, LoginUser.class);

View File

@ -749,4 +749,6 @@ public interface ISysBaseAPI extends CommonAPI {
@PostMapping("/sys/api/updateUserDepart") @PostMapping("/sys/api/updateUserDepart")
void updateUserDepart(@RequestParam("username") String username,@RequestParam("orgCode") String orgCode,@RequestParam("loginTenantId") Integer loginTenantId); void updateUserDepart(@RequestParam("username") String username,@RequestParam("orgCode") String orgCode,@RequestParam("loginTenantId") Integer loginTenantId);
@GetMapping("/sys/api/setLoginTenant")
JSONObject setLoginTenant(@RequestParam("username") String username);
} }

View File

@ -452,4 +452,9 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
public LoginUser getUserByPhone(String phone) { public LoginUser getUserByPhone(String phone) {
return null; return null;
} }
@Override
public JSONObject setLoginTenant(String username) {
return null;
}
} }

View File

@ -917,4 +917,9 @@ public class SystemApiController {
sysBaseApi.updateUserDepart(username, orgCode, loginTenantId); sysBaseApi.updateUserDepart(username, orgCode, loginTenantId);
} }
@GetMapping("/sys/api/setLoginTenant")
public JSONObject setLoginTenant(@RequestParam("username") String username) {
return sysBaseApi.setLoginTenant(username);
}
} }

View File

@ -20,6 +20,7 @@ import org.apache.commons.lang3.ObjectUtils;
import org.jeecg.common.api.dto.DataLogDTO; import org.jeecg.common.api.dto.DataLogDTO;
import org.jeecg.common.api.dto.OnlineAuthDTO; import org.jeecg.common.api.dto.OnlineAuthDTO;
import org.jeecg.common.api.dto.message.*; import org.jeecg.common.api.dto.message.*;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.UrlMatchEnum; import org.jeecg.common.aspect.UrlMatchEnum;
import org.jeecg.common.config.TenantContext; import org.jeecg.common.config.TenantContext;
import org.jeecg.common.constant.*; import org.jeecg.common.constant.*;
@ -1780,4 +1781,11 @@ public class SysBaseApiImpl implements ISysBaseAPI {
} }
} }
@Override
public JSONObject setLoginTenant(String username) {
JSONObject obj = new JSONObject(new LinkedHashMap<>());
SysUser sysUser = sysUserService.getUserByName(username);
sysUserService.setLoginTenant(sysUser, obj, username, null);
return obj;
}
} }