解决springboot集成activiti7工作流权限认证问题

本文档介绍了在SpringBoot中集成Activiti7时遇到的权限认证问题及解决方法。通过重写Spring Security的UserDetailsService,实现自定义用户认证,并在调用工作流方法前设置权限信息。此外,还展示了如何从远程服务获取用户信息,包括角色和权限,以确保工作流操作的权限控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

springboot集成activiti7工作流权限认证问题

如果你的登录不是用的security方式, 集成后会有权限认证的问题,因为activiti7自带spring-security

代码
1、重写security 的UserDetailsService方法

package com.xxx.activiti.config;

import com.xxx.common.core.constant.SecurityConstants;
import com.xxx.system.api.model.LoginUser;
import com.xxx.system.api.system.RemoteUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private RemoteUserService remoteUserService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        LoginUser user = remoteUserService.getUserInfo(username, SecurityConstants.INNER).getData();
        return createLoginUser(user);
    }

    public UserDetails createLoginUser(LoginUser user) {
        Set<String> postCode = user.getPostCode();
        postCode = postCode.parallelStream().map( s ->  "GROUP_" + s).collect(Collectors.toSet());
        postCode.add("ROLE_ACTIVITI_USER");
        List<SimpleGrantedAuthority> collect = postCode.stream().map(s -> new SimpleGrantedAuthority(s)).collect(Collectors.toList());
        return new User(user.getPermissions(), collect, user.getSysUser());
    }
}

2、给auth赋值

package com.xxx.activiti.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import javax.security.auth.Subject;
import java.util.Collection;

@Component
public class SecurityActivitiUtil {

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    public void logInAs(String username) {
        UserDetails user = userDetailsService.loadUserByUsername(username);
        if (user == null) {
            throw new IllegalStateException("User " + username + " doesn't exist, please provide a valid user");
        }

        Authentication authentication = new Authentication() {
            @Override
            public String getName() {
                return user.getUsername();
            }

            @Override
            public boolean implies(Subject subject) {
                return false;
            }

            @Override
            public Collection<? extends GrantedAuthority> getAuthorities() {
               // Set<String> postCode = user.getPostCode();
                //List<SimpleGrantedAuthority> collect = postCode.stream().map(s -> new SimpleGrantedAuthority(s)).collect(Collectors.toList());
                return user.getAuthorities();
            }

            @Override
            public Object getCredentials() {
                return user.getPassword();
            }

            @Override
            public Object getDetails() {

                return user;
            }

            @Override
            public Object getPrincipal() {

                return user;
            }

            @Override
            public boolean isAuthenticated() {
                return true;
            }

            @Override
            public void setAuthenticated(boolean b) throws IllegalArgumentException {

            }
        };

        SecurityContextImpl securityContext = new SecurityContextImpl();
        securityContext.setAuthentication(authentication);
        SecurityContextHolder.setContext(securityContext);
        org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(username);
    }
}

3、在每次调用工作流的方法前调用

 SysUser sysUser= SecurityUtils.getLoginUser().getSysUser();
        //activiti7 权限认证
        securityActivitiUtil.logInAs(sysUser.getUserName());

4、另外说一下 remoteUserService.getUserInfo大致内容:
主要是通过username获取用户信息,最重要的是包括roles集合:

/**
     * 获取当前用户信息
     */
    @InnerAuth
    @GetMapping("/info/{username}")
    public R<LoginUser> info(@PathVariable("username") String username)
    {
        SysUser sysUser = userService.selectUserByUserName(username);
        if (StringUtils.isNull(sysUser))
        {
            return R.fail("用户名或密码错误");
        }
        // 角色集合
        Set<String> roles = permissionService.getRolePermission(sysUser.getUserId());
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(sysUser.getUserId());
        Set<String> postCode = postService.selectPostCodeByUserId(sysUser.getUserId());
        postCode = postCode.parallelStream().map( s ->  "GROUP_" + s).collect(Collectors.toSet());
        LoginUser sysUserVo = new LoginUser();
        sysUserVo.setSysUser(sysUser);
        sysUserVo.setRoles(roles);
        sysUserVo.setPermissions(permissions);
        sysUserVo.setPostCode(postCode);
        return R.ok(sysUserVo);
    }

如果有人用过security做登录权限验证,那么这个问题很简单

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值