📄 authenticate.java
字号:
{ if (subjectName == null || subjectName.getLoginName().length() < 2) { log.warning("Given loginName is null"); throw new XmlBlasterException(this.glob, ErrorCode.USER_ILLEGALARGUMENT, ME + ".InvalidClientName", "Your given loginName is null or shorter 2 chars, loginName rejected"); } SubjectInfo subjectInfo = null; boolean isNew = false; synchronized(this.loginNameSubjectInfoMap) { subjectInfo = (SubjectInfo)this.loginNameSubjectInfoMap.get(subjectName.getLoginName()); if (subjectInfo == null) { SessionName name = new SessionName(glob, glob.getNodeId(), subjectName.getLoginName()); // strip nodeId, strip pubSessionId //log.error(ME, "DEBUG ONLY: Stripped name=" + name.toString()); subjectInfo = new SubjectInfo(getGlobal(), this, name); this.loginNameSubjectInfoMap.put(subjectName.getLoginName(), subjectInfo); isNew = true; } } if (isNew) { if (returnLocked) subjectInfo.getLock().lock(); try { //log.error(ME, "DEBUG ONLY: REMOVE AGAIN"); //if (subjectName.getLoginName().equals("subscriber")) { // log.error(ME, "DEBUG ONLY: sleepig 20 sec for toAlive(): " + subjectName.toString()); // try { Thread.currentThread().sleep(20*1000L); } catch( InterruptedException i) {} //} subjectInfo.toAlive(subjectCtx, (prop != null) ? prop : new CbQueueProperty(getGlobal(), Constants.RELATING_SUBJECT, null)); } catch(Throwable e) { synchronized(this.loginNameSubjectInfoMap) { this.loginNameSubjectInfoMap.remove(subjectInfo.getLoginName()); } if (returnLocked) subjectInfo.getLock().release(); throw XmlBlasterException.convert(getGlobal(), ErrorCode.INTERNAL_UNKNOWN, ME, e.toString(), e); } } else { subjectInfo.waitUntilAlive(returnLocked); if (subjectCtx != null && subjectInfo.getSecurityCtx() == null) subjectInfo.setSecurityCtx(subjectCtx); // If SubjectInfo was created by a PtP message the securityCtx is missing, add it here } return subjectInfo; } /** * Remove a SubjectInfo instance. */ void removeLoginName(SubjectInfo subjectInfo) { Object entry = null; synchronized(this.loginNameSubjectInfoMap) { entry = this.loginNameSubjectInfoMap.remove(subjectInfo.getLoginName()); } if (entry == null) { return; } try { glob.getRequestBroker().updateInternalUserList(); } catch (XmlBlasterException e) { log.severe("Publishing internal user list failed: " + e.getMessage()); } } public int getNumSubjects() { return this.loginNameSubjectInfoMap.size(); } /** * Access a subjectInfo with the unique login name * @return the SubjectInfo object<br /> * null if not found */ public final SubjectInfo getSubjectInfoByName(SessionName subjectName) { synchronized(this.loginNameSubjectInfoMap) { return (SubjectInfo)this.loginNameSubjectInfoMap.get(subjectName.getLoginName()); } } public final SessionInfo getSessionInfoByName(SessionName sessionName) { SubjectInfo subjectInfo = getSubjectInfoByName(sessionName); if (subjectInfo == null) return null; return subjectInfo.getSession(sessionName); } /** * Replace the old by the new session id */ public final void changeSecretSessionId(String oldSessionId, String newSessionId) throws XmlBlasterException { synchronized(this.sessionInfoMap) { SessionInfo sessionInfo = (SessionInfo)this.sessionInfoMap.get(oldSessionId); if (sessionInfo == null) { throw new XmlBlasterException(glob, ErrorCode.INTERNAL_UNKNOWN, ME+".changeSecretSessionId()", "Couldn't lookup secretSessionId."); } if (this.sessionInfoMap.get(newSessionId) != null) { throw new XmlBlasterException(glob, ErrorCode.INTERNAL_UNKNOWN, ME+".changeSecretSessionId()", "The new secretSessionId is already in use."); } this.sessionInfoMap.put(newSessionId, sessionInfo); this.sessionInfoMap.remove(oldSessionId); sessionInfo.getSecuritySession().changeSecretSessionId(newSessionId); sessionInfo.getConnectQos().getSessionQos().setSecretSessionId(newSessionId); } } /** * Access a sessionInfo with the unique secretSessionId. * <p /> * @return the SessionInfo object or null if not known */ private final SessionInfo getSessionInfo(String secretSessionId) { synchronized(this.sessionInfoMap) { return (SessionInfo)this.sessionInfoMap.get(secretSessionId); } } /** * Returns a current snapshot of all sessions, never returns null. */ public final SessionInfo[] getSessionInfoArr() { synchronized(this.sessionInfoMap) { return (SessionInfo[])this.sessionInfoMap.values().toArray((new SessionInfo[this.sessionInfoMap.size()])); } } /** * Find a session by its login name and pubSessionId or return null if not found */ public final SessionInfo getSessionInfo(SessionName sessionName) { SubjectInfo subjectInfo = getSubjectInfoByName(sessionName); if (subjectInfo == null) { return null; } return subjectInfo.getSessionInfo(sessionName); } public boolean sessionExists(String secretSessionId) { synchronized(this.sessionInfoMap) { return this.sessionInfoMap.containsKey(secretSessionId); } } /** * Logout of a client. * <p> * @exception XmlBlasterException If client is unknown */ public final void logout(String secretSessionId) throws XmlBlasterException { log.severe("logout not implemented"); throw new XmlBlasterException(this.glob, ErrorCode.INTERNAL_NOTIMPLEMENTED, ME + ".logout not implemented"); } /** * @param sessionInfo * @param clearQueue Shall the message queue of the client be destroyed as well on last session logout? * @param forceShutdownEvenIfEntriesExist on last session * @param isDisconnecting true if this method is invoked while explicitly disconnecting a session, false * otherwise. It is used to determine if the session queue (callback queue) has to be cleared or not. * */ private void resetSessionInfo(SessionInfo sessionInfo, boolean clearQueue, boolean forceShutdownEvenIfEntriesExist, boolean isDisconnecting) throws XmlBlasterException { firePreRemovedClientEvent(sessionInfo); String secretSessionId = sessionInfo.getSecretSessionId(); Object obj; synchronized(this.sessionInfoMap) { obj = this.sessionInfoMap.remove(secretSessionId); } if (obj == null) { log.warning("Sorry, '" + sessionInfo.getId() + "' is not known, no logout."); throw new XmlBlasterException(glob, ErrorCode.USER_SECURITY_AUTHENTICATION_ACCESSDENIED, ME, "Client '" + sessionInfo.getId() + "' is not known, disconnect is not possible."); } log.info("Disconnecting client " + sessionInfo.getSessionName() + ", instanceId=" + sessionInfo.getInstanceId() + ", secretSessionId=" + secretSessionId); I_Session oldSessionCtx = sessionInfo.getSecuritySession(); oldSessionCtx.getManager().releaseSession(secretSessionId, null); fireClientEvent(sessionInfo, false); // informs all I_ClientListener SubjectInfo subjectInfo = sessionInfo.getSubjectInfo(); subjectInfo.notifyAboutLogout(sessionInfo.getId(), clearQueue, forceShutdownEvenIfEntriesExist); //if (subjectInfo.isShutdown()) { // subjectInfo = null; // Give GC a hint //} // with positive sessionId avoid to clear session queue: Such a DisconnectQos flag is currently not existing if (isDisconnecting) sessionInfo.getSessionQueue().clear(); sessionInfo.shutdown(); sessionInfo = null; log.info("loginNameSubjectInfoMap has " + getNumSubjects() + " entries and sessionInfoMap has " + this.sessionInfoMap.size() + " entries"); } /** * Generate a unique (and secret) resource ID <br> * * @param loginName * @return unique ID * @exception XmlBlasterException random generator */ private String createSessionId(String loginName) throws XmlBlasterException { try { String ip = glob.getLocalIP(); // This is a real random, but probably not necessary here: // Random random = new java.security.SecureRandom(); java.util.Random ran = new java.util.Random(); // is more or less currentTimeMillis // Note: We should include the process ID from this JVM on this host to be granted unique // secretSessionId:<IP-Address>-<LoginName>-<TimestampMilliSec>-<RandomNumber>-<LocalCounter> StringBuffer buf = new StringBuffer(512); buf.append(Constants.SESSIONID_PREFIX).append(ip).append("-").append(loginName).append("-"); buf.append(System.currentTimeMillis()).append("-").append(ran.nextInt()).append("-").append((counter++)); String secretSessionId = buf.toString(); if (log.isLoggable(Level.FINE)) log.fine("Created secretSessionId='" + secretSessionId + "'"); return secretSessionId; } catch (Exception e) { String text = "Can't generate a unique secretSessionId: " + e.getMessage(); log.severe(text); throw new XmlBlasterException(glob, ErrorCode.USER_SECURITY_AUTHENTICATION_ACCESSDENIED, ME, text); } } /** * Returns a current snapshot of all ClientListeners */ private final I_ClientListener[] getClientListenerArr() { synchronized(this.clientListenerSet) { return (I_ClientListener[])this.clientListenerSet.toArray((new I_ClientListener[this.clientListenerSet.size()])); } } private void firePreRemovedClientEvent(SessionInfo sessionInfo) throws XmlBlasterException { I_ClientListener[] clientListenerArr = getClientListenerArr(); if (clientListenerArr.length == 0) return; ClientEvent event = new ClientEvent(sessionInfo); for (int ii=0; ii<clientListenerArr.length; ii++) clientListenerArr[ii].sessionPreRemoved(event); event = null; } /** * Used to fire an event if a client does a login / logout */ private void fireClientEvent(SessionInfo sessionInfo, boolean login) throws XmlBlasterException { I_ClientListener[] clientListenerArr = getClientListenerArr(); if (clientListenerArr.length == 0) return; ClientEvent event = new ClientEvent(sessionInfo); for (int ii=0; ii<clientListenerArr.length; ii++) { if (login) clientListenerArr[ii].sessionAdded(event); else clientListenerArr[ii].sessionRemoved(event); } event = null; } /** * Use this method to check a clients authentication. * <p> * This method is called from an invoked xmlBlaster-server * method (like subscribe()), using the delivered secretSessionId * * @return SessionInfo - if the client is OK otherwise an exception is thrown (returns never null)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -