org.frat.common.security.BaseSecurityContext.java Source code

Java tutorial

Introduction

Here is the source code for org.frat.common.security.BaseSecurityContext.java

Source

/*
 * Project Name: qcpj-trunk
 * File Name: SecurityContext.java
 * Class Name: SecurityContext
 *
 * Copyright 2014 Hengtian Software Inc
 *
 * Licensed under the Hengtiansoft
 *
 * http://www.hengtiansoft.com
 *
 * 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.frat.common.security;

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

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.CachingSecurityManager;
import org.apache.shiro.mgt.RealmSecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.frat.common.dto.SysUserDto;
import org.frat.common.security.authc.ShiroJdbcRealm;
import org.frat.common.service.SysUserService;
import org.frat.common.util.AppConfigUtil;
import org.frat.common.util.ApplicationContextUtil;
import org.frat.common.util.DateUtil;
import org.frat.common.util.StackTraceUtil;
import org.frat.common.util.StringUtil;
import org.frat.common.util.web.WebUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;

/**
 * Class Name: SecurityContext Description: TODO.
 * 
 * @author SC
 * 
 */
public class BaseSecurityContext {

    private static final String USER_KEY = "shiro.user";

    private static final Logger LOGGER = LoggerFactory.getLogger(BaseSecurityContext.class);

    private static final String CACHE_NAME_AUTHZ = "cache.name.authz";

    private static final String CACHE_NAME_AUTHC = "cache.name.authc";

    @Autowired
    private static SessionDAO sessionDAO;
    @Autowired
    private static EhCacheManager shiroCacheManager;

    /**
     * Description: ???.
     * 
     * @return
     */
    public SysUserDto getCurrentUser() {
        Subject subject = getSubject();
        if (subject == null) {
            return null;
        }
        return (SysUserDto) subject.getSession().getAttribute(USER_KEY);
    }

    /**
     * Description: ?.
     * 
     * @return
     */
    public static boolean isAuthenticated() {
        Subject subject = getSubject();
        if (subject == null) {
            return false;
        }
        return getSubject().isAuthenticated();
    }

    /**
     * Description: ??.
     * 
     * @return
     */
    public static boolean isRemembered() {
        Subject subject = getSubject();
        if (subject == null) {
            return false;
        }
        return getSubject().isRemembered();
    }

    /**
     * Description: ???, ???.
     * 
     * @param userId
     * @param password
     * @return the new session
     * @throws IncorrectCredentialsException
     *             ?
     * @throws LockedAccountException
     *             ?
     */
    public static Session login(String userName, String password, Boolean rememberMe)
            throws IncorrectCredentialsException, LockedAccountException {
        long start = System.currentTimeMillis();
        UsernamePasswordToken token = new UsernamePasswordToken(userName, password, rememberMe);
        Subject currentUser = SecurityUtils.getSubject();
        // This is to prevent session fixation attack, see:
        // https://issues.apache.org/jira/browse/SHIRO-170
        currentUser.getSession().stop();
        // this will create a new session by default in applications that allow
        // session state:
        currentUser.login(token);
        Session session = currentUser.getSession();
        LOGGER.debug("User {} login successfully, session id {}", userName, session.getId());
        // UserService userService =
        // ApplicationContextUtil.getBean(UserService.class);
        // User user = userService.findUserByUserName(userName);
        SysUserService sysUserService = ApplicationContextUtil.getBean(SysUserService.class);
        SysUserDto user = sysUserService.findSysUserByUserName(userName);
        session.setAttribute(USER_KEY, user);
        long end = System.currentTimeMillis();
        LOGGER.debug("login() completed for user {}, total time spent: {}ms", userName, end - start);

        // 
        // ServletContext application=WebUtil.getServletContext();
        // @SuppressWarnings("unchecked")
        // HashSet<HttpSession> loginSessions = (HashSet<HttpSession>)
        // application.getAttribute("loginSessions");
        // if (loginSessions == null) {
        // loginSessions = new HashSet<HttpSession>();
        // application.setAttribute("loginSessions", loginSessions);
        // }
        // // session?HashSet
        // loginSessions.add(WebUtil.getThreadSession());
        // LOGGER.debug(""+loginSessions.size());
        return session;
    }

    /**
     * ?.
     */
    public static void logout() {
        getSubject().logout();
    }

    /**
     * Description: ??.
     * 
     * @param userId
     */
    public static void clearAuthzCache(String userName) {
        RealmSecurityManager sm = (RealmSecurityManager) SecurityUtils.getSecurityManager();
        for (Realm realm : sm.getRealms()) {
            if (realm instanceof ShiroJdbcRealm) {
                ShiroJdbcRealm jdbcRealm = (ShiroJdbcRealm) realm;
                SimplePrincipalCollection spc = new SimplePrincipalCollection(userName, realm.getName());
                jdbcRealm.clearAuthorizationCache(spc);
            }
        }
        LOGGER.info("Authorization cache cleared for user: {}", userName);
    }

    /**
     * Description: ??.
     * 
     * @param users
     */
    public static void clearAuthzCache(List<String> users) {
        for (String user : users) {
            clearAuthzCache(user);
        }
    }

    /**
     * Description: ??.
     * 
     * @param users
     */
    public static void clearAllAuthzCache() {
        CacheManager cm = (CacheManager) ((CachingSecurityManager) SecurityUtils.getSecurityManager())
                .getCacheManager();
        cm.getCache(AppConfigUtil.getConfig(CACHE_NAME_AUTHZ)).clear();
    }

    /**
     * Description: ??.
     * 
     * @param userId
     */
    public static void clearAuthcCache(String userName) {
        RealmSecurityManager sm = (RealmSecurityManager) SecurityUtils.getSecurityManager();
        for (Realm realm : sm.getRealms()) {
            if (realm instanceof ShiroJdbcRealm) {
                ShiroJdbcRealm jdbcRealm = (ShiroJdbcRealm) realm;
                SimplePrincipalCollection spc = new SimplePrincipalCollection(userName, realm.getName());
                jdbcRealm.clearAuthenticationCache(spc);
            }
        }
    }

    /**
     * Description: list??.
     * 
     * @param users
     */
    public static void clearAuthcCache(List<String> users) {
        for (String user : users) {
            clearAuthcCache(user);
        }
    }

    /**
     * Description: ??.
     * 
     * @param users
     */
    public static void clearAllAuthcCache() {
        CacheManager cm = (CacheManager) ((CachingSecurityManager) SecurityUtils.getSecurityManager())
                .getCacheManager();
        cm.getCache(AppConfigUtil.getConfig(CACHE_NAME_AUTHC)).clear();
    }

    /**
     * Description: ???.
     * 
     */
    public void clearCurrentAuthzCache() {
        clearAuthzCache(getSubject().getPrincipal().toString());
    }

    /**
     * Description: ?????.
     * 
     * @param permission
     * @return
     */
    public boolean hasPermission(String permission) {
        Subject subject = getSubject();
        return subject == null ? false : subject.isPermitted(permission);
    }

    /**
     * Description: ?????.
     * 
     * @param permissions
     * @return
     */
    public boolean hasAllPermissions(String... permissions) {
        Subject subject = getSubject();
        return subject == null ? false : subject.isPermittedAll(permissions);
    }

    /**
     * Description: ??????.
     * 
     * @param permissions
     * @return
     */
    public static boolean hasAnyPermission(String[] permissions) {
        Subject subject = getSubject();
        if (subject != null && permissions != null) {
            for (int i = 0; i < permissions.length; i++) {
                String permission = permissions[i];
                if (permission != null && subject.isPermitted(permission.trim())) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * ???.
     * 
     * @see org.apache.shiro.subject.Subject#checkPermission(String permission)
     * @param permission
     * @throws AuthorizationException
     */
    public void checkPermission(String permission) throws AuthorizationException {
        Subject subject = getSubject();
        if (subject == null) {
            throw new AuthorizationException("No permission as there is no subject bound.");
        }
        subject.checkPermission(permission);
    }

    /**
     * Description: ???????hasPermission.
     * 
     * @param roles
     * @return
     */
    @Deprecated
    public boolean hasAllRoles(Collection<String> roles) {
        return getSubject().hasAllRoles(roles);
    }

    /**
     * Description: ????????hasPermission.
     * 
     * @param roleNames
     * @return
     */
    @Deprecated
    public boolean hasAnyRoles(Collection<String> roleNames) {
        Subject subject = getSubject();
        if (subject != null && roleNames != null) {
            for (String role : roleNames) {
                if (role != null && subject.hasRole(role)) {
                    return true;
                }
            }
        }
        return false;
    }

    private static Subject getSubject() {
        try {
            return SecurityUtils.getSubject();
        } catch (Exception e) {
            LOGGER.warn("Failed to get Subject, maybe user is not login or session is lost:", e);
            return null;
        }
    }

    /**
     * @param username
     * @return
     */
    public static HashSet<HttpSession> getSessionByUsername(String username) {

        @SuppressWarnings("unchecked")
        HashSet<HttpSession> sessions = (HashSet<HttpSession>) WebUtil.getThreadSession().getServletContext()
                .getAttribute("loginSessions");
        HashSet<HttpSession> httpSessions = new HashSet<HttpSession>();
        for (HttpSession session : sessions) {
            if (null != session && StringUtil.isEqualObj(
                    String.valueOf(session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY)), username)) {
                httpSessions.add(session);
            }
        }
        return httpSessions;
    }

    /**
     * .
     * 
     * @param username
     */
    public static void kickOutUser(String username) {
        try {
            // applicationHashSet?session
            @SuppressWarnings("unchecked")
            HashSet<HttpSession> sessions = (HashSet<HttpSession>) WebUtil.getServletContext()
                    .getAttribute("loginSessions");
            List<HttpSession> sessionList = new ArrayList<HttpSession>();
            for (HttpSession session : sessions) {
                if (null != session && StringUtil.isEqualObj(
                        String.valueOf(session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY)),
                        username)) {
                    // session
                    if (!StringUtil.isEqualObj(session.getId(), WebUtil.getSessionId())) {
                        sessionList.add(session);
                    }
                }
            }
            for (HttpSession session : sessionList) {
                session.invalidate();
                LOGGER.info("success kick out session [" + session.getId() + "]");
                LOGGER.info("success kick out user [" + username + "]");
            }
        } catch (Exception e) {
            LOGGER.error("");
            LOGGER.error(StackTraceUtil.getStackTrace(e));
        }
    }

    /**
     * .
     * 
     * @param username
     */
    public static void kickOutUnLogin() {
        try {
            WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
            ServletContext servletContext = webApplicationContext.getServletContext();

            // applicationHashSet?session
            @SuppressWarnings("unchecked")
            HashSet<HttpSession> sessions = (HashSet<HttpSession>) servletContext.getAttribute("loginSessions");
            List<HttpSession> sessionList = new ArrayList<HttpSession>();
            if (StringUtil.isObjNotNull(sessions)) {
                for (HttpSession session : sessions) {
                    SysUserDto user = (SysUserDto) session.getAttribute("shiro.user");
                    if (null != session && StringUtil.isObjNull(user)) {
                        // LOGGER.debug("getLastAccessedTime="+ new
                        // Date(session.getLastAccessedTime()));
                        // LOGGER.debug("now="+ new Date());
                        int diffTime = DateUtil.diffTime(new Date(), new Date(session.getLastAccessedTime()));
                        // LOGGER.debug("diffTime="+diffTime);
                        if (diffTime > 300) {
                            sessionList.add(session);
                        }
                    }
                }
                for (HttpSession session : sessionList) {
                    session.invalidate();
                    LOGGER.debug("success kick out UnLogin session [" + session.getId() + "]");
                }
            }
        } catch (Exception e) {
            LOGGER.error("");
            LOGGER.error(StackTraceUtil.getStackTrace(e));
        }

    }

}