package com.github.ebnew.ki4so.core.authentication; import com.github.ebnew.ki4so.core.app.KnightApp; import com.github.ebnew.ki4so.core.app.KnightAppService; import com.github.ebnew.ki4so.core.authentication.status.KnightUserLoggedStatusStore; import com.github.ebnew.ki4so.core.authentication.status.KnightUserLoginStatus; import com.github.ebnew.ki4so.core.key.KnightKey; import com.github.ebnew.ki4so.core.key.KnightKeyService; import com.github.ebnew.ki4so.core.model.KnightCredentialInfo; import com.github.ebnew.ki4so.web.utils.WebConstants; import org.apache.log4j.Logger; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * 默认的后置处理器,提供抽象的方法由具体的子类实现 * @author zhenglu * @since 15/4/23 */ public class KnightDefaultAuthenticationPostHandler implements KnightAuthenticationPostHandler{ private static final Logger logger = Logger.getLogger(KnightDefaultAuthenticationPostHandler.class); /** * 服务端过期时间设置为3个月 */ private static final Long SERVER_INVALID = 3L*30*24*60*60*1000; /** * 客户端失效时间为1分钟 */ private static final Long CLIENT_INVALID = 60L * 1000; private KnightEncryCredentialManager encryCredentialManager; private KnightKeyService keyService; private KnightAppService appService; private KnightUserLoggedStatusStore userLoggedStatusStore; @Override public KnightAuthentication postAuthentication(KnightCredential credential, KnightUser user) { Date createTime = new Date(); // 若认证通过,则返回认证的结果对象 KnightAuthenticationImpl authentication = new KnightAuthenticationImpl(); authentication.setAuthenticatedDate(createTime); authentication.setAuthenticatedDate(createTime); authentication.setUser(user); encryCredentialWithServerKey(authentication, credential, user); encryCredentialWithAppKey(authentication, credential, user); return authentication; } /** * 使用ki4so服务器本身的key对凭据进行加密处理 * @param authentication * @param credential * @param user */ private void encryCredentialWithServerKey(KnightAuthenticationImpl authentication,KnightCredential credential,KnightUser user){ //如果是原始凭据,则需要进行加密操作处理 if(credential != null && credential.isOriginal()){ //查找自身服务对应的应用信息 KnightApp app = appService.findKi4soServerApp(); if(app == null ){ logger.info("no ki4so key info"); } String encryStr = encryCredentialManager.encrypt(buildEncryCredentialInfo(app.getAppId(),authentication,user,SERVER_INVALID)); Map<String,Object> attributes = authentication.getAttrbutes(); if(attributes == null){ attributes = new HashMap<String, Object>(); } attributes.put(KNIGHT_SERVER_EC_KEY,encryStr); authentication.setAttributes(attributes); } } private void encryCredentialWithAppKey(KnightAuthenticationImpl authentication,KnightCredential credential,KnightUser user){ KnightAbstractParameter abstractParameter = null; if(credential != null && credential instanceof KnightAbstractParameter){ abstractParameter = (KnightAbstractParameter)credential; } //若登录对应的服务参数service的值不为空,则使用该service对应的应用的key进行加密 if(authentication != null && abstractParameter != null && abstractParameter.getParameterValue(WebConstants.SERVICE_PARAM_NAME)!=null){ String service = abstractParameter.getParameterValue(WebConstants.SERVICE_PARAM_NAME).toString().trim().toLowerCase(); //service 不为空,且符合http协议url格式,则继续加密 if(service.length() > 0){ KnightApp app = appService.findAppByHost(service); if(app != null){ String encryCredential = encryCredentialManager.encrypt(buildEncryCredentialInfo(app.getAppId(),authentication,user,CLIENT_INVALID)); Map<String,Object> attributes = authentication.getAttrbutes(); if(attributes == null){ attributes = new HashMap<String, Object>(); } attributes.put(KNIGHT_CLIENT_EC_KEY,encryCredential); attributes.put(WebConstants.SERVICE_PARAM_NAME,service); authentication.setAttributes(attributes); //更新用户登录状态到存储器中 KnightUserLoginStatus status = new KnightUserLoginStatus(); status.setAppId(app.getAppId()); status.setUserId(user.getId()); status.setLoginDate(authentication.getAuthenticateDate()); userLoggedStatusStore.addUserLoggerStatus(status); } } } } private KnightCredentialInfo buildEncryCredentialInfo(String appId,KnightAuthenticationImpl authentication,KnightUser user,long duration){ KnightCredentialInfo info = new KnightCredentialInfo(); if(authentication == null || user == null){ return info; } KnightKey key = keyService.findKeyByAppId(appId); if(key == null){ logger.info("no key for appId:: " + appId); } info.setAppId(appId); info.setCreateTime(authentication.getAuthenticateDate()); info.setUserId(user.getId()); info.setKeyId(key.getKeyId()); Date expireTime = new Date(authentication.getAuthenticateDate().getTime() + duration); info.setExpireTime(expireTime); return info; } public void setEncryCredentialManager(KnightEncryCredentialManager encryCredentialManager) { this.encryCredentialManager = encryCredentialManager; } public void setKeyService(KnightKeyService keyService) { this.keyService = keyService; } public void setAppService(KnightAppService appService) { this.appService = appService; } public void setUserLoggedStatusStore(KnightUserLoggedStatusStore userLoggedStatusStore) { this.userLoggedStatusStore = userLoggedStatusStore; } }