Browse Source

完成登录流程等功能

master
前端-胡立永 5 days ago
parent
commit
486cad2d6c
9 changed files with 92 additions and 23 deletions
  1. +1
    -1
      jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/AppletShiroConfig.java
  2. +1
    -1
      jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/AppletShiroRealm.java
  3. +3
    -1
      jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java
  4. +55
    -3
      jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroRealm.java
  5. +2
    -0
      jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/filters/AppletJwtFilter.java
  6. +20
    -2
      jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/filters/JwtFilter.java
  7. +5
    -8
      jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/src/main/java/org/jeecg/modules/applet/controller/AppletApiIndexController.java
  8. +3
    -4
      jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/src/main/java/org/jeecg/modules/applet/service/AppletApiIndexService.java
  9. +2
    -3
      jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/src/main/java/org/jeecg/modules/applet/service/impl/AppletApiIndexServiceImpl.java

+ 1
- 1
jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/AppletShiroConfig.java View File

@ -24,7 +24,7 @@ import java.util.Map;
* @date 2025-01-25 * @date 2025-01-25
*/ */
@Slf4j @Slf4j
@Configuration
//@Configuration
public class AppletShiroConfig { public class AppletShiroConfig {
/** /**


+ 1
- 1
jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/AppletShiroRealm.java View File

@ -164,7 +164,7 @@ public class AppletShiroRealm extends AuthorizingRealm {
} catch (Exception e) { } catch (Exception e) {
log.error("获取小程序用户信息异常,openid: {}", openid, e); log.error("获取小程序用户信息异常,openid: {}", openid, e);
return null;
return null;
} }
} }


+ 3
- 1
jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java View File

@ -104,7 +104,7 @@ public class ShiroConfig {
filterChainDefinitionMap.put("/sys/common/pdf/**", "anon");//pdf预览 filterChainDefinitionMap.put("/sys/common/pdf/**", "anon");//pdf预览
filterChainDefinitionMap.put("/appletApi/**", "anon");//小程序
//filterChainDefinitionMap.put("/appletApi/**", "anon");//小程序
//filterChainDefinitionMap.put("/sys/common/view/**", "anon");//图片预览不限制token //filterChainDefinitionMap.put("/sys/common/view/**", "anon");//图片预览不限制token
//filterChainDefinitionMap.put("/sys/common/download/**", "anon");//文件下载不限制token //filterChainDefinitionMap.put("/sys/common/download/**", "anon");//文件下载不限制token
@ -191,10 +191,12 @@ public class ShiroConfig {
//如果cloudServer为空 则说明是单体 需要加载跨域配置微服务跨域切换 //如果cloudServer为空 则说明是单体 需要加载跨域配置微服务跨域切换
Object cloudServer = env.getProperty(CommonConstant.CLOUD_SERVER_KEY); Object cloudServer = env.getProperty(CommonConstant.CLOUD_SERVER_KEY);
filterMap.put("jwt", new JwtFilter(cloudServer==null)); filterMap.put("jwt", new JwtFilter(cloudServer==null));
// filterMap.put("appletApi", new AppletJwtFilter(cloudServer==null));
shiroFilterFactoryBean.setFilters(filterMap); shiroFilterFactoryBean.setFilters(filterMap);
// <!-- 过滤链定义从上向下顺序执行 // <!-- 过滤链定义从上向下顺序执行
// 其他请求使用jwt过滤器 // 其他请求使用jwt过滤器
// filterChainDefinitionMap.put("/appletApi/**", "appletApi");
filterChainDefinitionMap.put("/**", "jwt"); filterChainDefinitionMap.put("/**", "jwt");
// 未授权界面返回JSON // 未授权界面返回JSON


+ 55
- 3
jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroRealm.java View File

@ -10,10 +10,12 @@ import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.subject.PrincipalCollection;
import org.jeecg.common.api.CommonAPI; import org.jeecg.common.api.CommonAPI;
import org.jeecg.common.api.IAppletUserService;
import org.jeecg.common.config.TenantContext; import org.jeecg.common.config.TenantContext;
import org.jeecg.common.constant.CacheConstant; import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.util.JwtUtil; import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.AppletUser;
import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.RedisUtil; import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.SpringContextUtils; import org.jeecg.common.util.SpringContextUtils;
@ -44,12 +46,16 @@ public class ShiroRealm extends AuthorizingRealm {
@Resource @Resource
private RedisUtil redisUtil; private RedisUtil redisUtil;
@Lazy
@Resource
private IAppletUserService appletUserService;
/** /**
* 必须重写此方法不然Shiro会报错 * 必须重写此方法不然Shiro会报错
*/ */
@Override @Override
public boolean supports(AuthenticationToken token) { public boolean supports(AuthenticationToken token) {
return token instanceof JwtToken;
return token instanceof JwtToken || token instanceof AppletJwtToken;
} }
/** /**
@ -65,6 +71,11 @@ public class ShiroRealm extends AuthorizingRealm {
String username = null; String username = null;
String userId = null; String userId = null;
if (principals != null) { if (principals != null) {
if (principals.getPrimaryPrincipal() instanceof AppletUser){
return new SimpleAuthorizationInfo();
}
LoginUser sysUser = (LoginUser) principals.getPrimaryPrincipal(); LoginUser sysUser = (LoginUser) principals.getPrimaryPrincipal();
username = sysUser.getUsername(); username = sysUser.getUsername();
userId = sysUser.getId(); userId = sysUser.getId();
@ -102,9 +113,16 @@ public class ShiroRealm extends AuthorizingRealm {
throw new AuthenticationException("token为空!"); throw new AuthenticationException("token为空!");
} }
// 校验token有效性 // 校验token有效性
LoginUser loginUser = null;
Object loginUser = null;
try { try {
loginUser = this.checkUserTokenIsEffect(token);
if (auth instanceof AppletJwtToken){
String openid = JwtUtil.getUsername(token);
loginUser = getAppletUser(openid, token);
}else {
loginUser = this.checkUserTokenIsEffect(token);
}
} catch (AuthenticationException e) { } catch (AuthenticationException e) {
JwtUtil.responseError(SpringContextUtils.getHttpServletResponse(),401,e.getMessage()); JwtUtil.responseError(SpringContextUtils.getHttpServletResponse(),401,e.getMessage());
e.printStackTrace(); e.printStackTrace();
@ -181,6 +199,40 @@ public class ShiroRealm extends AuthorizingRealm {
return loginUser; return loginUser;
} }
/**
* 获取小程序用户信息
*
* @param openid
* @param token
* @return 用户信息
*/
private AppletUser getAppletUser(String openid, String token) {
try {
log.debug("开始获取小程序用户信息,openid: {}", openid);
if (openid == null) {
throw new AuthenticationException("小程序token非法无效!");
}
// 从数据库查询用户信息
AppletUser appletUser = appletUserService.getByOpenid(openid);
if (appletUser != null) {
log.debug("从数据库获取到小程序用户: {}", appletUser.getName());
return appletUser;
}
if (!jwtTokenRefresh(token, openid, appletUser.getId())) {
throw new AuthenticationException(CommonConstant.TOKEN_IS_INVALID_MSG);
}
log.warn("未找到小程序用户,openid: {}", openid);
return null;
} catch (Exception e) {
log.error("获取小程序用户信息异常,openid: {}", openid, e);
return null;
}
}
/** /**
* JWTToken刷新生命周期 实现 用户在线操作不掉线功能 * JWTToken刷新生命周期 实现 用户在线操作不掉线功能
* 1登录成功后将用户的JWT生成的Token作为kv存储到cache缓存里面(这时候kv值一样)缓存有效期设置为Jwt有效时间的2倍 * 1登录成功后将用户的JWT生成的Token作为kv存储到cache缓存里面(这时候kv值一样)缓存有效期设置为Jwt有效时间的2倍


+ 2
- 0
jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/filters/AppletJwtFilter.java View File

@ -110,6 +110,8 @@ public class AppletJwtFilter extends BasicHttpAuthenticationFilter {
AppletJwtToken jwtToken = new AppletJwtToken(token); AppletJwtToken jwtToken = new AppletJwtToken(token);
// 提交给小程序专用realm进行登入如果错误他会抛出异常并被捕获 // 提交给小程序专用realm进行登入如果错误他会抛出异常并被捕获
getSubject(request, response).login(jwtToken); getSubject(request, response).login(jwtToken);
// 如果没有抛出异常则代表登入成功返回true // 如果没有抛出异常则代表登入成功返回true
log.debug("小程序登录认证成功"); log.debug("小程序登录认证成功");
return true; return true;


+ 20
- 2
jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/filters/JwtFilter.java View File

@ -2,11 +2,13 @@ package org.jeecg.config.shiro.filters;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter; import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
import org.jeecg.common.config.TenantContext; import org.jeecg.common.config.TenantContext;
import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.util.JwtUtil; import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.util.oConvertUtils; import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.shiro.AppletJwtToken;
import org.jeecg.config.shiro.JwtToken; import org.jeecg.config.shiro.JwtToken;
import org.jeecg.config.shiro.ignore.InMemoryIgnoreAuth; import org.jeecg.config.shiro.ignore.InMemoryIgnoreAuth;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
@ -48,10 +50,19 @@ public class JwtFilter extends BasicHttpAuthenticationFilter {
@Override @Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
try { try {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String requestPath = httpRequest.getServletPath();
// 判断当前路径是不是注解了@IngoreAuth路径如果是则放开验证 // 判断当前路径是不是注解了@IngoreAuth路径如果是则放开验证
if (InMemoryIgnoreAuth.contains(((HttpServletRequest) request).getServletPath())) { if (InMemoryIgnoreAuth.contains(((HttpServletRequest) request).getServletPath())) {
return true; return true;
} }
// 不处理以/appletApi开头的请求
// if (requestPath.startsWith("/appletApi")) {
// log.debug("不是小程序请求,直接放行: {}", requestPath);
// return true; // 不是appletApi请求直接放行
// }
executeLogin(request, response); executeLogin(request, response);
return true; return true;
@ -75,9 +86,16 @@ public class JwtFilter extends BasicHttpAuthenticationFilter {
} }
// update-end--Author:lvdandan Date:20210105 forJT-355 OA聊天添加token验证获取token参数 // update-end--Author:lvdandan Date:20210105 forJT-355 OA聊天添加token验证获取token参数
JwtToken jwtToken = new JwtToken(token);
// 提交给realm进行登入如果错误他会抛出异常并被捕获
String requestPath = httpServletRequest.getServletPath();
AuthenticationToken jwtToken;
if (requestPath.startsWith("/appletApi")) {
jwtToken = new AppletJwtToken(token);
}else {
jwtToken = new JwtToken(token);
}
getSubject(request, response).login(jwtToken); getSubject(request, response).login(jwtToken);
// 如果没有抛出异常则代表登入成功返回true // 如果没有抛出异常则代表登入成功返回true
return true; return true;
} }


+ 5
- 8
jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/src/main/java/org/jeecg/modules/applet/controller/AppletApiIndexController.java View File

@ -31,18 +31,15 @@ public class AppletApiIndexController {
/** /**
* Banner列表查询 * Banner列表查询
* @return Banner列表按类型分组
* @return Banner列表
*/ */
@AutoLog(value = "Banner列表查询") @AutoLog(value = "Banner列表查询")
@Operation(summary = "Banner列表查询", description = "获取Banner列表,按类型分组,按排序字段排序")
@Operation(summary = "Banner列表查询", description = "获取Banner列表")
@GetMapping(value = "/list") @GetMapping(value = "/list")
@IgnoreAuth @IgnoreAuth
public Result<Map<String, List<AppletBanner>>> list() {
public Result<List<AppletBanner>> list() {
log.info("Banner列表查询"); log.info("Banner列表查询");
Map<String, List<AppletBanner>> groupedBanners = appletIndexService.getBannerListGrouped();
return Result.OK(groupedBanners);
List<AppletBanner> bannerList = appletIndexService.getBannerList();
return Result.OK(bannerList);
} }
} }

+ 3
- 4
jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/src/main/java/org/jeecg/modules/applet/service/AppletApiIndexService.java View File

@ -14,8 +14,7 @@ import java.util.Map;
public interface AppletApiIndexService { public interface AppletApiIndexService {
/** /**
* 获取Banner列表按类型分组
* @return Banner分组数据
* 获取Banner列表
*/ */
Map<String, List<AppletBanner>> getBannerListGrouped();
}
List<AppletBanner> getBannerList();
}

+ 2
- 3
jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/src/main/java/org/jeecg/modules/applet/service/impl/AppletApiIndexServiceImpl.java View File

@ -24,14 +24,13 @@ public class AppletApiIndexServiceImpl implements AppletApiIndexService {
private IAppletBannerService appletBannerService; private IAppletBannerService appletBannerService;
@Override @Override
public Map<String, List<AppletBanner>> getBannerListGrouped() {
public List<AppletBanner> getBannerList() {
LambdaQueryWrapper<AppletBanner> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<AppletBanner> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.orderByAsc(AppletBanner::getSortOrder); queryWrapper.orderByAsc(AppletBanner::getSortOrder);
List<AppletBanner> list = appletBannerService.list(queryWrapper); List<AppletBanner> list = appletBannerService.list(queryWrapper);
// 按类型分组 // 按类型分组
return list.stream()
.collect(Collectors.groupingBy(AppletBanner::getType));
return list;
} }
} }

Loading…
Cancel
Save