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

org.nuiton.web.security.TopiaSecurityRealm Maven / Gradle / Ivy

There is a newer version: 1.20
Show newest version
/*
 * #%L
 * Nuiton Web :: Nuiton Security
 * %%
 * Copyright (C) 2012 - 2013 CodeLutin, Chatellier Eric
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as 
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public 
 * License along with this program.  If not, see
 * .
 * #L%
 */

package org.nuiton.web.security;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.CredentialsMatcher;
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.nuiton.config.ApplicationConfig;
import org.nuiton.util.StringUtil;
import org.nuiton.web.SecurityTopiaApplicationContext;
import org.nuiton.web.SecurityTopiaPersistenceContext;

/**
 * Topia shiro realm finding user in database.
 * 
 * @author Eric Chatellier
 */
public class TopiaSecurityRealm extends AuthorizingRealm implements CredentialsMatcher {

    private static final Log log = LogFactory.getLog(TopiaSecurityRealm.class);

    protected SecurityTopiaApplicationContext rootContext;

    protected ApplicationConfig config;

    /** Authorization cache (invalidated at login). */
    protected transient Map authorizationCache;

    public TopiaSecurityRealm(SecurityTopiaApplicationContext rootContext, ApplicationConfig config) {
        this.rootContext = rootContext;
        this.config = config;
        authorizationCache = new HashMap();
        setCredentialsMatcher(this);
    }

    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        char[] tokenCredentials = (char[]) token.getCredentials();
        String submittedPassword = String.valueOf(tokenCredentials);
        String submittedHashedPassword = StringUtil.encodeMD5(submittedPassword);

        String expectedHashedPassword = (String) info.getCredentials();
        return expectedHashedPassword.equals(submittedHashedPassword);
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        String login = (String) principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo result = authorizationCache.get(login);
        if (result == null) {
            Properties props = config.getFlatOptions();
            SecurityTopiaPersistenceContext transaction = null;
            try {
                transaction = rootContext.newPersistenceContext();
                SecurityUserTopiaDao securityUserDAO = transaction.getSecurityUserDao();
    
                if (log.isDebugEnabled()) {
                    log.debug("Build autorisation list for user : " + login);
                }
    
                SecurityUser securityUser = securityUserDAO.findByLogin(login);
                result = new SimpleAuthorizationInfo();
                for (SecurityRole role : securityUser.getSecurityRole()) {
                    for (String permission : role.getPermissions()) {
                        //result.addStringPermission(permission);
                        if (log.isDebugEnabled()) {
                            log.debug("- add permission : " + permission);
                        }
    
                        for (String prop : props.stringPropertyNames()) {
                            if (prop.startsWith("topia.security.permission.")) {
                                String endProp = StringUtils.removeStart(prop, "topia.security.permission.");
                                String[] subs = endProp.split("\\.");
                                if (subs.length == 3) {
                                    if (subs[2].equals("perm")) {
                                        if (subs[1].equals(permission)) {
                                            String perms = props.getProperty(prop);
                                            // use ; separator because shiro use ,
                                            String[] permTab = perms.split("\\s*\\;\\s*");
                                            for (String perm : permTab) {
                                                result.addStringPermission(perm);
                                                if (log.isDebugEnabled()) {
                                                    log.debug("  string permission : " + perm);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
    
                // si seul l'utilisateur anon existe
                // on lui offre une promotion
                if (login.equals(SecurityShiroFilter.ANON_LOGIN) && securityUserDAO.count() == 1) {
                    result.addStringPermission("*");
                    if (log.isDebugEnabled()) {
                        log.debug("Grant all right (*) because no user exists");
                    }
                }
    
                // si la securité est desactivee, 
                if (config.getOptionAsBoolean("topia.security.disable")) {
                    result.addStringPermission("*");
                }
    
                // ajout de l'url de login et logout quand meme !!!
                result.addStringPermission("url" + SecurityUtil.convertToShiroPerm(config.getOption("topia.security.loginurl"),
                        config.getOption("topia.security.separators")));
                result.addStringPermission("url" + SecurityUtil.convertToShiroPerm(config.getOption("topia.security.logouturl"),
                        config.getOption("topia.security.separators")));

                // cache authorization
                authorizationCache.put(login, result);
            } catch (Exception ex) {
                if (log.isErrorEnabled()) {
                    log.error("Can't get user permission", ex);
                }
            } finally {
                if (transaction != null) {
                    transaction.close();
                }
            }
        } else {
            if (log.isTraceEnabled()) {
                log.trace("Using autorisation from cache for " + login);
            }
        }
        return result;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        String login = usernamePasswordToken.getUsername();
        //char[] password = usernamePasswordToken.getPassword();

        if (log.isDebugEnabled()) {
            log.debug("doGetAuthenticationInfo for login : " + login);
        }

        AuthenticationInfo result = null;
        SecurityTopiaPersistenceContext transaction = null;
        try {
            transaction = rootContext.newPersistenceContext();
            SecurityUserTopiaDao securityUserDAO = transaction.getSecurityUserDao();

            SecurityUser securityUser = securityUserDAO.forLoginEquals(login).findUniqueOrNull();
            if (securityUser != null) {
                if (login.equals(SecurityShiroFilter.ANON_LOGIN)) {
                    result = new SimpleAuthenticationInfo(securityUser.getLogin(),
                        StringUtil.encodeMD5(""), getName());
                } else {
                    result = new SimpleAuthenticationInfo(securityUser.getLogin(),
                        securityUser.getPassword(), getName());
                }

                // invalidate cache for login
                authorizationCache.remove(login);
            }

        } finally {
            if (transaction != null) {
                transaction.close();
            }
        }

        return result;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy