All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.streamnative.pulsar.handlers.kop.security.ProxySslSaslServer Maven / Gradle / Ivy

There is a newer version: 4.0.0.4
Show newest version
/**
 * Copyright (c) 2019 - 2024 StreamNative, Inc.. All Rights Reserved.
 */
/**
 * Licensed 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 io.streamnative.pulsar.handlers.kop.security;

import static io.streamnative.pulsar.handlers.kop.security.SaslAuthenticator.AUTH_DATA_SOURCE_PROP;
import static io.streamnative.pulsar.handlers.kop.security.SaslAuthenticator.GROUP_ID_PROP;
import static io.streamnative.pulsar.handlers.kop.security.SaslAuthenticator.USER_NAME_PROP;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
import lombok.extern.slf4j.Slf4j;
import org.apache.pulsar.broker.authentication.AuthenticationDataCommand;
import org.apache.pulsar.broker.authentication.AuthenticationDataSource;

/**
 * The SaslServer implementation for SASL/PROXY_SSL.
 */
@Slf4j
public class ProxySslSaslServer implements SaslServer {

    public static final String PROXY_SSL_MECHANISM = "PROXY_SSL";

    private boolean complete;
    private String authorizationId;
    private String username;
    private AuthenticationDataSource authDataSource;


    @Override
    public String getMechanismName() {
        return PROXY_SSL_MECHANISM;
    }

    @Override
    public byte[] evaluateResponse(byte[] response) {
        String role = new String(response, StandardCharsets.UTF_8);
        this.authDataSource = new AuthenticationDataCommand(role);
        this.authorizationId = role;
        this.username = "public/default";
        this.complete = true;
        return response;
    }

    @Override
    public boolean isComplete() {
        return complete;
    }

    @Override
    public String getAuthorizationID() {
        if (!complete) {
            throw new IllegalStateException("Authentication exchange has not completed");
        }
        return authorizationId;
    }

    @Override
    public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException {
        if (!complete) {
            throw new IllegalStateException("Authentication exchange has not completed");
        }
        return Arrays.copyOfRange(incoming, offset, offset + len);
    }

    @Override
    public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException {
        if (!complete) {
            throw new IllegalStateException("Authentication exchange has not completed");
        }
        return Arrays.copyOfRange(outgoing, offset, offset + len);
    }
    @Override
    public Object getNegotiatedProperty(String propName) {
        if (!complete) {
            throw new IllegalStateException("Authentication exchange has not completed");
        }
        if (USER_NAME_PROP.equals(propName)) {
            return username;
        }
        if (GROUP_ID_PROP.equals(propName)) {
            return "";
        }
        if (AUTH_DATA_SOURCE_PROP.equals(propName)) {
            return authDataSource;
        }
        return null;
    }

    @Override
    public void dispose() {}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy