如何安装使用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的主要内容,如果未能解决你的问题,请参考以下文章
[5]深入浅出工作开源框架Camunda: 解读 camunda-webapp 笔记
[3] 深入浅出工作开源框架Camunda: Camunda 切换到MySQL数据库