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

io.aeron.samples.security.SimpleAuthenticator Maven / Gradle / Ivy

There is a newer version: 1.46.7
Show newest version
/*
 * Copyright 2014-2024 Real Logic Limited.
 *
 * 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
 *
 * https://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.aeron.samples.security;

import io.aeron.security.Authenticator;
import io.aeron.security.CredentialsSupplier;
import io.aeron.security.SessionProxy;
import org.agrona.collections.Long2ObjectHashMap;
import org.agrona.collections.Object2ObjectHashMap;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * An authenticator that works off a simple principal/credential pair constructed by a builder. It only supports simple
 * authentication, but not challenge/response.
 */
public final class SimpleAuthenticator implements Authenticator
{
    private final Object2ObjectHashMap principalsByCredentialsMap =
        new Object2ObjectHashMap<>();

    private final Long2ObjectHashMap authenticatedSessionIdToPrincipalMap = new Long2ObjectHashMap<>();

    private SimpleAuthenticator(final Builder builder)
    {
        for (final Principal principal : builder.principals)
        {
            principalsByCredentialsMap.put(principal.credentials, principal);
        }
    }

    /**
     * {@inheritDoc}
     */
    public void onConnectRequest(final long sessionId, final byte[] encodedCredentials, final long nowMs)
    {
        final Principal principal = principalsByCredentialsMap.get(new Credentials(encodedCredentials));
        if (null != principal && principal.credentialsMatch(encodedCredentials))
        {
            authenticatedSessionIdToPrincipalMap.put(sessionId, principal);
        }
    }

    /**
     * {@inheritDoc}
     */
    public void onChallengeResponse(final long sessionId, final byte[] encodedCredentials, final long nowMs)
    {
        throw new UnsupportedOperationException();
    }

    /**
     * {@inheritDoc}
     */
    public void onConnectedSession(final SessionProxy sessionProxy, final long nowMs)
    {
        final long sessionId = sessionProxy.sessionId();
        final Principal principal = authenticatedSessionIdToPrincipalMap.get(sessionId);
        if (null != principal)
        {
            if (sessionProxy.authenticate(principal.encodedPrincipal))
            {
                authenticatedSessionIdToPrincipalMap.remove(sessionId);
            }
        }
        else
        {
            sessionProxy.reject();
        }
    }

    /**
     * {@inheritDoc}
     */
    public void onChallengedSession(final SessionProxy sessionProxy, final long nowMs)
    {
        throw new UnsupportedOperationException();
    }

    /**
     * Builder to create instances of SimpleAuthenticator
     */
    public static class Builder
    {
        private final ArrayList principals = new ArrayList<>();

        /**
         * Add a principal/credentials pair to the list supported by this authenticator. Note that the
         * {@link SimpleAuthenticator} keys the principals by the credentials, so the encoded credentials should
         * include the encoded principal. The associated {@link CredentialsSupplier} used on the client should handle
         * encoding these credentials correctly as well. E.g.
         * 
         * final SimpleAuthenticator simpleAuthenticator = new SimpleAuthenticator.Builder()
         *     .principal("user".getBytes(US_ASCII), "user:pass".getBytes(US_ASCII))
         *     .newInstance();
         * 
* * @param encodedPrincipal principal encoded as a byte array. * @param encodedCredentials credentials encoded as a byte array. * @return this for a fluent API. */ public Builder principal(final byte[] encodedPrincipal, final byte[] encodedCredentials) { principals.add(new Principal(encodedPrincipal, encodedCredentials)); return this; } /** * Construct a new instance of the SimpleAuthenticator. * * @return a new SimpleAuthenticator instance. */ public SimpleAuthenticator newInstance() { return new SimpleAuthenticator(this); } } private static final class Principal { private final byte[] encodedPrincipal; private final Credentials credentials; private Principal(final byte[] encodedPrincipal, final byte[] encodedCredentials) { this.encodedPrincipal = encodedPrincipal; this.credentials = new Credentials(encodedCredentials); } public boolean credentialsMatch(final byte[] encodedCredentials) { return Arrays.equals(credentials.encodedCredentials, encodedCredentials); } } private static final class Credentials { private final byte[] encodedCredentials; private Credentials(final byte[] encodedCredentials) { this.encodedCredentials = encodedCredentials; } public boolean equals(final Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } final Credentials that = (Credentials)o; return Arrays.equals(encodedCredentials, that.encodedCredentials); } public int hashCode() { return Arrays.hashCode(encodedCredentials); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy