org.wso2.carbon.identity.sso.saml.ui.session.mgt.FESessionManager.java Source code

Java tutorial

Introduction

Here is the source code for org.wso2.carbon.identity.sso.saml.ui.session.mgt.FESessionManager.java

Source

/*
 * Copyright (c) 2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. 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.wso2.carbon.identity.sso.saml.ui.session.mgt;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * This class is used to maintain a session map at the SSO FE. This class is introduced
 * to get rid of the session usage to hold the meta information of a incoming authentication
 * request.  This class implements Singleton since there can be only one session manager.
 */
public enum FESessionManager {

    INSTANCE;
    private static SecureRandom secureRandomInstance;
    private static MessageDigest messageDigest;
    private static Log log = LogFactory.getLog(FESessionManager.class);

    public ConcurrentMap<String, FESessionBean> sessionMap;

    static {
        initialize();
    }

    private FESessionManager() {
        this.sessionMap = new ConcurrentHashMap<String, FESessionBean>();
    }

    /**
     * Initialize the FESessionManager class. Create the instances of SecureRandom and
     * MessageDigest and keep them as static references.
     */
    private static void initialize() {
        try {
            secureRandomInstance = SecureRandom.getInstance("SHA1PRNG");
            messageDigest = MessageDigest.getInstance("SHA-1");
        } catch (NoSuchAlgorithmException e) {
            log.error("Error when initializing the SAML2 SSO FESessionManager.", e);
            throw new RuntimeException(e);
        }
    }

    public static FESessionManager getInstance() {

        return INSTANCE;
    }

    /**
     * Get the corresponding FESessionBean for a particular session id
     *
     * @param sessionID session id
     * @return FESessionBean
     */
    public FESessionBean getFESessionBean(String sessionID) {
        if (sessionMap.containsKey(sessionID)) {
            return sessionMap.get(sessionID);
        }
        return null;
    }

    /**
     * Add a new session bean object to the session map
     *
     * @param sessionBean
     * @return created session id
     */
    public String addNewSession(FESessionBean sessionBean) {
        String sessionId = generateSessionId();
        sessionMap.put(sessionId, sessionBean);
        return sessionId;
    }

    /**
     * Remove an existing session.
     *
     * @param sessionId session id
     */
    public void removeSession(String sessionId) {
        if (sessionMap.containsKey(sessionId)) {
            sessionMap.remove(sessionId);
        } else {
            log.warn("The session bean with the ID : " + sessionId + "is not available in the session map");
        }
    }

    /**
     * Generate a session id to store the FE session beans
     *
     * @return generated session id
     */
    private String generateSessionId() {
        //generate the random number
        String randomNum = Integer.toString(secureRandomInstance.nextInt());
        //get its digest
        byte[] result = messageDigest.digest(randomNum.getBytes(StandardCharsets.UTF_8));
        return hexEncode(result);
    }

    /**
     * The byte[] returned by MessageDigest does not have a nice
     * textual representation, so some form of encoding is usually performed.
     *
     * @param digestValue digested bite array
     * @return Encoded string
     */
    private String hexEncode(byte[] digestValue) {
        StringBuilder result = new StringBuilder();
        char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
        for (int idx = 0; idx < digestValue.length; ++idx) {
            byte b = digestValue[idx];
            result.append(digits[(b & 0xf0) >> 4]);
            result.append(digits[b & 0x0f]);
        }
        return result.toString();
    }

}