com.itrus.ca.modules.sys.security.SystemAuthorizingRealm.java Source code

Java tutorial

Introduction

Here is the source code for com.itrus.ca.modules.sys.security.SystemAuthorizingRealm.java

Source

/**
 * Copyright &copy; 2012-2013 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package com.itrus.ca.modules.sys.security;

import java.io.Serializable;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
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.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Service;
import com.itrus.ca.common.servlet.ValidateCodeServlet;
import com.itrus.ca.common.utils.CacheUtils;
import com.itrus.ca.common.utils.Encodes;
import com.itrus.ca.common.utils.SpringContextHolder;
import com.itrus.ca.modules.sys.entity.Menu;
import com.itrus.ca.modules.sys.entity.Office;
import com.itrus.ca.modules.sys.entity.SingleCvm;
import com.itrus.ca.modules.sys.entity.User;
import com.itrus.ca.modules.sys.service.SystemService;
import com.itrus.ca.modules.sys.utils.UserUtils;
import com.itrus.ca.modules.sys.web.LoginController;
import com.itrus.ca.modules.work.web.CertController;

import cn.topca.sp.cvm.CVM;
import cn.topca.sp.svm.SVM;
import cn.topca.sp.x509.X509Certificate;

/**
 * ?
 * @author ThinkGem
 * @version 2013-5-29
 */
@Service
@DependsOn({ "userDao", "roleDao", "menuDao" })
public class SystemAuthorizingRealm extends AuthorizingRealm {

    Logger log = Logger.getLogger(SystemAuthorizingRealm.class);

    private SystemService systemService;

    @Value(value = "${isCheckRevoked}")
    String isCheckRevoked;

    @Value(value = "${isCheckValidPeriod}")
    String isCheckValidPeriod;

    /**
     * ?, 
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) {
        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;

        if (token.getLoginType() != null && token.getLoginType().equals("1")) {

            try {

                String randomString = token.getRandomString();
                if (randomString == null) {
                    throw new CaptchaException("?");
                }

                String toSign = "LOGONDATA:" + randomString;

                log.debug(":" + toSign);
                byte[] signedDate = Base64.decodeBase64(token.getSignedData());
                log.debug("Base64:" + Arrays.toString(signedDate));
                X509Certificate certificate = SVM.verifyPKCS7SignedData(signedDate, toSign.getBytes());
                log.debug("?:" + certificate);

                log.debug("??:" + certificate.getCertSubjectNames().getItem("SN"));

                /*User user = getSystemService().getUserByLoginName(certificate.getCertSubjectNames().getItem("CN"));*/

                User user = getSystemService()
                        .getUserByIdentityNumber(certificate.getCertSubjectNames().getItem("SN"));
                log.debug(":" + user);

                if (user == null) {
                    throw new CaptchaException("??");
                }

                log.debug("??:" + user.getLoginName());

                if (user.getLoginType() == null || !user.getLoginType().equals("1")) {
                    throw new CaptchaException("????");
                    //return null;
                }
                if (user.getOffice().getDelFlag().equals(Office.DEL_FLAG_DELETE)) {
                    throw new CaptchaException("?");
                    //return null;
                }

                CVM cvm = SingleCvm.getInstance().getCVM();
                log.debug("isCheckRevoked:" + isCheckRevoked);
                log.debug("isCheckValidPeriod:" + isCheckValidPeriod);

                int status = cvm.verifyCertificate(certificate, Boolean.parseBoolean(isCheckRevoked),
                        Boolean.parseBoolean(isCheckValidPeriod));
                log.debug("??:" + status);
                if (status != 0) {
                    if (status == -1) {
                        throw new CaptchaException(
                                "?,CVM?,??");
                    }
                    if (status == 1) {
                        throw new CaptchaException("??");
                    }
                    if (status == 2) {
                        throw new CaptchaException("???");
                    }
                    if (status == 3) {
                        throw new CaptchaException(
                                "????=[" + certificate.getCertSubjectNames() + "]");
                    }
                    if (status == 4) {
                        throw new CaptchaException("?CA??,??");
                    }
                    if (status == 5) {
                        throw new CaptchaException("?CRL,??");
                    }
                    if (status == 6) {
                        throw new CaptchaException("???");
                    }

                    throw new CaptchaException("???");
                }

                String password = SystemService.entryptPassword("certLogin");

                byte[] salt = Encodes.decodeHex(password.substring(0, 16));
                return new SimpleAuthenticationInfo(new Principal(user), password.substring(16),
                        ByteSource.Util.bytes(salt), getName());

            } catch (Exception e) {
                if (e.getMessage().contains("Could not open connection")) {
                    throw new CaptchaException("??:??");
                }
                //   e.printStackTrace();
                log.debug("?:" + e.getMessage());
                throw new CaptchaException("??:" + e.getMessage());
            }

        } else {
            if (token.getUsername().length() < 30
                    && LoginController.isValidateCodeLogin(token.getUsername(), false, false)) {
                // ??
                Session session = SecurityUtils.getSubject().getSession();
                String code = (String) session.getAttribute(ValidateCodeServlet.VALIDATE_CODE);
                if (token.getCaptcha() == null || !token.getCaptcha().toUpperCase().equals(code)) {
                    throw new CaptchaException("??.");
                }
            }
            User user = getSystemService().getUserByLoginName(token.getUsername());
            if (user == null) {
                return null;
            }
            if (user.getLoginType() == null || !user.getLoginType().equals("0")) {
                throw new LoginTypeException(".");
            }
            if (user.getOffice().getDelFlag().equals(Office.DEL_FLAG_DELETE)) {
                return null;
            }
            byte[] salt = Encodes.decodeHex(user.getPassword().substring(0, 16));
            return new SimpleAuthenticationInfo(new Principal(user), user.getPassword().substring(16),
                    ByteSource.Util.bytes(salt), getName());
        }

    }

    /**
     * ?, ???
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        Principal principal = (Principal) getAvailablePrincipal(principals);
        User user = getSystemService().getUserByLoginName(principal.getLoginName());
        if (user != null) {
            UserUtils.putCache("user", user);
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            List<Menu> list = UserUtils.getMenuList();
            for (Menu menu : list) {
                if (StringUtils.isNotBlank(menu.getPermission())) {
                    // Permission???
                    info.addStringPermission(menu.getPermission());
                }
            }
            return info;
        } else {
            return null;
        }
    }

    /**
     * ?Hash
     */
    @PostConstruct
    public void initCredentialsMatcher() {
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(SystemService.HASH_ALGORITHM);
        matcher.setHashIterations(SystemService.HASH_INTERATIONS);
        setCredentialsMatcher(matcher);
    }

    /**
     * ?????
     */
    public void clearCachedAuthorizationInfo(String principal) {
        SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
        clearCachedAuthorizationInfo(principals);
    }

    /**
     * ??
     */
    public void clearAllCachedAuthorizationInfo() {
        Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
        if (cache != null) {
            for (Object key : cache.keys()) {
                cache.remove(key);
            }
        }
    }

    /**
     * ?
     */
    public SystemService getSystemService() {
        if (systemService == null) {
            systemService = SpringContextHolder.getBean(SystemService.class);
        }
        return systemService;
    }

    /**
     * ??
     */
    public static class Principal implements Serializable {

        private static final long serialVersionUID = 1L;

        private Long id;
        private String loginName;
        private String name;
        private Map<String, Object> cacheMap;

        public Principal(User user) {
            this.id = user.getId();
            this.loginName = user.getLoginName();
            this.name = user.getName();
        }

        public Long getId() {
            return id;
        }

        public String getLoginName() {
            return loginName;
        }

        public String getName() {
            return name;
        }

        public Map<String, Object> getCacheMap() {
            if (cacheMap == null) {
                cacheMap = new HashMap<String, Object>();
            }
            return cacheMap;
        }

    }
}