Search in sources :

Example 1 with LoginUser

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);
}
Also used : InExpression(net.sf.jsqlparser.expression.operators.relational.InExpression) Expression(net.sf.jsqlparser.expression.Expression) OrExpression(net.sf.jsqlparser.expression.operators.conditional.OrExpression) DeptDataPermissionRespDTO(cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO) EqualsTo(net.sf.jsqlparser.expression.operators.relational.EqualsTo) LoginUser(cn.iocoder.yudao.framework.security.core.LoginUser) OrExpression(net.sf.jsqlparser.expression.operators.conditional.OrExpression)

Example 2 with LoginUser

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 方法(LoginUserLoginUser 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());
    }
}
Also used : SecurityFrameworkUtils(cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils) Expression(net.sf.jsqlparser.expression.Expression) Alias(net.sf.jsqlparser.expression.Alias) DeptDataPermissionRespDTO(cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO) RandomUtils.randomString(cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString) LoginUser(cn.iocoder.yudao.framework.security.core.LoginUser) Test(org.junit.jupiter.api.Test) BaseMockitoUnitTest(cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest)

Example 3 with LoginUser

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 方法(LoginUserLoginUser 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());
    }
}
Also used : SecurityFrameworkUtils(cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils) Expression(net.sf.jsqlparser.expression.Expression) Alias(net.sf.jsqlparser.expression.Alias) DeptDataPermissionRespDTO(cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO) RandomUtils.randomString(cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString) LoginUser(cn.iocoder.yudao.framework.security.core.LoginUser) Test(org.junit.jupiter.api.Test) BaseMockitoUnitTest(cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest)

Example 4 with LoginUser

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);
}
Also used : CommonResult(cn.iocoder.yudao.framework.common.pojo.CommonResult) LoginUser(cn.iocoder.yudao.framework.security.core.LoginUser)

Example 5 with LoginUser

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();
}
Also used : AuthenticationException(org.springframework.security.core.AuthenticationException) Authentication(org.springframework.security.core.Authentication) MultiUsernamePasswordAuthenticationToken(cn.iocoder.yudao.framework.security.core.authentication.MultiUsernamePasswordAuthenticationToken) DisabledException(org.springframework.security.authentication.DisabledException) BadCredentialsException(org.springframework.security.authentication.BadCredentialsException) LoginUser(cn.iocoder.yudao.framework.security.core.LoginUser) LoginLogTypeEnum(cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum)

Aggregations

LoginUser (cn.iocoder.yudao.framework.security.core.LoginUser)36 Test (org.junit.jupiter.api.Test)20 DeptDataPermissionRespDTO (cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO)13 BaseDbUnitTest (cn.iocoder.yudao.module.system.test.BaseDbUnitTest)10 SecurityFrameworkUtils (cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils)7 BaseMockitoUnitTest (cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest)7 RandomUtils.randomString (cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString)7 Alias (net.sf.jsqlparser.expression.Alias)7 Expression (net.sf.jsqlparser.expression.Expression)7 AdminUserDO (cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO)6 RoleDO (cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO)5 UserRoleDO (cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO)5 LoginLogTypeEnum (cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum)4 BadCredentialsException (org.springframework.security.authentication.BadCredentialsException)4 DisabledException (org.springframework.security.authentication.DisabledException)4 CommonStatusEnum (cn.iocoder.yudao.framework.common.enums.CommonStatusEnum)2 CommonResult (cn.iocoder.yudao.framework.common.pojo.CommonResult)2 MultiUsernamePasswordAuthenticationToken (cn.iocoder.yudao.framework.security.core.authentication.MultiUsernamePasswordAuthenticationToken)2 AssertUtils (cn.iocoder.yudao.framework.test.core.util.AssertUtils)2 AssertUtils.assertServiceException (cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException)2