use of cn.iocoder.yudao.framework.security.core.LoginUser in project ruoyi-vue-pro by YunaiV.
the class DeptDataPermissionRule method getExpression.
@Override
public Expression getExpression(String tableName, Alias tableAlias) {
// 只有有登陆用户的情况下,才进行数据权限的处理
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
if (loginUser == null) {
return null;
}
// 获得数据权限
DeptDataPermissionRespDTO deptDataPermission = deptDataPermissionService.getDeptDataPermission(loginUser);
if (deptDataPermission == null) {
log.error("[getExpression][LoginUser({}) 获取数据权限为 null]", JsonUtils.toJsonString(loginUser));
throw new NullPointerException(String.format("LoginUser(%d) Table(%s/%s) 未返回数据权限", loginUser.getId(), tableName, tableAlias.getName()));
}
// 情况一,如果是 ALL 可查看全部,则无需拼接条件
if (deptDataPermission.getAll()) {
return null;
}
// 情况二,即不能查看部门,又不能查看自己,则说明 100% 无权限
if (CollUtil.isEmpty(deptDataPermission.getDeptIds()) && Boolean.FALSE.equals(deptDataPermission.getSelf())) {
// WHERE null = null,可以保证返回的数据为空
return new EqualsTo(null, null);
}
// 情况三,拼接 Dept 和 User 的条件,最后组合
Expression deptExpression = this.buildDeptExpression(tableName, tableAlias, deptDataPermission.getDeptIds());
Expression userExpression = this.buildUserExpression(tableName, tableAlias, deptDataPermission.getSelf(), loginUser.getId());
if (deptExpression == null && userExpression == null) {
// TODO 芋艿:获得不到条件的时候,暂时不抛出异常,而是不返回数据
log.warn("[getExpression][LoginUser({}) Table({}/{}) DeptDataPermission({}) 构建的条件为空]", JsonUtils.toJsonString(loginUser), tableName, tableAlias, JsonUtils.toJsonString(deptDataPermission));
// loginUser.getId(), tableName, tableAlias.getName()));
return EXPRESSION_NULL;
}
if (deptExpression == null) {
return userExpression;
}
if (userExpression == null) {
return deptExpression;
}
// 目前,如果有指定部门 + 可查看自己,采用 OR 条件。即,WHERE dept_id IN ? OR user_id = ?
return new OrExpression(deptExpression, userExpression);
}
use of cn.iocoder.yudao.framework.security.core.LoginUser in project ruoyi-vue-pro by YunaiV.
the class DeptDataPermissionRuleTest method testGetExpression_noDept_noSelf.
// 即不能查看部门,又不能查看自己,则说明 100% 无权限
@Test
public void testGetExpression_noDept_noSelf() {
try (MockedStatic<SecurityFrameworkUtils> securityFrameworkUtilsMock = mockStatic(SecurityFrameworkUtils.class)) {
// 准备参数
String tableName = "t_user";
Alias tableAlias = new Alias("u");
// mock 方法(LoginUser)
LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L));
securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
// mock 方法(DeptDataPermissionRespDTO)
DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO();
when(deptDataPermissionFrameworkService.getDeptDataPermission(same(loginUser))).thenReturn(deptDataPermission);
// 调用
Expression expression = rule.getExpression(tableName, tableAlias);
// 断言
assertEquals("null = null", expression.toString());
}
}
use of cn.iocoder.yudao.framework.security.core.LoginUser in project ruoyi-vue-pro by YunaiV.
the class DeptDataPermissionRuleTest method testGetExpression_yesDeptColumn_noSelfColumn.
// 拼接 Dept 和 User 的条件(dept 符合)
@Test
public void testGetExpression_yesDeptColumn_noSelfColumn() {
try (MockedStatic<SecurityFrameworkUtils> securityFrameworkUtilsMock = mockStatic(SecurityFrameworkUtils.class)) {
// 准备参数
String tableName = "t_user";
Alias tableAlias = new Alias("u");
// mock 方法(LoginUser)
LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L));
securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
// mock 方法(DeptDataPermissionRespDTO)
DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO().setDeptIds(CollUtil.newLinkedHashSet(10L, 20L));
when(deptDataPermissionFrameworkService.getDeptDataPermission(same(loginUser))).thenReturn(deptDataPermission);
// 添加 dept 字段配置
rule.addDeptColumn("t_user", "dept_id");
// 调用
Expression expression = rule.getExpression(tableName, tableAlias);
// 断言
assertEquals("u.dept_id IN (10, 20)", expression.toString());
}
}
use of cn.iocoder.yudao.framework.security.core.LoginUser in project ruoyi-vue-pro by YunaiV.
the class JWTAuthenticationTokenFilter method doFilterInternal.
@Override
@SuppressWarnings("NullableProblems")
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
String token = SecurityFrameworkUtils.obtainAuthorization(request, securityProperties.getTokenHeader());
if (StrUtil.isNotEmpty(token)) {
try {
// 验证 token 有效性
LoginUser loginUser = authenticationProvider.verifyTokenAndRefresh(request, token);
// 模拟 Login 功能,方便日常开发调试
if (loginUser == null) {
loginUser = this.mockLoginUser(request, token);
}
// 设置当前用户
if (loginUser != null) {
SecurityFrameworkUtils.setLoginUser(loginUser, request);
}
} catch (Throwable ex) {
CommonResult<?> result = globalExceptionHandler.allExceptionHandler(request, ex);
ServletUtils.writeJSON(response, result);
return;
}
}
// 继续过滤链
chain.doFilter(request, response);
}
use of cn.iocoder.yudao.framework.security.core.LoginUser in project ruoyi-vue-pro by YunaiV.
the class MemberAuthServiceImpl method login0.
private LoginUser login0(String username, String password) {
final LoginLogTypeEnum logType = LoginLogTypeEnum.LOGIN_USERNAME;
// 用户验证
Authentication authentication;
try {
// 调用 Spring Security 的 AuthenticationManager#authenticate(...) 方法,使用账号密码进行认证
// 在其内部,会调用到 loadUserByUsername 方法,获取 User 信息
authentication = authenticationManager.authenticate(new MultiUsernamePasswordAuthenticationToken(username, password, getUserType()));
} catch (BadCredentialsException badCredentialsException) {
this.createLoginLog(username, logType, LoginResultEnum.BAD_CREDENTIALS);
throw exception(AUTH_LOGIN_BAD_CREDENTIALS);
} catch (DisabledException disabledException) {
this.createLoginLog(username, logType, LoginResultEnum.USER_DISABLED);
throw exception(AUTH_LOGIN_USER_DISABLED);
} catch (AuthenticationException authenticationException) {
log.error("[login0][username({}) 发生未知异常]", username, authenticationException);
this.createLoginLog(username, logType, LoginResultEnum.UNKNOWN_ERROR);
throw exception(AUTH_LOGIN_FAIL_UNKNOWN);
}
// 登录成功的日志
Assert.notNull(authentication.getPrincipal(), "Principal 不会为空");
this.createLoginLog(username, logType, LoginResultEnum.SUCCESS);
return (LoginUser) authentication.getPrincipal();
}
Aggregations