mirror of https://github.com/apache/nifi.git
NIFI-1552: - Introducing the Authorizer API and additional components necessary for discovery and creation of configured instances. - Minor refactoring of existing Authority Provider API code/configuration to avoid some xsd naming conflicts. These components will be removed in NIFI-1551. - Introducing a number of the resource definitions that the Authorizer will make access decisions on. This list is likely not finalized may see some changes in NIFI-1554. - Address comments from PR. - This closes #318.
Signed-off-by: Matt Gilman <matt.c.gilman@gmail.com>
This commit is contained in:
parent
1ac05266a5
commit
9aa69b242e
|
@ -5,8 +5,6 @@ os:
|
|||
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
- oraclejdk7
|
||||
- openjdk7
|
||||
|
||||
# before_install aids in a couple workarounds for issues within the Travis-CI environment
|
||||
# 1. Workaround for buffer overflow issues with OpenJDK versions of java as per https://github.com/travis-ci/travis-ci/issues/5227#issuecomment-165135711
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.authorization;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents an authorization request for a given user/entity performing an action against a resource within some context.
|
||||
*/
|
||||
public class AuthorizationRequest {
|
||||
|
||||
private final Resource resource;
|
||||
private final String identity;
|
||||
private final RequestAction action;
|
||||
private final Map<String, String> context;
|
||||
private final Map<String, String> eventAttributes;
|
||||
|
||||
private AuthorizationRequest(final Builder builder) {
|
||||
Objects.requireNonNull(builder.resource, "The resource is required when creating an authorization request");
|
||||
Objects.requireNonNull(builder.identity, "The identity of the user is required when creating an authorization request");
|
||||
Objects.requireNonNull(builder.action, "The action is required when creating an authorization request");
|
||||
|
||||
this.resource = builder.resource;
|
||||
this.identity = builder.identity;
|
||||
this.action = builder.action;
|
||||
this.context = Collections.unmodifiableMap(builder.context);
|
||||
this.eventAttributes = Collections.unmodifiableMap(builder.eventAttributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* The Resource being authorized. Not null.
|
||||
*
|
||||
* @return The resource
|
||||
*/
|
||||
public Resource getResource() {
|
||||
return resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* The identity accessing the Resource. Not null.
|
||||
*
|
||||
* @return The identity
|
||||
*/
|
||||
public String getIdentity() {
|
||||
return identity;
|
||||
}
|
||||
|
||||
/**
|
||||
* The action being taken against the Resource. Not null.
|
||||
*
|
||||
* @return The action
|
||||
*/
|
||||
public RequestAction getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
/**
|
||||
* The context of the user request to make additional access decisions. May be null.
|
||||
*
|
||||
* @return The context of the user request
|
||||
*/
|
||||
public Map<String, String> getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* The event attributes to make additional access decisions for provenance events. May be null.
|
||||
*
|
||||
* @return The event attributes
|
||||
*/
|
||||
public Map<String, String> getEventAttributes() {
|
||||
return eventAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* AuthorizationRequest builder.
|
||||
*/
|
||||
public static final class Builder {
|
||||
|
||||
private Resource resource;
|
||||
private String identity;
|
||||
private RequestAction action;
|
||||
private Map<String, String> context;
|
||||
private Map<String, String> eventAttributes;
|
||||
|
||||
public Builder resource(final Resource resource) {
|
||||
this.resource = resource;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder identity(final String identity) {
|
||||
this.identity = identity;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder action(final RequestAction action) {
|
||||
this.action = action;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder context(final Map<String, String> context) {
|
||||
this.context = new HashMap<>(context);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder eventAttributes(final Map<String, String> eventAttributes) {
|
||||
this.eventAttributes = new HashMap<>(eventAttributes);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AuthorizationRequest build() {
|
||||
return new AuthorizationRequest(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.authorization;
|
||||
|
||||
/**
|
||||
* Represents a decision whether authorization is granted.
|
||||
*/
|
||||
public class AuthorizationResult {
|
||||
|
||||
private enum Result {
|
||||
Approved,
|
||||
Denied,
|
||||
ResourceNotFound
|
||||
}
|
||||
|
||||
private static final AuthorizationResult APPROVED = new AuthorizationResult(Result.Approved, null);
|
||||
private static final AuthorizationResult RESOURCE_NOT_FOUND = new AuthorizationResult(Result.ResourceNotFound, null);
|
||||
|
||||
private final Result result;
|
||||
private final String explanation;
|
||||
|
||||
/**
|
||||
* Creates a new AuthorizationResult with the specified result and explanation.
|
||||
*
|
||||
* @param result of the authorization
|
||||
* @param explanation for the authorization attempt
|
||||
*/
|
||||
private AuthorizationResult(Result result, String explanation) {
|
||||
if (Result.Denied.equals(result) && explanation == null) {
|
||||
throw new IllegalArgumentException("An explanation is required when the authorization request is denied.");
|
||||
}
|
||||
|
||||
this.result = result;
|
||||
this.explanation = explanation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether or not the request is approved
|
||||
*/
|
||||
public Result getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return If the request is denied, the reason why. Null otherwise
|
||||
*/
|
||||
public String getExplanation() {
|
||||
return explanation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a new approved AuthorizationResult
|
||||
*/
|
||||
public static AuthorizationResult approved() {
|
||||
return APPROVED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resource not found will indicate that there are no specific authorization rules for this resource.
|
||||
* @return a new resource not found AuthorizationResult
|
||||
*/
|
||||
public static AuthorizationResult resourceNotFound() {
|
||||
return RESOURCE_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new denied AuthorizationResult with a message indicating 'Access is denied'.
|
||||
*
|
||||
* @return a new denied AuthorizationResult
|
||||
*/
|
||||
public static AuthorizationResult denied() {
|
||||
return denied("Access is denied");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new denied AuthorizationResult with the specified explanation.
|
||||
*
|
||||
* @param explanation for why it was denied
|
||||
* @return a new denied AuthorizationResult with the specified explanation
|
||||
* @throws IllegalArgumentException if explanation is null
|
||||
*/
|
||||
public static AuthorizationResult denied(String explanation) {
|
||||
return new AuthorizationResult(Result.Denied, explanation);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.authorization;
|
||||
|
||||
import org.apache.nifi.authorization.exception.AuthorityAccessException;
|
||||
import org.apache.nifi.authorization.exception.AuthorizationAccessException;
|
||||
import org.apache.nifi.authorization.exception.AuthorizerCreationException;
|
||||
import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
|
||||
import org.apache.nifi.authorization.exception.UnknownIdentityException;
|
||||
|
||||
/**
|
||||
* Authorizes user requests.
|
||||
*/
|
||||
public interface Authorizer {
|
||||
|
||||
/**
|
||||
* Determines if the specified user/entity is authorized to access the specified resource within the given context.
|
||||
*
|
||||
* @param request The authorization request
|
||||
* @return the authorization result
|
||||
* @throws AuthorityAccessException if unable to access the authorities
|
||||
*/
|
||||
AuthorizationResult authorize(AuthorizationRequest request) throws AuthorizationAccessException;
|
||||
|
||||
/**
|
||||
* Called immediately after instance creation for implementers to perform additional setup
|
||||
*
|
||||
* @param initializationContext in which to initialize
|
||||
*/
|
||||
void initialize(AuthorizerInitializationContext initializationContext) throws AuthorizerCreationException;
|
||||
|
||||
/**
|
||||
* Called to configure the Authorizer.
|
||||
*
|
||||
* @param configurationContext at the time of configuration
|
||||
* @throws AuthorizerCreationException for any issues configuring the provider
|
||||
*/
|
||||
void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException;
|
||||
|
||||
/**
|
||||
* Called immediately before instance destruction for implementers to release resources.
|
||||
*
|
||||
* @throws AuthorizerDestructionException If pre-destruction fails.
|
||||
*/
|
||||
void preDestruction() throws AuthorizerDestructionException;
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.authorization;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public interface AuthorizerConfigurationContext {
|
||||
|
||||
/**
|
||||
* @return identifier for the authorizer
|
||||
*/
|
||||
String getIdentifier();
|
||||
|
||||
/**
|
||||
* Retrieves all properties the component currently understands regardless
|
||||
* of whether a value has been set for them or not. If no value is present
|
||||
* then its value is null and thus any registered default for the property
|
||||
* descriptor applies.
|
||||
*
|
||||
* @return Map of all properties
|
||||
*/
|
||||
Map<String, String> getProperties();
|
||||
|
||||
/**
|
||||
* @param property to lookup the descriptor and value of
|
||||
* @return the value the component currently understands for the given
|
||||
* PropertyDescriptor. This method does not substitute default
|
||||
* PropertyDescriptor values, so the value returned will be null if not set
|
||||
*/
|
||||
String getProperty(String property);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.authorization;
|
||||
|
||||
/**
|
||||
* Initialization content for Authorizers.
|
||||
*/
|
||||
public interface AuthorizerInitializationContext {
|
||||
|
||||
/**
|
||||
* The identifier of the Authorizer.
|
||||
*
|
||||
* @return The identifier
|
||||
*/
|
||||
public String getIdentifier();
|
||||
|
||||
/**
|
||||
* The lookup for accessing other configured Authorizers.
|
||||
*
|
||||
* @return The Authorizer lookup
|
||||
*/
|
||||
public AuthorizerLookup getAuthorizerLookup();
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.authorization;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public interface AuthorizerLookup {
|
||||
|
||||
/**
|
||||
* Looks up the Authorizer with the specified identifier
|
||||
*
|
||||
* @param identifier The identifier of the Authorizer
|
||||
* @return The Authorizer
|
||||
*/
|
||||
Authorizer getAuthorizer(String identifier);
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.authorization;
|
||||
|
||||
/**
|
||||
* Actions a user/entity can take on a resource.
|
||||
*/
|
||||
public enum RequestAction {
|
||||
READ,
|
||||
WRITE;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.authorization;
|
||||
|
||||
/**
|
||||
* Resource in an authorization request.
|
||||
*/
|
||||
public interface Resource {
|
||||
|
||||
/**
|
||||
* The identifier for this resource.
|
||||
*
|
||||
* @return identifier for this resource
|
||||
*/
|
||||
String getIdentifier();
|
||||
|
||||
/**
|
||||
* The name of this resource.
|
||||
*
|
||||
* @return name of this resource
|
||||
*/
|
||||
String getName();
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.authorization.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Documented
|
||||
@Target({ElementType.FIELD, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
public @interface AuthorizerContext {
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.authorization.exception;
|
||||
|
||||
/**
|
||||
* Represents the case when an authorization decision could not be made because the Authorizer was unable to access the underlying data store.
|
||||
*/
|
||||
public class AuthorizationAccessException extends RuntimeException {
|
||||
|
||||
public AuthorizationAccessException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public AuthorizationAccessException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.authorization.exception;
|
||||
|
||||
/**
|
||||
* Represents the exceptional case when an Authorizer fails instantiation.
|
||||
*
|
||||
*/
|
||||
public class AuthorizerCreationException extends RuntimeException {
|
||||
|
||||
public AuthorizerCreationException() {
|
||||
}
|
||||
|
||||
public AuthorizerCreationException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public AuthorizerCreationException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public AuthorizerCreationException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.authorization.exception;
|
||||
|
||||
/**
|
||||
* Represents the exceptional case when an Authorizer fails destruction.
|
||||
*
|
||||
*/
|
||||
public class AuthorizerDestructionException extends RuntimeException {
|
||||
|
||||
public AuthorizerDestructionException() {
|
||||
}
|
||||
|
||||
public AuthorizerDestructionException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public AuthorizerDestructionException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public AuthorizerDestructionException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
|
@ -16,6 +16,36 @@
|
|||
*/
|
||||
package org.apache.nifi.authorization;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.authorization.annotation.AuthorityProviderContext;
|
||||
import org.apache.nifi.authorization.exception.AuthorityAccessException;
|
||||
import org.apache.nifi.authorization.exception.IdentityAlreadyExistsException;
|
||||
import org.apache.nifi.authorization.exception.ProviderCreationException;
|
||||
import org.apache.nifi.authorization.exception.ProviderDestructionException;
|
||||
import org.apache.nifi.authorization.exception.UnknownIdentityException;
|
||||
import org.apache.nifi.authorization.generated.AuthorityProviderProperty;
|
||||
import org.apache.nifi.authorization.generated.AuthorityProviders;
|
||||
import org.apache.nifi.authorization.generated.Provider;
|
||||
import org.apache.nifi.nar.ExtensionManager;
|
||||
import org.apache.nifi.nar.NarCloseable;
|
||||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBElement;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import javax.xml.validation.Schema;
|
||||
import javax.xml.validation.SchemaFactory;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
|
@ -27,35 +57,6 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBElement;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import javax.xml.validation.Schema;
|
||||
import javax.xml.validation.SchemaFactory;
|
||||
import org.apache.nifi.authorization.annotation.AuthorityProviderContext;
|
||||
import org.apache.nifi.authorization.exception.AuthorityAccessException;
|
||||
import org.apache.nifi.authorization.exception.IdentityAlreadyExistsException;
|
||||
import org.apache.nifi.authorization.exception.ProviderCreationException;
|
||||
import org.apache.nifi.authorization.exception.ProviderDestructionException;
|
||||
import org.apache.nifi.authorization.exception.UnknownIdentityException;
|
||||
import org.apache.nifi.authorization.generated.AuthorityProviders;
|
||||
import org.apache.nifi.authorization.generated.Property;
|
||||
import org.apache.nifi.authorization.generated.Provider;
|
||||
import org.apache.nifi.nar.ExtensionManager;
|
||||
import org.apache.nifi.nar.NarCloseable;
|
||||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* Factory bean for loading the configured authority provider.
|
||||
|
@ -196,7 +197,7 @@ public class AuthorityProviderFactoryBean implements FactoryBean, ApplicationCon
|
|||
private AuthorityProviderConfigurationContext loadAuthorityProviderConfiguration(final Provider provider) {
|
||||
final Map<String, String> providerProperties = new HashMap<>();
|
||||
|
||||
for (final Property property : provider.getProperty()) {
|
||||
for (final AuthorityProviderProperty property : provider.getProperty()) {
|
||||
providerProperties.put(property.getName(), property.getValue());
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,343 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.authorization;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.authorization.annotation.AuthorizerContext;
|
||||
import org.apache.nifi.authorization.exception.AuthorizationAccessException;
|
||||
import org.apache.nifi.authorization.exception.AuthorizerCreationException;
|
||||
import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
|
||||
import org.apache.nifi.authorization.generated.AuthorityProviders;
|
||||
import org.apache.nifi.authorization.generated.Authorizers;
|
||||
import org.apache.nifi.authorization.generated.Property;
|
||||
import org.apache.nifi.nar.ExtensionManager;
|
||||
import org.apache.nifi.nar.NarCloseable;
|
||||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBElement;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import javax.xml.validation.Schema;
|
||||
import javax.xml.validation.SchemaFactory;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Factory bean for loading the configured authorizer.
|
||||
*/
|
||||
public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, AuthorizerLookup {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AuthorizerFactoryBean.class);
|
||||
private static final String AUTHORIZERS_XSD = "/authorizers.xsd";
|
||||
private static final String JAXB_GENERATED_PATH = "org.apache.nifi.authorization.generated";
|
||||
private static final JAXBContext JAXB_CONTEXT = initializeJaxbContext();
|
||||
|
||||
/**
|
||||
* Load the JAXBContext.
|
||||
*/
|
||||
private static JAXBContext initializeJaxbContext() {
|
||||
try {
|
||||
return JAXBContext.newInstance(JAXB_GENERATED_PATH, AuthorizerFactoryBean.class.getClassLoader());
|
||||
} catch (JAXBException e) {
|
||||
throw new RuntimeException("Unable to create JAXBContext.");
|
||||
}
|
||||
}
|
||||
|
||||
private Authorizer authorizer;
|
||||
private NiFiProperties properties;
|
||||
private final Map<String, Authorizer> authorizers = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public Authorizer getAuthorizer(String identifier) {
|
||||
return authorizers.get(identifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getObject() throws Exception {
|
||||
if (authorizer == null) {
|
||||
// look up the authorizer to use
|
||||
final String authorizerIdentifier = properties.getProperty(NiFiProperties.SECURITY_USER_AUTHORITY_PROVIDER);
|
||||
|
||||
// ensure the authorizer class name was specified
|
||||
if (StringUtils.isBlank(authorizerIdentifier)) {
|
||||
// if configured for ssl, the authorizer must be specified
|
||||
if (properties.getSslPort() != null) {
|
||||
throw new Exception("When running securely, the authorizer identifier must be specified in the nifi properties file.");
|
||||
}
|
||||
|
||||
// use a default authorizer... only allowable when running not securely
|
||||
authorizer = createDefaultAuthorizer();
|
||||
} else {
|
||||
final Authorizers authorizerConfiguration = loadAuthorizersConfiguration();
|
||||
|
||||
// create each authorizer
|
||||
for (final org.apache.nifi.authorization.generated.Authorizer authorizer : authorizerConfiguration.getAuthorizer()) {
|
||||
authorizers.put(authorizer.getIdentifier(), createAuthorizer(authorizer.getIdentifier(), authorizer.getClazz()));
|
||||
}
|
||||
|
||||
// configure each authorizer
|
||||
for (final org.apache.nifi.authorization.generated.Authorizer provider : authorizerConfiguration.getAuthorizer()) {
|
||||
final Authorizer instance = authorizers.get(provider.getIdentifier());
|
||||
instance.onConfigured(loadAuthorizerConfiguration(provider));
|
||||
}
|
||||
|
||||
// get the authorizer instance
|
||||
authorizer = getAuthorizer(authorizerIdentifier);
|
||||
|
||||
// ensure it was found
|
||||
if (authorizer == null) {
|
||||
throw new Exception(String.format("The specified authorizer '%s' could not be found.", authorizerIdentifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return authorizer;
|
||||
}
|
||||
|
||||
private Authorizers loadAuthorizersConfiguration() throws Exception {
|
||||
final File authorizersConfigurationFile = properties.getAuthorityProviderConfiguraitonFile();
|
||||
|
||||
// load the authorizers from the specified file
|
||||
if (authorizersConfigurationFile.exists()) {
|
||||
try {
|
||||
// find the schema
|
||||
final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
||||
final Schema schema = schemaFactory.newSchema(AuthorityProviders.class.getResource(AUTHORIZERS_XSD));
|
||||
|
||||
// attempt to unmarshal
|
||||
final Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller();
|
||||
unmarshaller.setSchema(schema);
|
||||
final JAXBElement<Authorizers> element = unmarshaller.unmarshal(new StreamSource(authorizersConfigurationFile), Authorizers.class);
|
||||
return element.getValue();
|
||||
} catch (SAXException | JAXBException e) {
|
||||
throw new Exception("Unable to load the authorizer configuration file at: " + authorizersConfigurationFile.getAbsolutePath());
|
||||
}
|
||||
} else {
|
||||
throw new Exception("Unable to find the authorizer configuration file at " + authorizersConfigurationFile.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
private Authorizer createAuthorizer(final String identifier, final String authorizerClassName) throws Exception {
|
||||
// get the classloader for the specified authorizer
|
||||
final ClassLoader authorizerClassLoader = ExtensionManager.getClassLoader(authorizerClassName);
|
||||
if (authorizerClassLoader == null) {
|
||||
throw new Exception(String.format("The specified authorizer class '%s' is not known to this nifi.", authorizerClassName));
|
||||
}
|
||||
|
||||
// get the current context classloader
|
||||
final ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
|
||||
final Authorizer instance;
|
||||
try {
|
||||
// set the appropriate class loader
|
||||
Thread.currentThread().setContextClassLoader(authorizerClassLoader);
|
||||
|
||||
// attempt to load the class
|
||||
Class<?> rawAuthorizerClass = Class.forName(authorizerClassName, true, authorizerClassLoader);
|
||||
Class<? extends Authorizer> authorizerClass = rawAuthorizerClass.asSubclass(Authorizer.class);
|
||||
|
||||
// otherwise create a new instance
|
||||
Constructor constructor = authorizerClass.getConstructor();
|
||||
instance = (Authorizer) constructor.newInstance();
|
||||
|
||||
// method injection
|
||||
performMethodInjection(instance, authorizerClass);
|
||||
|
||||
// field injection
|
||||
performFieldInjection(instance, authorizerClass);
|
||||
|
||||
// call post construction lifecycle event
|
||||
instance.initialize(new StandardAuthorizerInitializationContext(identifier, this));
|
||||
} finally {
|
||||
if (currentClassLoader != null) {
|
||||
Thread.currentThread().setContextClassLoader(currentClassLoader);
|
||||
}
|
||||
}
|
||||
|
||||
return withNarLoader(instance);
|
||||
}
|
||||
|
||||
private AuthorizerConfigurationContext loadAuthorizerConfiguration(final org.apache.nifi.authorization.generated.Authorizer authorizer) {
|
||||
final Map<String, String> authorizerProperties = new HashMap<>();
|
||||
|
||||
for (final Property property : authorizer.getProperty()) {
|
||||
authorizerProperties.put(property.getName(), property.getValue());
|
||||
}
|
||||
|
||||
return new StandardAuthorizerConfigurationContext(authorizer.getIdentifier(), authorizerProperties);
|
||||
}
|
||||
|
||||
private void performMethodInjection(final Authorizer instance, final Class authorizerClass) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||
for (final Method method : authorizerClass.getMethods()) {
|
||||
if (method.isAnnotationPresent(AuthorizerContext.class)) {
|
||||
// make the method accessible
|
||||
final boolean isAccessible = method.isAccessible();
|
||||
method.setAccessible(true);
|
||||
|
||||
try {
|
||||
final Class<?>[] argumentTypes = method.getParameterTypes();
|
||||
|
||||
// look for setters (single argument)
|
||||
if (argumentTypes.length == 1) {
|
||||
final Class<?> argumentType = argumentTypes[0];
|
||||
|
||||
// look for well known types
|
||||
if (NiFiProperties.class.isAssignableFrom(argumentType)) {
|
||||
// nifi properties injection
|
||||
method.invoke(instance, properties);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
method.setAccessible(isAccessible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final Class parentClass = authorizerClass.getSuperclass();
|
||||
if (parentClass != null && AuthorityProvider.class.isAssignableFrom(parentClass)) {
|
||||
performMethodInjection(instance, parentClass);
|
||||
}
|
||||
}
|
||||
|
||||
private void performFieldInjection(final Authorizer instance, final Class authorizerClass) throws IllegalArgumentException, IllegalAccessException {
|
||||
for (final Field field : authorizerClass.getDeclaredFields()) {
|
||||
if (field.isAnnotationPresent(AuthorizerContext.class)) {
|
||||
// make the method accessible
|
||||
final boolean isAccessible = field.isAccessible();
|
||||
field.setAccessible(true);
|
||||
|
||||
try {
|
||||
// get the type
|
||||
final Class<?> fieldType = field.getType();
|
||||
|
||||
// only consider this field if it isn't set yet
|
||||
if (field.get(instance) == null) {
|
||||
// look for well known types
|
||||
if (NiFiProperties.class.isAssignableFrom(fieldType)) {
|
||||
// nifi properties injection
|
||||
field.set(instance, properties);
|
||||
}
|
||||
}
|
||||
|
||||
} finally {
|
||||
field.setAccessible(isAccessible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final Class parentClass = authorizerClass.getSuperclass();
|
||||
if (parentClass != null && AuthorityProvider.class.isAssignableFrom(parentClass)) {
|
||||
performFieldInjection(instance, parentClass);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a default Authorizer to use when running unsecurely with no authorizer configured
|
||||
*/
|
||||
private Authorizer createDefaultAuthorizer() {
|
||||
return new Authorizer() {
|
||||
@Override
|
||||
public AuthorizationResult authorize(final AuthorizationRequest request) throws AuthorizationAccessException {
|
||||
return AuthorizationResult.approved();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(AuthorizerInitializationContext initializationContext) throws AuthorizerCreationException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preDestruction() throws AuthorizerDestructionException {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Decorates the base authorizer to ensure the nar context classloader is used when invoking the underlying methods.
|
||||
*
|
||||
* @param baseAuthorizer base authorizer
|
||||
* @return authorizer
|
||||
*/
|
||||
public Authorizer withNarLoader(final Authorizer baseAuthorizer) {
|
||||
return new Authorizer() {
|
||||
@Override
|
||||
public AuthorizationResult authorize(final AuthorizationRequest request) throws AuthorizationAccessException {
|
||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
||||
return baseAuthorizer.authorize(request);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(AuthorizerInitializationContext initializationContext) throws AuthorizerCreationException {
|
||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
||||
baseAuthorizer.initialize(initializationContext);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
|
||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
||||
baseAuthorizer.onConfigured(configurationContext);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preDestruction() throws AuthorizerDestructionException {
|
||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
||||
baseAuthorizer.preDestruction();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class getObjectType() {
|
||||
return Authorizer.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
if (authorizer != null) {
|
||||
authorizer.preDestruction();
|
||||
}
|
||||
}
|
||||
|
||||
public void setProperties(NiFiProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@
|
|||
package org.apache.nifi.authorization;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
|
@ -29,7 +30,7 @@ public class StandardAuthorityProviderConfigurationContext implements AuthorityP
|
|||
|
||||
public StandardAuthorityProviderConfigurationContext(String identifier, Map<String, String> properties) {
|
||||
this.identifier = identifier;
|
||||
this.properties = properties;
|
||||
this.properties = Collections.unmodifiableMap(new HashMap<String, String>(properties));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -39,7 +40,7 @@ public class StandardAuthorityProviderConfigurationContext implements AuthorityP
|
|||
|
||||
@Override
|
||||
public Map<String, String> getProperties() {
|
||||
return Collections.unmodifiableMap(properties);
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.authorization;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class StandardAuthorizerConfigurationContext implements AuthorizerConfigurationContext {
|
||||
|
||||
private final String identifier;
|
||||
private final Map<String, String> properties;
|
||||
|
||||
public StandardAuthorizerConfigurationContext(String identifier, Map<String, String> properties) {
|
||||
this.identifier = identifier;
|
||||
this.properties = Collections.unmodifiableMap(new HashMap<String, String>(properties));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProperty(String property) {
|
||||
return properties.get(property);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.authorization;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class StandardAuthorizerInitializationContext implements AuthorizerInitializationContext {
|
||||
|
||||
private final String identifier;
|
||||
private final AuthorizerLookup authorizerLookup;
|
||||
|
||||
public StandardAuthorizerInitializationContext(String identifier, AuthorizerLookup authorizerLookup) {
|
||||
this.identifier = identifier;
|
||||
this.authorizerLookup = authorizerLookup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
public AuthorizerLookup getAuthorizerLookup() {
|
||||
return authorizerLookup;
|
||||
}
|
||||
|
||||
}
|
|
@ -16,17 +16,18 @@
|
|||
<beans default-lazy-init="true"
|
||||
xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
|
||||
|
||||
<!-- user authority provider -->
|
||||
<bean id="authorityProvider" class="org.apache.nifi.authorization.AuthorityProviderFactoryBean" depends-on="clusterManager">
|
||||
<property name="properties" ref="nifiProperties"/>
|
||||
</bean>
|
||||
|
||||
<!-- user/entity authorizer -->
|
||||
<bean id="authorizer" class="org.apache.nifi.authorization.AuthorizerFactoryBean" depends-on="clusterManager">
|
||||
<property name="properties" ref="nifiProperties"/>
|
||||
</bean>
|
||||
|
||||
<!-- initialize the user data source -->
|
||||
<bean id="userDataSource" class="org.apache.nifi.admin.UserDataSourceFactoryBean" destroy-method="shutdown">
|
||||
<property name="properties" ref="nifiProperties"/>
|
||||
|
|
|
@ -17,22 +17,22 @@
|
|||
<!-- role -->
|
||||
<xs:complexType name="Provider">
|
||||
<xs:sequence>
|
||||
<xs:element name="identifier" type="NonEmptyStringType"/>
|
||||
<xs:element name="class" type="NonEmptyStringType"/>
|
||||
<xs:element name="property" type="Property" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xs:element name="identifier" type="AuthorityProviderNonEmptyStringType"/>
|
||||
<xs:element name="class" type="AuthorityProviderNonEmptyStringType"/>
|
||||
<xs:element name="property" type="AuthorityProviderProperty" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Name/Value properties-->
|
||||
<xs:complexType name="Property">
|
||||
<xs:complexType name="AuthorityProviderProperty">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute name="name" type="NonEmptyStringType"></xs:attribute>
|
||||
<xs:attribute name="name" type="AuthorityProviderNonEmptyStringType"></xs:attribute>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:simpleType name="NonEmptyStringType">
|
||||
<xs:simpleType name="AuthorityProviderNonEmptyStringType">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:minLength value="1"/>
|
||||
</xs:restriction>
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- role -->
|
||||
<xs:complexType name="Authorizer">
|
||||
<xs:sequence>
|
||||
<xs:element name="identifier" type="NonEmptyStringType"/>
|
||||
<xs:element name="class" type="NonEmptyStringType"/>
|
||||
<xs:element name="property" type="Property" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Name/Value properties-->
|
||||
<xs:complexType name="Property">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute name="name" type="NonEmptyStringType"></xs:attribute>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:simpleType name="NonEmptyStringType">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:minLength value="1"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<!-- users -->
|
||||
<xs:element name="authorizers">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="authorizer" type="Authorizer" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-framework</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>nifi-framework-authorization</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-api</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.authorization.resource;
|
||||
|
||||
import org.apache.nifi.authorization.Resource;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public final class ResourceFactory {
|
||||
|
||||
private final static Resource FLOW_RESOURCE = new Resource() {
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "/flow";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "NiFi Flow";
|
||||
}
|
||||
};
|
||||
|
||||
private final static Resource RESOURCE_RESOURCE = new Resource() {
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "/resources";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "NiFi Resources";
|
||||
}
|
||||
};
|
||||
|
||||
private final static Resource SYSTEM_RESOURCE = new Resource() {
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "/system";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "System";
|
||||
}
|
||||
};
|
||||
|
||||
private final static Resource CONTROLLER_RESOURCE = new Resource() {
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "/controller";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Controller";
|
||||
}
|
||||
};
|
||||
|
||||
private final static Resource PROVENANCE_RESOURCE = new Resource() {
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "/provenance";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Provenance";
|
||||
}
|
||||
};
|
||||
|
||||
private final static Resource TOKEN_RESOURCE = new Resource() {
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "/token";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "API access token";
|
||||
}
|
||||
};
|
||||
|
||||
private final static Resource SITE_TO_SITE_RESOURCE = new Resource() {
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "/site-to-site";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Site to Site";
|
||||
}
|
||||
};
|
||||
|
||||
private final static Resource PROXY_RESOURCE = new Resource() {
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "/proxy";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Proxy User Requests";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the Resource for accessing the NiFi flow. This includes the data flow structure, component status, search results, and banner/about text.
|
||||
*
|
||||
* @return The NiFi resource
|
||||
*/
|
||||
public static Resource getFlowResource() {
|
||||
return FLOW_RESOURCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Resource for detailing all available NiFi Resources.
|
||||
*
|
||||
* @return The Resource resource
|
||||
*/
|
||||
public static Resource getResourceResource() {
|
||||
return RESOURCE_RESOURCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Resource for accessing details of the System NiFi is running on.
|
||||
*
|
||||
* @return The System resource
|
||||
*/
|
||||
public static Resource getSystemResource() {
|
||||
return SYSTEM_RESOURCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Resource for accessing the Controller. This includes Controller level configuration, bulletins, reporting tasks, and the cluster.
|
||||
*
|
||||
* @return The resource for accessing the Controller
|
||||
*/
|
||||
public static Resource getControllerResource() {
|
||||
return CONTROLLER_RESOURCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Resource for accessing provenance. Access to this Resource allows the user to access data provenance. However, additional authorization
|
||||
* is required based on the component that generated the event and the attributes of the event.
|
||||
*
|
||||
* @return The provenance resource
|
||||
*/
|
||||
public static Resource getProvenanceResource() {
|
||||
return PROVENANCE_RESOURCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Resource for creating API access tokens.
|
||||
*
|
||||
* @return The token request resource
|
||||
*/
|
||||
public static Resource getTokenResource() {
|
||||
return TOKEN_RESOURCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Resource for obtaining site to site details. This will allow other NiFi instances to obtain necessary configuration to initiate a
|
||||
* site to site data transfer.
|
||||
*
|
||||
* @return The resource for obtaining site to site details
|
||||
*/
|
||||
public static Resource getSiteToSiteResource() {
|
||||
return SITE_TO_SITE_RESOURCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Resource for proxying a user request.
|
||||
*
|
||||
* @return The resource for proxying a user request
|
||||
*/
|
||||
public static Resource getProxyResource() {
|
||||
return PROXY_RESOURCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a Resource for accessing a component configuration.
|
||||
*
|
||||
* @param resourceType The type of resource being accessed
|
||||
* @param identifier The identifier of the component being accessed
|
||||
* @param name The name of the component being accessed
|
||||
* @return The resource
|
||||
*/
|
||||
public static Resource getComponentResource(final ResourceType resourceType, final String identifier, final String name) {
|
||||
Objects.requireNonNull(resourceType, "The resource must be specified.");
|
||||
Objects.requireNonNull(identifier, "The component identifier must be specified.");
|
||||
Objects.requireNonNull(name, "The component name must be specified.");
|
||||
|
||||
return new Resource() {
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return String.format("%s/%s", resourceType.getValue(), identifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a Resource for accessing a component's provenance events.
|
||||
*
|
||||
* @param resourceType The type of resource being accessed
|
||||
* @param identifier The identifier of the component being accessed
|
||||
* @param name The name of the component being accessed
|
||||
* @return The resource
|
||||
*/
|
||||
public static Resource getComponentProvenanceResource(final ResourceType resourceType, final String identifier, final String name) {
|
||||
final Resource componentResource = getComponentResource(resourceType, identifier, name);
|
||||
return new Resource() {
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return String.format("%s/%s", componentResource.getIdentifier(), "provenance");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return componentResource.getName() + " provenance";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a Resource fo accessing a flowfile queue for the specified connection.
|
||||
*
|
||||
* @param connectionIdentifier The identifier of the connection
|
||||
* @param connectionName The name of the connection
|
||||
* @return The resource
|
||||
*/
|
||||
public static Resource getFlowFileQueueResource(final String connectionIdentifier, final String connectionName) {
|
||||
Objects.requireNonNull(connectionIdentifier, "The connection identifier must be specified.");
|
||||
Objects.requireNonNull(connectionName, "The connection name must be specified.");
|
||||
|
||||
return new Resource() {
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return String.format("/flowfile-queue/%s", connectionIdentifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return connectionName + " queue";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent outside instantiation.
|
||||
*/
|
||||
private ResourceFactory() {}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.authorization.resource;
|
||||
|
||||
public enum ResourceType {
|
||||
Processor("/processors"),
|
||||
InputPort("/input-ports"),
|
||||
OutputPort("/output-ports"),
|
||||
Connection("/connections"),
|
||||
ProcessGroup("/process-groups"),
|
||||
RemoteProcessGroup("/remote-process-groups"),
|
||||
Label("/labels"),
|
||||
ControllerService("/controller-services"),
|
||||
Template("/templates");
|
||||
|
||||
final String value;
|
||||
|
||||
private ResourceType(final String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
|
@ -36,6 +36,7 @@
|
|||
<module>nifi-file-authorization-provider</module>
|
||||
<module>nifi-cluster-authorization-provider</module>
|
||||
<module>nifi-user-actions</module>
|
||||
<module>nifi-framework-authorization</module>
|
||||
<module>nifi-administration</module>
|
||||
<module>nifi-web</module>
|
||||
<module>nifi-resources</module>
|
||||
|
|
Loading…
Reference in New Issue