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

org.wildfly.security.auth.server.SecurityIdentity Maven / Gradle / Ivy

There is a newer version: 2.4.1.Final
Show newest version
/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2015 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * 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 org.wildfly.security.auth.server;

import static org.wildfly.security.auth.server._private.ElytronMessages.log;

import java.security.Permission;
import java.security.Principal;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.ObjIntConsumer;
import java.util.function.Supplier;

import org.wildfly.common.Assert;
import org.wildfly.common.function.ExceptionBiConsumer;
import org.wildfly.common.function.ExceptionBiFunction;
import org.wildfly.common.function.ExceptionBiPredicate;
import org.wildfly.common.function.ExceptionFunction;
import org.wildfly.common.function.ExceptionObjIntConsumer;
import org.wildfly.common.function.ExceptionSupplier;
import org.wildfly.security.ParametricPrivilegedAction;
import org.wildfly.security.ParametricPrivilegedExceptionAction;
import org.wildfly.security.auth.permission.ChangeRoleMapperPermission;
import org.wildfly.security.auth.permission.RunAsPrincipalPermission;
import org.wildfly.security.auth.principal.AnonymousPrincipal;
import org.wildfly.security.auth.principal.NamePrincipal;
import org.wildfly.security.auth.server.event.SecurityPermissionCheckFailedEvent;
import org.wildfly.security.auth.server.event.SecurityPermissionCheckSuccessfulEvent;
import org.wildfly.security.authz.Attributes;
import org.wildfly.security.authz.AuthorizationIdentity;
import org.wildfly.security.authz.PermissionMappable;
import org.wildfly.security.authz.RoleMapper;
import org.wildfly.security.authz.Roles;
import org.wildfly.security.credential.Credential;
import org.wildfly.security.permission.ElytronPermission;
import org.wildfly.security.permission.PermissionVerifier;

/**
 * A loaded and authenticated security identity.
 *
 * @author David M. Lloyd
 */
public final class SecurityIdentity implements PermissionVerifier, PermissionMappable, Supplier, Scoped {
    private static final Permission SET_RUN_AS_PERMISSION = ElytronPermission.forName("setRunAsPrincipal");
    private static final Permission PRIVATE_CREDENTIALS_PERMISSION = ElytronPermission.forName("getPrivateCredentials");
    private static final Permission WITH_DEFAULT_ROLE_MAPPER_PERMISSION = ElytronPermission.forName("withDefaultRoleMapper");

    private static final SecurityIdentity[] NO_IDENTITIES = new SecurityIdentity[0];

    private final SecurityDomain securityDomain;
    private final Principal principal;
    private final AuthorizationIdentity authorizationIdentity;
    private final RealmInfo realmInfo;
    private final Function defaultRoles;
    private final Map roleMappers;
    private final Instant creationTime;
    private final PermissionVerifier verifier;
    private final IdentityCredentials publicCredentials;
    private final IdentityCredentials privateCredentials;
    private final Supplier withSuppliedIdentities;
    private final SecurityIdentity[] withIdentities;

    SecurityIdentity(final SecurityDomain securityDomain, final Principal principal, final RealmInfo realmInfo, final AuthorizationIdentity authorizationIdentity, final Map roleMappers, final IdentityCredentials publicCredentials, final IdentityCredentials privateCredentials) {
        this.securityDomain = securityDomain;
        this.principal = principal;
        this.realmInfo = realmInfo;
        this.authorizationIdentity = authorizationIdentity;
        this.defaultRoles = securityDomain::mapRoles;
        this.roleMappers = roleMappers;
        this.creationTime = Instant.now();
        this.verifier = securityDomain.mapPermissions(this);
        this.publicCredentials = publicCredentials;
        this.privateCredentials = privateCredentials;
        this.withSuppliedIdentities = null;
        this.withIdentities = null;
    }

    SecurityIdentity(final SecurityIdentity old, final Map roleMappers) {
        this.securityDomain = old.securityDomain;
        this.principal = old.principal;
        this.realmInfo = old.realmInfo;
        this.authorizationIdentity = old.authorizationIdentity;
        this.defaultRoles = old.defaultRoles;
        this.roleMappers = roleMappers;
        this.creationTime = old.creationTime;
        this.verifier = old.verifier;
        this.publicCredentials = old.publicCredentials;
        this.privateCredentials = old.privateCredentials;
        this.withSuppliedIdentities = old.withSuppliedIdentities;
        this.withIdentities = old.withIdentities;
    }

    SecurityIdentity(final SecurityIdentity old, final PermissionVerifier verifier) {
        this.securityDomain = old.securityDomain;
        this.principal = old.principal;
        this.realmInfo = old.realmInfo;
        this.authorizationIdentity = old.authorizationIdentity;
        this.defaultRoles = old.defaultRoles;
        this.roleMappers = old.roleMappers;
        this.creationTime = old.creationTime;
        this.verifier = verifier;
        this.publicCredentials = old.publicCredentials;
        this.privateCredentials = old.privateCredentials;
        this.withSuppliedIdentities = old.withSuppliedIdentities;
        this.withIdentities = old.withIdentities;
    }

    SecurityIdentity(final SecurityIdentity old, final Credential credential, final boolean isPrivate) {
        this.securityDomain = old.securityDomain;
        this.principal = old.principal;
        this.realmInfo = old.realmInfo;
        this.authorizationIdentity = old.authorizationIdentity;
        this.defaultRoles = old.defaultRoles;
        this.roleMappers = old.roleMappers;
        this.creationTime = old.creationTime;
        this.verifier = old.verifier;
        this.publicCredentials = isPrivate ? old.publicCredentials : old.publicCredentials.withCredential(credential);
        this.privateCredentials = isPrivate ? old.privateCredentials.withCredential(credential) : old.privateCredentials;
        this.withSuppliedIdentities = old.withSuppliedIdentities;
        this.withIdentities = old.withIdentities;
    }

    SecurityIdentity(final SecurityIdentity old, final IdentityCredentials credentials, final boolean isPrivate) {
        this.securityDomain = old.securityDomain;
        this.principal = old.principal;
        this.realmInfo = old.realmInfo;
        this.authorizationIdentity = old.authorizationIdentity;
        this.defaultRoles = old.defaultRoles;
        this.roleMappers = old.roleMappers;
        this.creationTime = old.creationTime;
        this.verifier = old.verifier;
        this.publicCredentials = isPrivate ? old.publicCredentials : old.publicCredentials.with(credentials);
        this.privateCredentials = isPrivate ? old.privateCredentials.with(credentials) : old.privateCredentials;
        this.withSuppliedIdentities = old.withSuppliedIdentities;
        this.withIdentities = old.withIdentities;
    }

    SecurityIdentity(final SecurityIdentity old, final Supplier withSuppliedIdentites) {
        this.securityDomain = old.securityDomain;
        this.principal = old.principal;
        this.realmInfo = old.realmInfo;
        this.authorizationIdentity = old.authorizationIdentity;
        this.defaultRoles = old.defaultRoles;
        this.roleMappers = old.roleMappers;
        this.creationTime = old.creationTime;
        this.verifier = old.verifier;
        this.publicCredentials = old.publicCredentials;
        this.privateCredentials = old.privateCredentials;
        this.withSuppliedIdentities = withSuppliedIdentites;
        this.withIdentities = null;
    }

    SecurityIdentity(final SecurityIdentity old, final SecurityIdentity[] withIdentities) {
        this.securityDomain = old.securityDomain;
        this.principal = old.principal;
        this.realmInfo = old.realmInfo;
        this.authorizationIdentity = old.authorizationIdentity;
        this.defaultRoles = old.defaultRoles;
        this.roleMappers = old.roleMappers;
        this.creationTime = old.creationTime;
        this.verifier = old.verifier;
        this.publicCredentials = old.publicCredentials;
        this.privateCredentials = old.privateCredentials;
        this.withSuppliedIdentities = null;
        this.withIdentities = withIdentities;
    }

    SecurityIdentity(final SecurityIdentity old, final FunctiondefaultRoles) {
        this.securityDomain = old.securityDomain;
        this.principal = old.principal;
        this.realmInfo = old.realmInfo;
        this.authorizationIdentity = old.authorizationIdentity;
        this.defaultRoles = defaultRoles;
        this.roleMappers = old.roleMappers;
        this.creationTime = old.creationTime;
        this.verifier = old.verifier;
        this.publicCredentials = old.publicCredentials;
        this.privateCredentials = old.privateCredentials;
        this.withSuppliedIdentities = null;
        this.withIdentities = old.withIdentities;
    }

    SecurityIdentity(final SecurityIdentity old, final Attributes runtimeAttributes) {
        this.securityDomain = old.securityDomain;
        this.principal = old.principal;
        this.realmInfo = old.realmInfo;
        this.authorizationIdentity = AuthorizationIdentity.basicIdentity(old.authorizationIdentity, runtimeAttributes);
        this.defaultRoles = old.defaultRoles;
        this.roleMappers = old.roleMappers;
        this.creationTime = old.creationTime;
        this.verifier = old.verifier;
        this.publicCredentials = old.publicCredentials;
        this.privateCredentials = old.privateCredentials;
        this.withSuppliedIdentities = null;
        this.withIdentities = old.withIdentities;
    }

    SecurityDomain getSecurityDomain() {
        return securityDomain;
    }

    RealmInfo getRealmInfo() {
        return this.realmInfo;
    }

    AuthorizationIdentity getAuthorizationIdentity() {
        return authorizationIdentity;
    }

    @SuppressWarnings("unchecked")
    private Supplier[] establishIdentities() {
        SecurityIdentity[] withIdentities = this.withIdentities != null ? this.withIdentities : withSuppliedIdentities != null ? withSuppliedIdentities.get() : NO_IDENTITIES;
        if (withIdentities.length == 0) {
            return NO_IDENTITIES;
        }

        Supplier[] oldIdentities = new Supplier[withIdentities.length];
        for (int i = 0; i < withIdentities.length; i++) {
            Supplier securityIdentity = withIdentities[i];
            oldIdentities[i] = securityIdentity.get().getSecurityDomain().getAndSetCurrentSecurityIdentity(securityIdentity);
        }

        return oldIdentities;
    }

    private void restoreIdentities(Supplier[] securityIdentities) {
        for (Supplier currentIdentity : securityIdentities) {
            currentIdentity.get().securityDomain.setCurrentSecurityIdentity(currentIdentity);
        }
    }

    /**
     * Run an action under this identity.
     *
     * @param action the action to run
     * @param  the action return type
     * @return the action result (may be {@code null})
     * @deprecated Use {@link #runAsSupplier(Supplier)} instead.
     */
    @Deprecated
    public  T runAs(PrivilegedAction action) {
        if (action == null) return null;
        return runAs(action, (ParametricPrivilegedAction>) PrivilegedAction::run);
    }

    /**
     * Run an action under this identity.
     *
     * @param action the action to run
     * @param  the action return type
     * @return the action result (may be {@code null})
     * @throws PrivilegedActionException if the action fails
     * @deprecated Use {@link #runAsSupplierEx(ExceptionSupplier)} instead.
     */
    @Deprecated
    public  T runAs(PrivilegedExceptionAction action) throws PrivilegedActionException {
        if (action == null) return null;
        return runAs(action, (ParametricPrivilegedExceptionAction>) PrivilegedExceptionAction::run);
    }

    /**
     * Run an action under this identity.
     *
     * @param parameter the parameter to pass to the action
     * @param action the action to run
     * @param  the action return type
     * @param 

the action parameter type * @return the action result (may be {@code null}) * @deprecated Use {@link #runAsFunction(Function, Object)} instead. */ @Deprecated public T runAs(P parameter, ParametricPrivilegedAction action) { if (action == null) return null; final Supplier[] oldWithIdentities = establishIdentities(); final Supplier oldIdentity = securityDomain.getAndSetCurrentSecurityIdentity(this); try { return action.run(parameter); } finally { securityDomain.setCurrentSecurityIdentity(oldIdentity); restoreIdentities(oldWithIdentities); } } /** * Run an action under this identity. * * @param parameter the parameter to pass to the action * @param action the action to run * @param the action return type * @param

the action parameter type * @return the action result (may be {@code null}) * @throws PrivilegedActionException if the action fails * @deprecated Use {@link #runAsFunctionEx(ExceptionFunction, Object)} instead. */ @Deprecated public T runAs(P parameter, ParametricPrivilegedExceptionAction action) throws PrivilegedActionException { if (action == null) return null; final Supplier[] oldWithIdentities = establishIdentities(); final Supplier oldIdentity = securityDomain.getAndSetCurrentSecurityIdentity(this); try { return action.run(parameter); } catch (RuntimeException | PrivilegedActionException e) { throw e; } catch (Exception e) { throw new PrivilegedActionException(e); } finally { securityDomain.setCurrentSecurityIdentity(oldIdentity); restoreIdentities(oldWithIdentities); } } /** * Run an action under this identity. * * @param parameter1 the first parameter to pass to the action * @param parameter2 the second parameter to pass to the action * @param action the action to run * @param the action return type * @param the action first parameter type * @param the action second parameter type * @return the action result (may be {@code null}) */ public R runAsFunction(BiFunction action, T parameter1, U parameter2) { if (action == null) return null; final Supplier[] oldWithIdentities = establishIdentities(); final Supplier oldIdentity = securityDomain.getAndSetCurrentSecurityIdentity(this); try { return action.apply(parameter1, parameter2); } finally { securityDomain.setCurrentSecurityIdentity(oldIdentity); restoreIdentities(oldWithIdentities); } } /** * Run an action under this identity. * * @param parameter1 the first parameter to pass to the action * @param parameter2 the second parameter to pass to the action * @param action the action to run * @param the action first parameter type * @param the action second parameter type */ public void runAsConsumer(BiConsumer action, T parameter1, U parameter2) { if (action == null) return; final Supplier[] oldWithIdentities = establishIdentities(); final Supplier oldIdentity = securityDomain.getAndSetCurrentSecurityIdentity(this); try { action.accept(parameter1, parameter2); } finally { securityDomain.setCurrentSecurityIdentity(oldIdentity); restoreIdentities(oldWithIdentities); } } /** * Run an action under this identity. * * @param parameter1 the first parameter to pass to the action * @param parameter2 the second parameter to pass to the action * @param action the action to run * @param the action first parameter type */ public void runAsObjIntConsumer(ObjIntConsumer action, T parameter1, int parameter2) { if (action == null) return; final Supplier[] oldWithIdentities = establishIdentities(); final Supplier oldIdentity = securityDomain.getAndSetCurrentSecurityIdentity(this); try { action.accept(parameter1, parameter2); } finally { securityDomain.setCurrentSecurityIdentity(oldIdentity); restoreIdentities(oldWithIdentities); } } /** * Run an action under this identity. * * @param parameter1 the first parameter to pass to the action * @param parameter2 the second parameter to pass to the action * @param action the action to run * @param the action return type * @param the action first parameter type * @param the action second parameter type * @param the action exception type * @return the action result (may be {@code null}) * @throws E if the action throws this exception */ public R runAsFunctionEx(ExceptionBiFunction action, T parameter1, U parameter2) throws E { if (action == null) return null; final Supplier[] oldWithIdentities = establishIdentities(); final Supplier oldIdentity = securityDomain.getAndSetCurrentSecurityIdentity(this); try { return action.apply(parameter1, parameter2); } finally { securityDomain.setCurrentSecurityIdentity(oldIdentity); restoreIdentities(oldWithIdentities); } } /** * Run an action under this identity. * * @param parameter1 the first parameter to pass to the action * @param parameter2 the second parameter to pass to the action * @param action the action to run * @param the action first parameter type * @param the action second parameter type * @param the action exception type * @throws E if the action throws this exception */ public void runAsConsumerEx(ExceptionBiConsumer action, T parameter1, U parameter2) throws E { if (action == null) return; final Supplier[] oldWithIdentities = establishIdentities(); final Supplier oldIdentity = securityDomain.getAndSetCurrentSecurityIdentity(this); try { action.accept(parameter1, parameter2); } finally { securityDomain.setCurrentSecurityIdentity(oldIdentity); restoreIdentities(oldWithIdentities); } } /** * Run an action under this identity. * * @param parameter1 the first parameter to pass to the action * @param parameter2 the second parameter to pass to the action * @param action the action to run * @param the action first parameter type * @param the action exception type * @throws E if the action throws this exception */ public void runAsObjIntConsumerEx(ExceptionObjIntConsumer action, T parameter1, int parameter2) throws E { if (action == null) return; final Supplier[] oldWithIdentities = establishIdentities(); final Supplier oldIdentity = securityDomain.getAndSetCurrentSecurityIdentity(this); try { action.accept(parameter1, parameter2); } finally { securityDomain.setCurrentSecurityIdentity(oldIdentity); restoreIdentities(oldWithIdentities); } } /** * Run an action under this identity. * * @param parameter1 the first parameter to pass to the action * @param parameter2 the second parameter to pass to the action * @param action the action to run * @param the action first parameter type * @param the action second parameter type * @return the action result (may be {@code null}) */ public boolean runAsBiPredicate(BiPredicate action, T parameter1, U parameter2) { if (action == null) return false; final Supplier[] oldWithIdentities = establishIdentities(); final Supplier oldIdentity = securityDomain.getAndSetCurrentSecurityIdentity(this); try { return action.test(parameter1, parameter2); } finally { securityDomain.setCurrentSecurityIdentity(oldIdentity); restoreIdentities(oldWithIdentities); } } /** * Run an action under this identity. * * @param parameter1 the first parameter to pass to the action * @param parameter2 the second parameter to pass to the action * @param action the action to run * @param the action first parameter type * @param the action second parameter type * @param the action exception type * @return the action result (may be {@code null}) * @throws E if the action throws this exception */ public boolean runAsExBiPredicate(ExceptionBiPredicate action, T parameter1, U parameter2) throws E { if (action == null) return false; final Supplier[] oldWithIdentities = establishIdentities(); final Supplier oldIdentity = securityDomain.getAndSetCurrentSecurityIdentity(this); try { return action.test(parameter1, parameter2); } finally { securityDomain.setCurrentSecurityIdentity(oldIdentity); restoreIdentities(oldWithIdentities); } } /** * Run an action under a series of identities. * * @param action the action to run * @param identities the identities to set up * @param the action return type * @return the action result (may be {@code null}) * @throws PrivilegedActionException if the action fails */ @SuppressWarnings({ "unchecked", "rawtypes" }) public static T runAsAll(PrivilegedExceptionAction action, SecurityIdentity... identities) throws PrivilegedActionException { if (action == null) return null; int length = identities.length; Supplier[] oldIdentities = new Supplier[length]; for (int i = 0; i < length; i++) { Supplier securityIdentity = identities[i]; SecurityDomain securityDomain = securityIdentity.get().getSecurityDomain(); oldIdentities[i] = securityDomain.getAndSetCurrentSecurityIdentity(securityIdentity); } try { return action.run(); } catch (RuntimeException | PrivilegedActionException e) { throw e; } catch (Exception e) { throw new PrivilegedActionException(e); } finally { for (int i = 0; i < length; i++) { Supplier oldIdentity = oldIdentities[i]; SecurityDomain securityDomain = oldIdentity.get().getSecurityDomain(); securityDomain.setCurrentSecurityIdentity(oldIdentity); } } } /** * Get the roles associated with this identity. * * @return the roles associated with this identity */ public Roles getRoles() { return defaultRoles.apply(this); } /** * Get the mapped roles associated with this identity. If no role mapping exists for the given category, an * empty role set is returned. * * @param category the role mapping category * @return the category roles */ public Roles getRoles(String category) { return getRoles(category, false); } /** * Attempt to create a new identity that is the same as this identity but with a {@link Supplier Supplier} to supply identities that will be associated with all 'run' calls. * * Any existing individual identities associated with this identity will be dropped. * * The supplier will be called for each run call so were possible should handle it's own optimisation. * * @param securityIdentities a {@link Supplier Supplier} for identities to be associated with every run call. * @return the new identity * @throws IllegalArgumentException if the supplied identity */ public SecurityIdentity withSecurityIdentitySupplier(Supplier securityIdentities) { Assert.checkNotNullParam("securityIdentities", securityIdentities); if (this.withSuppliedIdentities == securityIdentities) { return this; } return new SecurityIdentity(this, securityIdentities); } /** * Attempt to create a new identity that is the same as this identity but with an additional identity from a different * security domain that will be associated with all 'run' calls. * * If a {@link Supplier Supplier} has previously been associated with this identity it will be dropped. * * @param securityIdentity the {@link SecurityIdentity} to also be associated with all run calls made to this identity. * @return the new identity * @throws IllegalArgumentException if the supplied identity */ public SecurityIdentity withSecurityIdentity(SecurityIdentity securityIdentity) { Assert.checkNotNullParam("securityIdentity", securityIdentity); if (securityIdentity == this) { return this; } if (securityDomain == securityIdentity.securityDomain) { throw log.cantWithSameSecurityDomainDomain(); } int oldCapacity = this.withIdentities == null ? 0 : this.withIdentities.length; List withIdentities = new ArrayList<>(oldCapacity + 1); if (oldCapacity != 0) { for (SecurityIdentity currentIdentity : this.withIdentities) { if (currentIdentity == securityIdentity) { return this; // already added } if (currentIdentity.securityDomain != securityIdentity.securityDomain) { withIdentities.add(currentIdentity); // re-add identities from other domains } } } withIdentities.add(securityIdentity); return new SecurityIdentity(this, withIdentities.toArray(new SecurityIdentity[0])); } /** * Get the mapped roles associated with this identity. * * @param category the role mapping category * @param fallbackToDefault {@code true} if the default roles associated with this identity should be returned if no * role mapping exists for the given category, {@code false} otherwise * @return the category roles */ public Roles getRoles(String category, boolean fallbackToDefault) { final RoleMapper roleMapper = roleMappers.get(category); return roleMapper == null ? (fallbackToDefault ? getRoles() : Roles.NONE) : roleMapper.mapRoles(getRoles()); } /** * Attempt to create a new identity which replaces a role mapper category on the current identity. If the given role * mapper is already set on the current identity, the current identity is returned. * * @param category the category name * @param roleMapper the role mapper to use * @return the new identity * @throws SecurityException if the calling class is not granted the {@link ChangeRoleMapperPermission} for the given * category name */ public SecurityIdentity withRoleMapper(String category, RoleMapper roleMapper) { Assert.checkNotNullParam("category", category); Assert.checkNotNullParam("roleMapper", roleMapper); final Map roleMappers = this.roleMappers; final RoleMapper existingRoleMapper = roleMappers.get(category); if (existingRoleMapper == roleMapper) { // identical return this; } // it's a change of some sort final SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(new ChangeRoleMapperPermission(category)); } // authorized; next see if we can use a memory-efficient collection final Map newMap; if (roleMappers.isEmpty() || roleMappers.size() == 1 && roleMappers.keySet().iterator().next().equals(category)) { newMap = Collections.singletonMap(category, roleMapper); } else { newMap = new HashMap<>(roleMappers); newMap.put(category, roleMapper); } return new SecurityIdentity(this, newMap); } /** * Attempt to create a new identity which wraps the default roles with a default role mapper. * * @param roleMapper the roleMapper to map the roles. * @return the new identity * @throws SecurityException if the calling class is not granted the withDefaultRoleMapper permission. */ public SecurityIdentity withDefaultRoleMapper(final RoleMapper roleMapper) { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(WITH_DEFAULT_ROLE_MAPPER_PERMISSION); } return new SecurityIdentity(this, (SecurityIdentity si) -> roleMapper.mapRoles(this.getRoles())); } /** * Attempt to create a new identity that can be used to run as a user with the given name. If the * current identity is not authorized to run as a user with the given name, an exception is thrown. * * Calling with enabled security manager requires {@code setRunAsPrincipal} {@link ElytronPermission}. * Regardless security manager is enabled, {@link RunAsPrincipalPermission} for given name is required. * * @param name the name to attempt to run as * @return the new security identity * @throws SecurityException if the operation authorization failed for any reason */ public SecurityIdentity createRunAsIdentity(String name) throws SecurityException { return createRunAsIdentity(name, true); } /** * Attempt to create a new identity that can be used to run as a user with the given name. * * Calling with enabled security manager requires {@code setRunAsPrincipal} {@link ElytronPermission}. * * @param name the name to attempt to run as * @param authorize whether to check the current identity is authorized to run as a user * with the given principal (has {@link RunAsPrincipalPermission}) * @return the new security identity * @throws SecurityException if the caller does not have the {@code setRunAsPrincipal} * {@link ElytronPermission} or if the operation authorization failed for any other reason */ public SecurityIdentity createRunAsIdentity(String name, boolean authorize) throws SecurityException { Assert.checkNotNullParam("name", name); return createRunAsIdentity(new NamePrincipal(name), authorize); } /** * Attempt to create a new identity that can be used to run as a user with the given principal. * * Calling with enabled security manager requires {@code setRunAsPrincipal} {@link ElytronPermission}. * * @param principal the principal to attempt to run as * @param authorize whether to check the current identity is authorized to run as a user * with the given principal (has {@link RunAsPrincipalPermission}) * @return the new security identity * @throws SecurityException if the caller does not have the {@code setRunAsPrincipal} * {@link ElytronPermission} or if the operation authorization failed for any other reason */ public SecurityIdentity createRunAsIdentity(Principal principal, boolean authorize) throws SecurityException { Assert.checkNotNullParam("principal", principal); final SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(SET_RUN_AS_PERMISSION); } try (final ServerAuthenticationContext context = securityDomain.createNewAuthenticationContext(this, MechanismConfigurationSelector.constantSelector(MechanismConfiguration.EMPTY))) { if (! (context.importIdentity(this) && context.authorize(principal, authorize))) { throw log.runAsAuthorizationFailed(this.principal, principal, null); } return context.getAuthorizedIdentity(); } catch (RealmUnavailableException e) { throw log.runAsAuthorizationFailed(this.principal, principal, e); } } /** * Attempt to create a new identity that can be used to run as an anonymous user. If the * current identity is not authorized to run as an anonymous user, an exception is thrown. * * Calling with enabled security manager requires {@code setRunAsPrincipal} {@link ElytronPermission}. * {@link org.wildfly.security.auth.permission.LoginPermission} granted to the anonymous identity will be required. * * @return the new security identity * @throws SecurityException if the operation authorization failed for any reason */ public SecurityIdentity createRunAsAnonymous() throws SecurityException { return createRunAsAnonymous(true); } /** * Attempt to create a new identity that can be used to run as an anonymous user * * Calling with enabled security manager requires {@code setRunAsPrincipal} {@link ElytronPermission}. * * @param authorize whether to check the anonymous identity is authorized to log in * (has {@link org.wildfly.security.auth.permission.LoginPermission}) * @return the new security identity * @throws SecurityException if the caller does not have the {@code setRunAsPrincipal} * {@link ElytronPermission} or if the operation authorization failed for any other reason */ public SecurityIdentity createRunAsAnonymous(boolean authorize) throws SecurityException { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(SET_RUN_AS_PERMISSION); } try (final ServerAuthenticationContext context = securityDomain.createNewAuthenticationContext(this, MechanismConfigurationSelector.constantSelector(MechanismConfiguration.EMPTY))) { if (! context.authorizeAnonymous(authorize)) { throw log.runAsAuthorizationFailed(principal, AnonymousPrincipal.getInstance(), null); } return context.getAuthorizedIdentity(); } } /** * Create a new security identity which is the same as this one, but which limits authorization privileges to the * intersection of the current privileges and the given verifier. * * @param verifier the restricted verifier (must not be {@code null}) * @return the restricted identity */ public SecurityIdentity intersectWith(PermissionVerifier verifier) { Assert.checkNotNullParam("verifier", verifier); return new SecurityIdentity(this, this.verifier.and(verifier)); } public boolean implies(final Permission permission) { final boolean result = verifier.implies(permission); SecurityDomain.safeHandleSecurityEvent(securityDomain, result ? new SecurityPermissionCheckSuccessfulEvent(this, permission) : new SecurityPermissionCheckFailedEvent(this, permission)); return result; } /** * Get the attributes associated with this identity. * * @return a read-only instance of {@link Attributes} with all attributes associated with this identity */ public Attributes getAttributes() { return this.authorizationIdentity.getAttributes().asReadOnly(); } /** * Get the principal of this identity. * * @return the principal of this identity */ public Principal getPrincipal() { return principal; } /** * Get the creation time of this identity, which is the time that the initial authentication occurred. * * @return the creation time of this identity (not {@code null}) */ public Instant getCreationTime() { return creationTime; } /** * Get the public credentials of this identity. * * @return the public credentials of this identity (not {@code null}) */ public IdentityCredentials getPublicCredentials() { return publicCredentials; } /** * Convenience method to determine if this identity is anonymous. * * @return {@code true} if the identity is anonymous, {@code false} otherwise */ public boolean isAnonymous() { return principal instanceof AnonymousPrincipal; } /** * Create a new security identity which is the same as this one, but which includes the given credential as a * public credential. * * @param credential the credential (must not be {@code null}) * @return the new identity */ public SecurityIdentity withPublicCredential(Credential credential) { Assert.checkNotNullParam("credential", credential); return new SecurityIdentity(this, credential, false); } /** * Create a new security identity which is the same as this one, but which includes the given credentials as * public credentials. * * @param credentials the credential set (must not be {@code null}) * @return the new identity */ public SecurityIdentity withPublicCredentials(final IdentityCredentials credentials) { Assert.checkNotNullParam("credentials", credentials); return credentials == IdentityCredentials.NONE ? this : new SecurityIdentity(this, credentials, false); } /** * Create a new security identity which is the same as this one, but which includes the given credential as a * private credential. * * @param credential the credential (must not be {@code null}) * @return the new identity */ public SecurityIdentity withPrivateCredential(Credential credential) { Assert.checkNotNullParam("credential", credential); return new SecurityIdentity(this, credential, true); } /** * Create a new security identity which is the same as this one, but which includes the given credentials as * private credentials. * * @param credentials the credential set (must not be {@code null}) * @return the new identity */ public SecurityIdentity withPrivateCredentials(final IdentityCredentials credentials) { Assert.checkNotNullParam("credentials", credentials); return credentials == IdentityCredentials.NONE ? this : new SecurityIdentity(this, credentials, true); } /** * Create a new security identity which is the same as this one, but which includes the given runtime attributes. * * @param runtimeAttributes the runtime attributes (must not be {@code null}) * @return the new identity */ public SecurityIdentity withRuntimeAttributes(final Attributes runtimeAttributes) { Assert.checkNotNullParam("runtimeAttributes", runtimeAttributes); return runtimeAttributes == Attributes.EMPTY ? this : new SecurityIdentity(this, runtimeAttributes); } /** * Get the private credentials of this identity. The caller must have the {@code getPrivateCredentials} {@link ElytronPermission}. * * @return the private credentials of this identity (not {@code null}) */ public IdentityCredentials getPrivateCredentials() { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(PRIVATE_CREDENTIALS_PERMISSION); } return getPrivateCredentialsPrivate(); } /** * Get this identity. * * @return this identity */ public SecurityIdentity get() { return this; } /** * Create a new flexible identity association, initializing it with this identity. * * @return the new flexible identity association (not {@code null}) */ public FlexibleIdentityAssociation createFlexibleAssociation() { return new FlexibleIdentityAssociation(securityDomain, this); } IdentityCredentials getPrivateCredentialsPrivate() { return privateCredentials; } @Override public String toString() { return "SecurityIdentity{" + "principal=" + principal + ", securityDomain=" + securityDomain + ", authorizationIdentity=" + authorizationIdentity + ", realmInfo=" + realmInfo + ", creationTime=" + creationTime + '}'; } }