public SecureUserSession(UserSession userSession) { this.sessionId = userSession.getSessionId(); this.user = userSession.getUser(); this.encryptedContentKey = userSession.getEncryptedContentKey(); try { CryptoEngine cryptoEngine = CryptoFactory.getEngine(); accessTokenHash = cryptoEngine.hash(sessionId, userSession.getAccessToken()); } catch(JasDBSecurityException e) { throw new RuntimeJasDBException("Unable to hash token", e); } }
@Override public User addUser(UserSession currentSession, String userName, String allowedHost, String password) throws JasDBStorageException { authorize(currentSession, "/Users", AccessMode.WRITE); User currentUser = currentSession.getUser(); CryptoEngine cryptoEngine = CryptoFactory.getEngine(); String contentKey = cryptoEngine.decrypt(currentUser.getPasswordSalt(), currentSession.getAccessToken(), currentSession.getEncryptedContentKey()); return credentialsProvider.addUser(userName, allowedHost, contentKey, password); }
@RequestMapping(method = RequestMethod.POST, value = "/token", produces = "application/json", consumes = "application/json") public @ResponseBody ResponseEntity<String> getToken(HttpServletRequest request) { if(request.isSecure()) { try { String clientId = request.getParameter("client_id"); String clientSecret = request.getParameter("client_secret"); LOG.debug("Client: {} host: {}", clientId, request.getRemoteHost()); UserSession session = sessionManager.startSession(new BasicCredentials(clientId, request.getRemoteHost(), clientSecret)); LOG.debug("Loaded session: {}", session); String responseMessage = String.format(GRANT_VALID, session.getAccessToken(), session.getSessionId(), "jasdb", 3600); return new ResponseEntity<>(responseMessage, HttpStatus.OK); } catch(JasDBSecurityException e) { return getErrorResponse("Invalid credentials"); } catch(JasDBStorageException e) { return getErrorResponse("Unknown error"); } } else { return getErrorResponse("Insecure connection"); } }
private void validateSession() throws JasDBStorageException { if(session == null || !sessionManager.sessionValid(session.getSessionId())) { throw new JasDBSecurityException("Unable to change security principals, not logged in or session expired"); } } }
private boolean checkGrantHierarchy(String objectName, UserSession userSession, AccessMode objectMode) throws JasDBStorageException { String userName = userSession.getUser().getUsername(); LOG.debug("Checking grant hierarchy for: {} for user: {}", objectName, userName); //check root read access StringBuilder currentPath = new StringBuilder(); currentPath.append(Constants.OBJECT_SEPARATOR); AccessMode grantedMode = getGrantedMode(currentPath.toString(), userSession); LOG.debug("Root access mode: {} for user: {}", grantedMode, userName); grantedMode = grantedMode == null ? AccessMode.NONE : grantedMode; String[] pathElements = objectName.replaceFirst(Constants.OBJECT_SEPARATOR, "").split(Constants.OBJECT_SEPARATOR); for(String pathElement : pathElements) { currentPath.append(pathElement); AccessMode mode = getGrantedMode(currentPath.toString(), userSession); if(mode != null) { grantedMode = mode; if(mode == AccessMode.NONE) { break; } } currentPath.append(Constants.OBJECT_SEPARATOR); } LOG.debug("Grant level: {} for path: {}", grantedMode, currentPath.toString()); boolean granted = grantedMode != null ? grantedMode.getRank() >= objectMode.getRank() : false; return granted; }
private void checkToken(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws IOException, ServletException { try { String token = httpServletRequest.getHeader("oauth_token"); String sessionId = httpServletRequest.getHeader("sessionid"); LOG.debug("Token: {} for session: {}", token, sessionId); if(StringUtils.stringNotEmpty(token) && StringUtils.stringNotEmpty(sessionId)) { UserSession session = sessionManager.getSession(sessionId); if(session != null) { CryptoEngine cryptoEngine = CryptoFactory.getEngine(); String expectedTokenHash = cryptoEngine.hash(sessionId, token); if (expectedTokenHash.equals(session.getAccessToken())) { httpServletRequest.setAttribute("session", new UserSessionImpl(sessionId, token, session.getEncryptedContentKey(), session.getUser())); filterChain.doFilter(httpServletRequest, httpServletResponse); } else { handleErrorResponse(httpServletResponse, UNAUTHORIZED_CODE, "Invalid token"); } } else { handleErrorResponse(httpServletResponse, UNAUTHORIZED_CODE, "Invalid token"); } } else { handleErrorResponse(httpServletResponse, UNAUTHORIZED_CODE, "No token"); } } catch(JasDBStorageException e) { LOG.error("Unknown error happened when processing token", e); handleErrorResponse(httpServletResponse, 500, "Unknown error"); } }
@Override protected void authenticate(Credentials credentials) throws JasDBStorageException { if(credentials != null) { TokenConnector tokenConnector = RemoteConnectorFactory.createConnector(getNodeInformation(), TokenConnector.class); UserSession session = tokenConnector.loadSession(credentials.getUsername(), credentials.getPassword()); if(StringUtils.stringNotEmpty(session.getAccessToken()) && StringUtils.stringNotEmpty(session.getSessionId())) { context = new RemotingContext(true); context.setUserSession(session); LOG.debug("Token: {} session: {}", session.getAccessToken(), session.getSessionId()); } else { throw new JasDBSecurityException("Unable to obtain access token to service"); } } else { context = new RemotingContext(true); } }
private AccessMode getGrantedMode(String objectName, UserSession userSession) throws JasDBStorageException { StatRecord getGrantRecord = StatisticsMonitor.createRecord("auth:grant:check"); try { String username = userSession.getUser().getUsername(); if(cachedGrants.containsKey(objectName)) { return verifyGrantMode(cachedGrants.get(objectName), username); } else { GrantObject objectGrantObject = getMutableGrantObject(userSession, objectName); if(objectGrantObject != null) { cachedGrants.put(objectName, objectGrantObject); return verifyGrantMode(objectGrantObject, username); } else { return null; } } } finally { getGrantRecord.stop(); } }
private GrantObject decrypt(UserSession session, EncryptedGrants encryptedGrants) throws JasDBStorageException { CryptoEngine contentCryptoEngine = CryptoFactory.getEngine(); String contentKey = contentCryptoEngine.decrypt(session.getUser().getPasswordSalt(), session.getAccessToken(), session.getEncryptedContentKey()); CryptoEngine cryptoEngine = CryptoFactory.getEngine(encryptedGrants.getEncryptionEngine()); String decryptedData = cryptoEngine.decrypt(encryptedGrants.getSalt(), contentKey, encryptedGrants.getEncryptedData()); return GrantObjectMeta.fromEntity(SimpleEntity.fromJson(decryptedData)); }
urlConnection.setRequestProperty(REQUESTCONTEXT, getRequestContext(context)); if(context.getUserSession() != null) { urlConnection.setRequestProperty("oauth_token", context.getUserSession().getAccessToken()); urlConnection.setRequestProperty("sessionid", context.getUserSession().getSessionId());
@Override public void authorize(UserSession userSession, String object, AccessMode mode) throws JasDBStorageException { StatRecord authRecord = StatisticsMonitor.createRecord("auth:object"); try { if(userSession != null) { String userName = userSession.getUser().getUsername(); boolean granted = checkGrantHierarchy(object, userSession, mode); LOG.debug("User: {} is privileged: {} on object: {}", userName, granted, object); if(!granted) { throw new JasDBSecurityException("User: " + userName + " has insufficient privileges on object: " + object); } } else { throw new JasDBSecurityException("Unable to authorize user, no session"); } } finally { authRecord.stop(); } }
private EncryptedGrants encryptGrants(GrantObject grantObject, UserSession userSession) throws JasDBStorageException { CryptoEngine cryptoEngine = CryptoFactory.getEngine(); String contentKey = CryptoFactory.getEngine().decrypt(userSession.getUser().getPasswordSalt(), userSession.getAccessToken(), userSession.getEncryptedContentKey()); String salt = cryptoEngine.generateSalt(); String unencryptedData = SimpleEntity.toJson(GrantObjectMeta.toEntity(grantObject)); String encryptedData = cryptoEngine.encrypt(salt, contentKey, unencryptedData); return new EncryptedGrants(grantObject.getObjectName(), encryptedData, salt, cryptoEngine.getDescriptor()); }