io.buji.pac4j.ClientRealm.java Source code

Java tutorial

Introduction

Here is the source code for io.buji.pac4j.ClientRealm.java

Source

/*
 * Licensed to the bujiio organization of the Shiro project 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 io.buji.pac4j;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.util.StringUtils;
import org.pac4j.core.client.Client;
import org.pac4j.core.client.Clients;
import org.pac4j.core.credentials.Credentials;
import org.pac4j.core.exception.TechnicalException;
import org.pac4j.core.profile.CommonProfile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This realm implementation is dedicated to authentication. It acts on
 * credentials after the user authenticates at the provider and finishes the
 * authentication process by getting the user profile from the provider.
 *
 * @author Jerome Leleu
 * @since 1.0.0
 */
public class ClientRealm extends AuthorizingRealm {

    private static Logger log = LoggerFactory.getLogger(ClientRealm.class);

    // the clients definition
    private Clients clients;

    // default roles applied to authenticated user
    private String defaultRoles;

    // default permissions applied to authenticated user
    private String defaultPermissions;

    public ClientRealm() {
        setAuthenticationTokenClass(ClientToken.class);
    }

    /**
     * Authenticates a user and retrieves its user profile.
     *
     * @param authenticationToken
     *            the authentication token
     * @throws AuthenticationException
     *             if there is an error during authentication.
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(final AuthenticationToken authenticationToken)
            throws AuthenticationException {
        try {
            return internalGetAuthenticationInfo(authenticationToken);
        } catch (final TechnicalException e) {
            throw new AuthenticationException(e);
        }
    }

    /**
     * Authenticates a user and retrieves its user profile.
     *
     * @param authenticationToken the authentication token
     * @return authentication information
     */
    @SuppressWarnings("unchecked")
    protected AuthenticationInfo internalGetAuthenticationInfo(final AuthenticationToken authenticationToken) {
        final ClientToken clientToken = (ClientToken) authenticationToken;
        log.debug("clientToken : {}", clientToken);
        // token must be provided
        if (clientToken == null) {
            return null;
        }

        // credentials
        final Credentials credentials = (Credentials) clientToken.getCredentials();
        log.debug("credentials : {}", credentials);

        // client
        final Client<Credentials, CommonProfile> client = this.clients.findClient(clientToken.getClientName());
        log.debug("client : {}", client);

        // finish authentication process : get the user profile
        final CommonProfile profile = client.getUserProfile(credentials, clientToken.getContext());
        log.debug("profile : {}", profile);
        // no profile
        if (profile == null) {
            final String message = "No profile retrieved from authentication using client : " + client
                    + " and credentials : " + credentials;
            log.info(message);
            throw new NoAuthenticationException(message);
        }

        // refresh authentication token with user id
        final String userId = profile.getTypedId();
        clientToken.setUserId(userId);
        // set rememberMe status
        clientToken.setRememberMe(profile.isRemembered());
        // create simple authentication info
        final List<? extends Object> principals = CollectionUtils.asList(userId, profile);
        final PrincipalCollection principalCollection = new SimplePrincipalCollection(principals, getName());
        return new SimpleAuthenticationInfo(principalCollection, credentials);
    }

    /**
     * Retrieves the AuthorizationInfo for the given principals.
     *
     * @param principals
     *            the primary identifying principals of the AuthorizationInfo
     *            that should be retrieved.
     * @return the AuthorizationInfo associated with this principals.
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(final PrincipalCollection principals) {
        Set<String> roles = new HashSet<>(split(this.defaultRoles));
        Set<String> permissions = new HashSet<>(split(this.defaultPermissions));
        // get roles and permissions from principals
        Collection<CommonProfile> profiles = principals.byType(CommonProfile.class);
        if (profiles != null) {
            for (CommonProfile profile : profiles) {
                if (profile != null) {
                    roles.addAll(profile.getRoles());
                    permissions.addAll(profile.getPermissions());
                }
            }
        }
        // create simple authorization info
        final SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addRoles(roles);
        simpleAuthorizationInfo.addStringPermissions(permissions);
        return simpleAuthorizationInfo;
    }

    /**
     * Split a string into a list of not empty and trimmed strings, delimiter is
     * a comma.
     *
     * @param s
     *            the input string
     * @return the list of not empty and trimmed strings
     */
    protected List<String> split(final String s) {
        final List<String> list = new ArrayList<>();
        final String[] elements = StringUtils.split(s, ',');
        if (elements != null && elements.length > 0) {
            for (final String element : elements) {
                if (StringUtils.hasText(element)) {
                    list.add(element.trim());
                }
            }
        }
        return list;
    }

    public Clients getClients() {
        return this.clients;
    }

    public void setClients(final Clients clients) throws TechnicalException {
        this.clients = clients;
        clients.init();
    }

    public String getDefaultRoles() {
        return this.defaultRoles;
    }

    public void setDefaultRoles(final String defaultRoles) {
        this.defaultRoles = defaultRoles;
    }

    public String getDefaultPermissions() {
        return this.defaultPermissions;
    }

    public void setDefaultPermissions(final String defaultPermissions) {
        this.defaultPermissions = defaultPermissions;
    }
}