如何安装使用camunda

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何安装使用camunda相关的知识,希望对你有一定的参考价值。

如何安装使用camunda,详细步骤,万分感谢

参考技术A 不推荐使用这个,考虑activiti或者flowable,用的人多资料也多,这个有啥坑遇到了都没地方查资料解决,安装前提需要java环境,jdk1.8 参考技术B 你这个是什么东西

[5]深入浅出工作开源框架Camunda: 解读 camunda-webapp 笔记

本文的背景是基于camunda 7.16的版本;Camunda 7.16的运行版本在《[1]深入浅出工作开源框架Camunda: 安装和使用》 一文中已经提到如何下载;其默认访问的URL为http://127.0.0.1:8080/camunda/app/welcome/default/#!/welcome

那么上面的Camunda Web程序是如何工作的?其代码原理是什么呢?本章节笔者将会把我最近研究的结果和大家一起以笔记的形式分享。
(1)Web的应用程序在运行的程序中被拆成了两个jar

存放的是基于一个基于Spring的Web应用程序(注意其还不是SpringBoot的应用程序)

另外一个是封装了JS和CSS的Webjar,其代码结构如下:

需要注意的是,其里面有一个META-INF.resources.webjars.camunda.securityFilterRules.json


  "pathFilter": 
    "deniedPaths" : [
       "path": "/api/engine/.*", "methods" : "*" ,
       "path": "/api/cockpit/.*", "methods" : "*" ,
       "path": "/api/tasklist/.*", "methods" : "*" ,
       "path": "/api/admin/.*", "methods" : "*" ,
       "path": "/app/tasklist/engine/.*", "methods" : "*" ,
       "path": "/app/cockpit/engine/.*", "methods" : "*" ,
       "path": "/app/welcome/engine/.*", "methods" : "*" ,
       "path": "/app/admin/engine/.*", "methods" : "*" 
    ],
    "allowedPaths" : [
       "path": "/api/engine/engine/", "methods" : "GET" ,
       "path": "/api/app:cockpit/plugin/plugin/static/.*", "methods" : "GET" ,
       "path": "/api/app:cockpit/plugin/plugin/engine/.*", "methods" : "*", "authorizer" : "org.camunda.bpm.webapp.impl.security.filter.EngineRequestAuthorizer" ,
       "path": "/api/engine/engine/engine/identity/password-policy", "methods" : "GET" ,
       "path": "/api/engine/engine/engine/identity/password-policy", "methods" : "POST" ,
       "path": "/api/admin/auth/user/engine", "methods" : "GET" ,
       "path": "/api/admin/auth/user/engine/logout", "methods" : "POST" ,
       "path": "/api/admin/auth/user/engine/login/app", "methods" : "POST" ,
       "path": "/api/admin/auth/user/engine/.*", "methods" : "*", "authorizer" : "org.camunda.bpm.webapp.impl.security.filter.EngineRequestAuthorizer" ,
       "path": "/api/admin/setup/engine/user/create", "methods" : "POST" ,
       "path": "/api/admin/setup/engine/.*", "methods" : "*", "authorizer" : "org.camunda.bpm.webapp.impl.security.filter.EngineRequestAuthorizer" ,
       "path": "/api/app:admin/plugin/license/engine/check-key", "methods" : "GET" ,
       "path": "/api/app:admin/plugin/plugin/static/.*", "methods" : "GET" ,
       "path": "/api/app:admin/plugin/plugin/engine/.*", "methods" : "*", "authorizer" : "org.camunda.bpm.webapp.impl.security.filter.EngineRequestAuthorizer" ,
       "path": "/api/app:tasklist/plugin/plugin/static/.*", "methods" : "GET" ,
       "path": "/api/app:tasklist/plugin/plugin/engine/.*", "methods" : "*", "authorizer" : "org.camunda.bpm.webapp.impl.security.filter.EngineRequestAuthorizer" ,
       "path": "/api/engine/engine/engine/.*", "methods" : "*", "authorizer" : "org.camunda.bpm.webapp.impl.security.filter.EngineRequestAuthorizer" ,
       "path": "/app/app:cockpit/engine/.*", "methods" : "*", "authorizer" : "org.camunda.bpm.webapp.impl.security.filter.ApplicationRequestAuthorizer" ,
       "path": "/app/app:tasklist/engine/.*", "methods" : "*", "authorizer" : "org.camunda.bpm.webapp.impl.security.filter.ApplicationRequestAuthorizer" ,
       "path": "/app/app:welcome/engine/.*", "methods" : "*", "authorizer" : "org.camunda.bpm.webapp.impl.security.filter.ApplicationRequestAuthorizer" ,
       "path": "/app/app:admin/engine/.*", "methods" : "*", "authorizer" : "org.camunda.bpm.webapp.impl.security.filter.ApplicationRequestAuthorizer" 
    ]
  


其定义了基本的Filter的原则。其包括了两方面的授权Filter:

  • org.camunda.bpm.webapp.impl.security.filter.EngineRequestAuthorizer
    针对Camunda的API的请求的授权,其代码如下:
package org.camunda.bpm.webapp.impl.security.filter;
import java.util.Map;
import org.camunda.bpm.webapp.impl.security.auth.Authentication;
import org.camunda.bpm.webapp.impl.security.auth.Authentications;
/**
 * <p>This is a @link RequestAuthorizer which authorizes all process engine api
 * requests based on the current authentication</p>
 *
 * @author Daniel Meyer
 * @author nico.rehwaldt
 */
public class EngineRequestAuthorizer implements RequestAuthorizer 

  @Override
  public Authorization authorize(Map<String, String> parameters) 

    Authentications authentications = Authentications.getCurrent();
    if (authentications == null) 
      // no authentications --> reject request to app
      return Authorization.denied(Authentication.ANONYMOUS);
     else 
      String engineName = parameters.get("engine");

      Authentication engineAuth = authentications.getAuthenticationForProcessEngine(engineName);

      return Authorization.grantedUnlessNull(engineAuth);
    
  


从上面来看,当前的所有的认证信息,都是存放在调用org.camunda.bpm.webapp.impl.security.auth.Authentications 类的ThreadLocal当中,其会维护一个
authentications 的Map,其键值是engineName的名字,其值是一个org.camunda.bpm.webapp.impl.security.auth.Authentication的对象。

protected Map<String, Authentication> authentications = new HashMap<String, Authentication>();

org.camunda.bpm.webapp.impl.security.auth.Authentication的结构如下:

package org.camunda.bpm.webapp.impl.security.auth;

import java.io.Serializable;
import java.security.Principal;

/**
 * <p>Represents an active authentication of a given identity (usually a user).</p>
 *
 * <p>In camunda webapps, an authentication exists between some identity (user) and
 * a process engine</p>
 *
 * <p>Implements java.security.Principal so that this object may be used everywhere where a
 * @link Principal is required.</p>
 *
 * @author Daniel Meyer
 *
 */
public class Authentication implements Principal, Serializable 

  public static final Authentication ANONYMOUS = new Authentication(null, null);
  
  private static final long serialVersionUID = 1L;

  protected final String identityId;

  protected final String processEngineName;

  public Authentication(String identityId, String processEngineName) 
    this.identityId = identityId;
    this.processEngineName = processEngineName;
  

  /**
   * java.security.Principal implementation: return the id of the identity
   * (userId) behind this authentication
   */
  public String getName() 
    return identityId;
  

  /**
   * @return the id of the identity
   * (userId) behind this authentication
   */
  public String getIdentityId() 
    return identityId;
  

  /**
   * @return return the name of the process engine for which this authentication
   *         was established.
   */
  public String getProcessEngineName() 
    return processEngineName;
  

当前只有实现Authentication的子类只有一个org.camunda.bpm.webapp.impl.security.auth.UserAuthentication, 其里面会包括下面的用户相关的信息:

  protected List<String> groupIds;
  protected List<String> tenantIds;
  protected Set<String> authorizedApps;

另外从上面的代码可以看出,其只管engine的rest-api 相关的授权即可;

  • org.camunda.bpm.webapp.impl.security.filter.ApplicationRequestAuthorizer
    针对Camunda的Application的请求的授权,比如CSS,JS,HTML等
package org.camunda.bpm.webapp.impl.security.filter;

import java.util.Map;
import org.camunda.bpm.cockpit.Cockpit;
import org.camunda.bpm.engine.ProcessEngine;
import org.camunda.bpm.webapp.impl.security.auth.Authentication;
import org.camunda.bpm.webapp.impl.security.auth.Authentications;
import org.camunda.bpm.webapp.impl.security.auth.UserAuthentication;

/**
 * <p>This matcher can be used for restricting access to an app.</p>
 *
 * @author Daniel Meyer
 * @author nico.rehwaldt
 */
public class ApplicationRequestAuthorizer implements RequestAuthorizer 

  @Override
  public Authorization authorize(Map<String, String> parameters) 
    Authentications authentications = Authentications.getCurrent();

    if (authentications == null) 
      // the user is not authenticated
      // grant user anonymous access
      return grantAnnonymous();
     else 
      String engineName = parameters.get("engine");
      String appName = parameters.get("app");

      Authentication engineAuth = authentications.getAuthenticationForProcessEngine(engineName);
      if (engineAuth == null) 
        // the user is not authenticated
        // grant user anonymous access
        return grantAnnonymous();
      

      // get process engine
      ProcessEngine processEngine = Cockpit.getProcessEngine(engineName);
      if (processEngine == null) 
        // the process engine does not exist
        // grant user anonymous access
        return grantAnnonymous();
      

      // check authorization
      if (engineAuth instanceof UserAuthentication) 
        UserAuthentication userAuth = (UserAuthentication) engineAuth;

        if (userAuth.isAuthorizedForApp(appName)) 
          return Authorization.granted(userAuth).forApplication(appName);
         else 
          return Authorization.denied(userAuth).forApplication(appName);
        
      
    

    // no auth granted
    return Authorization.denied(Authentication.ANONYMOUS);
  

  private Authorization grantAnnonymous() 
    return Authorization.granted(Authentication.ANONYMOUS);
  


从上面的代码可以看出,其会先去获取engine的授权,如果没有的话,则直接返回并拒绝;
然后再从org.camunda.bpm.cockpit.Cockpit的类里面通过代理org.camunda.bpm.cockpit.impl.DefaultCockpitRuntimeDelegate 获取ProcessEngine的对象。
如果ProcessEngine返回的是空对象,则认为没有认证,并返回。

如果都有的话,则转换成为一个UserAuthentication的对象,并返回给上下文。

默认情况下是匿名的授权:

  public static class AnnonymousAuthorizer implements RequestAuthorizer 

    @Override
    public Authorization authorize(Map<String, String> parameters) 
      return Authorization.granted(Authentication.ANONYMOUS);
    
  

RequestAuthorizer.class是一个接口,其只有一个方法:

package org.camunda.bpm.webapp.impl.security.filter;

import java.util.Map;
import org.camunda.bpm.webapp.impl.security.auth.Authentication;

/**
 * The interface for request authorizers.
 * @author nico.rehwaldt
 */
public interface RequestAuthorizer 

  public static final RequestAuthorizer AUTHORIZE_ANNONYMOUS = new AnnonymousAuthorizer();

  /**
   * Authorize a request with the given parameters by returning a valid @link Authentication.
   *
   * @param parameters
   *
   * @return a valid @link Authentication or <code>null</code> if authorization to this request
   *         has not been granted
   */
  public Authorization authorize(Map<String, String> parameters);

再回头来看看securityFilterRules.json是如何被应用的?其会被 org.camunda.bpm.webapp.impl.security.filter.PathFilterRule 所读取使用。


package org.camunda.bpm.webapp.impl.security.filter;

import java.util.ArrayList;
import java.util.List;
import org.camunda.bpm.webapp.impl.security.auth.Authentication;
import org.camunda.bpm.webapp.impl.security.filter.RequestMatcher.Match;
import org.camunda.bpm.webapp.impl.security.filter.util.FilterRules;
import org.springframework.util.PathMatcher;

/**
 * <p>A @link SecurityFilterRule that deleagates to a set of @link PathMatchers</p>
 *
 * <p>How this thing works:
 * <ul>
 * <li> A path that is not listed in <code>deniedPaths</code> is always granted anonymous access
 *  (even if the user is authenticated for a process engine).
 * <li> A path that is listed in <code>deniedPaths</code> is then also checked against <code>allowedPaths</code>.
 * <li> A path that is listed in <code>allowedPaths</code> is checked by the
 *  corresponding @link RequestAuthorizer that can decide to grant/deny (identified or anonymous) access.
 * <li> A path that is not listed in <code>allowedPaths</code> is always granted anonymous access
 *  (via @link FilterRules#authorize(String, String, List))
 *
 * @author Daniel Meyer
 * @author nico.rehwaldt
 */
public class PathFilterRule implements SecurityFilterRule 

  protected List<RequestMatcher> allowedPaths = new ArrayList<>();
  protected List<RequestMatcher> deniedPaths = new ArrayList<>();

  @Override
  public Authorization authorize(String requestMethod, String requestUri) 

    boolean secured = false;


    for (RequestMatcher pattern : deniedPaths) 
      Match match = pattern.match(requestMethod, requestUri);

      if (match != null) 
        secured = true;
        break;
      
    

    if (!secured) 
      return Authorization.granted(Authentication.ANONYMOUS);
    

    for (RequestMatcher pattern : allowedPaths) 
      Match match = pattern.match(requestMethod, requestUri);

      if (match != null) 
        return match.authorize();
      
    

    return null;
  

  public List<RequestMatcher> getAllowedPaths() 
    return allowedPaths;
  

  public List<RequestMatcher> getDeniedPaths() 
    return deniedPaths;
  


PathFilterRule 会被org.camunda.bpm.webapp.impl.security.filter.util.FilterRules 引用,

package org.camunda.bpm.webapp.impl.security.filter.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.camunda.bpm.engine.impl.util.ReflectUtil;
import org.camunda.bpm.webapp.impl.security.auth.Authentication;
import org.camunda.以上是关于如何安装使用camunda的主要内容,如果未能解决你的问题,请参考以下文章

用于嵌入式安装的 Camunda 身份服务

[5]深入浅出工作开源框架Camunda: 解读 camunda-webapp 笔记

[3] 深入浅出工作开源框架Camunda: Camunda 切换到MySQL数据库

3流程引擎下载安装与部署

Camunda BPM Spring启动无法启动weblogic - 也许是泽西问题

如何使用cli将历史级别更改为camunda中的活动