Skip to content

Commit

Permalink
Merge pull request apache#519 from githublaohu/feature_acl
Browse files Browse the repository at this point in the history
[ISSUE#403]Implement the acl strandard for rocketmq
  • Loading branch information
dongeforever authored Nov 9, 2018
2 parents aeea021 + 11d3df6 commit 2d4cda2
Show file tree
Hide file tree
Showing 31 changed files with 508 additions and 110 deletions.
4 changes: 2 additions & 2 deletions acl-plug/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
<artifactId>rocketmq-all</artifactId>
<version>4.4.0-SNAPSHOT</version>
</parent>
<artifactId>rocketmq-acl-plug</artifactId>
<name>rocketmq-acl-plug ${project.version}</name>
<artifactId>rocketmq-acl</artifactId>
<name>rocketmq-acl ${project.version}</name>

<url>http://maven.apache.org</url>
<properties>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,16 @@
public interface AccessValidator {
/**
* Parse to get the AccessResource(user, resource, needed permission)
*
* @param request
* @return
*/
AccessResource parse(RemotingCommand request);
AccessResource parse(RemotingCommand request, String remoteAddr);

/**
* Validate the access resource.
*
* @param accessResource
*/
void validate(AccessResource accessResource) ;
void validate(AccessResource accessResource);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@

public class DefaultAccessValidator implements AccessValidator {

@Override public AccessResource parse(RemotingCommand request) {
@Override
public AccessResource parse(RemotingCommand request, String remoteAddr) {
return null;
}

@Override public void validate(AccessResource accessResource) {
@Override
public void validate(AccessResource accessResource) {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@
*/
package org.apache.rocketmq.acl.plug;

import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.acl.plug.entity.AccessControl;
import org.apache.rocketmq.acl.plug.exception.AclPlugRuntimeException;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.acl.plug.entity.AccessControl;
import org.apache.rocketmq.acl.plug.exception.AclPlugRuntimeException;

public class AccessContralAnalysis {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
public class Authentication {

public boolean authentication(AuthenticationInfo authenticationInfo,
AccessControl accessControl, AuthenticationResult authenticationResult) {
AccessControl accessControl, AuthenticationResult authenticationResult) {
int code = accessControl.getCode();
if (!authenticationInfo.getAuthority().get(code)) {
authenticationResult.setResultString(String.format("code is %d Authentication failed", code));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,28 @@
*/
package org.apache.rocketmq.acl.plug;

import java.util.HashMap;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.acl.AccessResource;
import org.apache.rocketmq.acl.AccessValidator;
import org.apache.rocketmq.acl.plug.engine.AclPlugEngine;
import org.apache.rocketmq.acl.plug.engine.PlainAclPlugEngine;
import org.apache.rocketmq.acl.plug.entity.AccessControl;
import org.apache.rocketmq.acl.plug.entity.AuthenticationResult;
import org.apache.rocketmq.acl.plug.entity.ControllerParameters;
import org.apache.rocketmq.acl.plug.exception.AclPlugRuntimeException;
import org.apache.rocketmq.remoting.protocol.RemotingCommand;

public class DefaultAclRemotingServiceImpl implements AclRemotingService {
public class DefaultAclRemotingServiceImpl implements AclRemotingService, AccessValidator {

private AclPlugEngine aclPlugEngine;

public DefaultAclRemotingServiceImpl() {
ControllerParameters controllerParameters = new ControllerParameters();
this.aclPlugEngine = new PlainAclPlugEngine(controllerParameters);
this.aclPlugEngine.initialize();
}

public DefaultAclRemotingServiceImpl(AclPlugEngine aclPlugEngine) {
this.aclPlugEngine = aclPlugEngine;
}
Expand All @@ -41,4 +54,34 @@ public AuthenticationResult check(AccessControl accessControl) {
return authenticationResult;
}

@Override
public AccessResource parse(RemotingCommand request, String remoteAddr) {
HashMap<String, String> extFields = request.getExtFields();
AccessControl accessControl = new AccessControl();
accessControl.setCode(request.getCode());
accessControl.setRecognition(remoteAddr);
accessControl.setNetaddress(StringUtils.split(remoteAddr, ":")[0]);
if (extFields != null) {
accessControl.setAccount(extFields.get("account"));
accessControl.setPassword(extFields.get("password"));
accessControl.setTopic(extFields.get("topic"));
}
return accessControl;
}

@Override
public void validate(AccessResource accessResource) {
try {
AuthenticationResult authenticationResult = aclPlugEngine.eachCheckAuthentication((AccessControl) accessResource);
if (authenticationResult.getException() != null) {
throw new AclPlugRuntimeException(String.format("eachCheck the inspection appear exception, accessControl data is %s", accessResource.toString()), authenticationResult.getException());
}
if (authenticationResult.getAccessControl() == null || !authenticationResult.isSucceed()) {
throw new AclPlugRuntimeException(String.format("%s accessControl data is %s", authenticationResult.getResultString(), accessResource.toString()));
}
} catch (Exception e) {
throw new AclPlugRuntimeException(String.format("validate exception AccessResource data %s", accessResource.toString()), e);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,7 @@ public interface AclPlugEngine {

public AuthenticationResult eachCheckLoginAndAuthentication(AccessControl accessControl);

public AuthenticationResult eachCheckAuthentication(AccessControl accessControl);

public void initialize();
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
*/
package org.apache.rocketmq.acl.plug.engine;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.rocketmq.acl.plug.AccessContralAnalysis;
import org.apache.rocketmq.acl.plug.Authentication;
import org.apache.rocketmq.acl.plug.entity.AccessControl;
Expand All @@ -37,7 +39,7 @@ public abstract class AuthenticationInfoManagementAclPlugEngine implements AclPl

private static final InternalLogger log = InternalLoggerFactory.getLogger(LoggerName.ACL_PLUG_LOGGER_NAME);
ControllerParameters controllerParameters;
private Map<String/** account **/, Map<String/** netaddress **/, AuthenticationInfo>> accessControlMap = new HashMap<>();
private Map<String/** account **/, List<AuthenticationInfo>> accessControlMap = new HashMap<>();
private AuthenticationInfo authenticationInfo;
private NetaddressStrategyFactory netaddressStrategyFactory = new NetaddressStrategyFactory();
private AccessContralAnalysis accessContralAnalysis = new AccessContralAnalysis();
Expand All @@ -54,16 +56,16 @@ public void setAccessControl(AccessControl accessControl) throws AclPlugRuntimeE
}
try {
NetaddressStrategy netaddressStrategy = netaddressStrategyFactory.getNetaddressStrategy(accessControl);
Map<String, AuthenticationInfo> accessControlAddressMap = accessControlMap.get(accessControl.getAccount());
if (accessControlAddressMap == null) {
accessControlAddressMap = new HashMap<>();
accessControlMap.put(accessControl.getAccount(), accessControlAddressMap);
List<AuthenticationInfo> accessControlAddressList = accessControlMap.get(accessControl.getAccount());
if (accessControlAddressList == null) {
accessControlAddressList = new ArrayList<>();
accessControlMap.put(accessControl.getAccount(), accessControlAddressList);
}
AuthenticationInfo authenticationInfo = new AuthenticationInfo(accessContralAnalysis.analysis(accessControl), accessControl, netaddressStrategy);
accessControlAddressMap.put(accessControl.getNetaddress(), authenticationInfo);
accessControlAddressList.add(authenticationInfo);
log.info("authenticationInfo is {}", authenticationInfo.toString());
} catch (Exception e) {
throw new AclPlugRuntimeException(String.format("Exception info %s %s" ,e.getMessage() , accessControl.toString()), e);
throw new AclPlugRuntimeException(String.format("Exception info %s %s", e.getMessage(), accessControl.toString()), e);
}
}

Expand All @@ -84,24 +86,19 @@ public void setNetaddressAccessControl(AccessControl accessControl) throws AclPl
}

public AuthenticationInfo getAccessControl(AccessControl accessControl) {
AuthenticationInfo existing = null;
if (accessControl.getAccount() == null && authenticationInfo != null) {
existing = authenticationInfo.getNetaddressStrategy().match(accessControl) ? authenticationInfo : null;
return authenticationInfo.getNetaddressStrategy().match(accessControl) ? authenticationInfo : null;
} else {
Map<String, AuthenticationInfo> accessControlAddressMap = accessControlMap.get(accessControl.getAccount());
if (accessControlAddressMap != null) {
existing = accessControlAddressMap.get(accessControl.getNetaddress());
if (existing == null)
return null;
if (existing.getAccessControl().getPassword().equals(accessControl.getPassword())) {
if (existing.getNetaddressStrategy().match(accessControl)) {
return existing;
List<AuthenticationInfo> accessControlAddressList = accessControlMap.get(accessControl.getAccount());
if (accessControlAddressList != null) {
for (AuthenticationInfo ai : accessControlAddressList) {
if (ai.getNetaddressStrategy().match(accessControl) && ai.getAccessControl().getPassword().equals(accessControl.getPassword())) {
return ai;
}
}
existing = null;
}
}
return existing;
return null;
}

@Override
Expand All @@ -112,13 +109,29 @@ public AuthenticationResult eachCheckLoginAndAuthentication(AccessControl access
if (authenticationInfo != null) {
boolean boo = authentication.authentication(authenticationInfo, accessControl, authenticationResult);
authenticationResult.setSucceed(boo);
authenticationResult.setAccessControl(authenticationInfo.getAccessControl());
}
} catch (Exception e) {
authenticationResult.setException(e);
}
return authenticationResult;
}

public AuthenticationResult eachCheckAuthentication(AccessControl accessControl) {
AuthenticationResult authenticationResult = new AuthenticationResult();
AuthenticationInfo authenticationInfo = getAccessControl(accessControl);
if (authenticationInfo != null) {
boolean boo = authentication.authentication(authenticationInfo, accessControl, authenticationResult);
authenticationResult.setSucceed(boo);
authenticationResult.setAccessControl(authenticationInfo.getAccessControl());
} else {
authenticationResult.setResultString("accessControl is null, Please check login, password, IP\"");
}


return authenticationResult;
}

void setBorkerAccessControlTransport(BorkerAccessControlTransport transport) {
if (transport.getOnlyNetAddress() == null && (transport.getList() == null || transport.getList().size() == 0)) {
throw new AclPlugRuntimeException("onlyNetAddress and list can't be all empty");
Expand All @@ -135,5 +148,5 @@ void setBorkerAccessControlTransport(BorkerAccessControlTransport transport) {
}

protected abstract AuthenticationInfo getAuthenticationInfo(AccessControl accessControl,
AuthenticationResult authenticationResult);
AuthenticationResult authenticationResult);
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.rocketmq.acl.plug.entity.AccessControl;
import org.apache.rocketmq.acl.plug.entity.AuthenticationInfo;
import org.apache.rocketmq.acl.plug.entity.AuthenticationResult;
Expand Down Expand Up @@ -53,7 +54,7 @@ public void deleteLoginInfo(String remoteAddr) {
}

protected AuthenticationInfo getAuthenticationInfo(AccessControl accessControl,
AuthenticationResult authenticationResult) {
AuthenticationResult authenticationResult) {
LoginInfo loginInfo = getLoginInfo(accessControl);
if (loginInfo != null && loginInfo.getAuthenticationInfo() != null) {
return loginInfo.getAuthenticationInfo();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,19 @@
*/
package org.apache.rocketmq.acl.plug.engine;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import org.apache.rocketmq.acl.plug.entity.BorkerAccessControlTransport;
import org.apache.rocketmq.acl.plug.entity.ControllerParameters;
import org.apache.rocketmq.acl.plug.exception.AclPlugRuntimeException;
import org.yaml.snakeyaml.Yaml;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class PlainAclPlugEngine extends LoginInfoAclPlugEngine {

public PlainAclPlugEngine(
ControllerParameters controllerParameters) throws AclPlugRuntimeException {
ControllerParameters controllerParameters) throws AclPlugRuntimeException {
super(controllerParameters);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
*/
package org.apache.rocketmq.acl.plug.entity;

public class AccessControl {
import org.apache.rocketmq.acl.AccessResource;

public class AccessControl implements AccessResource {

private String account;

Expand Down Expand Up @@ -85,8 +87,8 @@ public void setTopic(String topic) {
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("AccessControl [account=").append(account).append(", password=").append(password)
.append(", netaddress=").append(netaddress).append(", recognition=").append(recognition)
.append(", code=").append(code).append(", topic=").append(topic).append("]");
.append(", netaddress=").append(netaddress).append(", recognition=").append(recognition)
.append(", code=").append(code).append(", topic=").append(topic).append("]");
return builder.toString();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@
*/
package org.apache.rocketmq.acl.plug.entity;

import org.apache.rocketmq.acl.plug.strategy.NetaddressStrategy;

import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.rocketmq.acl.plug.strategy.NetaddressStrategy;

public class AuthenticationInfo {

Expand All @@ -30,7 +31,7 @@ public class AuthenticationInfo {
private Map<Integer, Boolean> authority;

public AuthenticationInfo(Map<Integer, Boolean> authority, AccessControl accessControl,
NetaddressStrategy netaddressStrategy) {
NetaddressStrategy netaddressStrategy) {
super();
this.authority = authority;
this.accessControl = accessControl;
Expand Down Expand Up @@ -65,7 +66,7 @@ public void setAuthority(Map<Integer, Boolean> authority) {
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("AuthenticationInfo [accessControl=").append(accessControl).append(", netaddressStrategy=")
.append(netaddressStrategy).append(", authority={");
.append(netaddressStrategy).append(", authority={");
Iterator<Entry<Integer, Boolean>> it = authority.entrySet().iterator();
while (it.hasNext()) {
Entry<Integer, Boolean> e = it.next();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -556,8 +556,8 @@ public void setQueryConsumeQueue(boolean queryConsumeQueue) {
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("BorkerAccessControl [permitSendTopic=").append(permitSendTopic).append(", noPermitSendTopic=")
.append(noPermitSendTopic).append(", permitPullTopic=").append(permitPullTopic)
.append(", noPermitPullTopic=").append(noPermitPullTopic);
.append(noPermitSendTopic).append(", permitPullTopic=").append(permitPullTopic)
.append(", noPermitPullTopic=").append(noPermitPullTopic);
if (!!sendMessage)
builder.append(", sendMessage=").append(sendMessage);
if (!!sendMessageV2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@
*/
package org.apache.rocketmq.acl.plug.entity;

import org.apache.rocketmq.common.MixAll;
import org.apache.rocketmq.common.protocol.RequestCode;

public class ControllerParameters {

private String fileHome;
private String fileHome = System.getProperty(MixAll.ROCKETMQ_HOME_PROPERTY, System.getenv(MixAll.ROCKETMQ_HOME_ENV));

private Class<?> accessContralAnalysisClass = RequestCode.class;

Expand All @@ -44,7 +45,7 @@ public void setAccessContralAnalysisClass(Class<?> accessContralAnalysisClass) {
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("ControllerParametersEntity [fileHome=").append(fileHome).append(", accessContralAnalysisClass=")
.append(accessContralAnalysisClass).append("]");
.append(accessContralAnalysisClass).append("]");
return builder.toString();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ public void setClear(AtomicBoolean clear) {
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("LoginInfo [recognition=").append(recognition).append(", loginTime=").append(loginTime)
.append(", operationTime=").append(operationTime).append(", clear=").append(clear)
.append(", authenticationInfo=").append(authenticationInfo).append("]");
.append(", operationTime=").append(operationTime).append(", clear=").append(clear)
.append(", authenticationInfo=").append(authenticationInfo).append("]");
return builder.toString();
}

Expand Down
Loading

0 comments on commit 2d4cda2

Please sign in to comment.