All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.milton.http.http11.auth.SimpleMemoryNonceProvider Maven / Gradle / Ivy

Go to download

Milton Community Edition: Supports DAV level 1 and is available on Apache2 license

There is a newer version: 4.0.3.2215
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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 io.milton.http.http11.auth;

import io.milton.http.Request;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * A very simple nonce provide that users a map to store issued nonces.
 * 

* If the map is constructed internally it will be a ConcurrentHashMap, which * will restrict the application to a single machine, and nonces will not be * preserved across restarts. *

* To improve reliability and scalability provide an alternative map * implementation. For example, it could be a cluster aware map which * synchronizes across a cluster. Or it could be a map which persists entries to * a database or file. * * @author brad */ public class SimpleMemoryNonceProvider implements NonceProvider { private static final Logger log = LoggerFactory.getLogger(SimpleMemoryNonceProvider.class); private final int nonceValiditySeconds; private final Map nonces; private final ExpiredNonceRemover remover; private boolean enableNonceCountChecking; public SimpleMemoryNonceProvider(int nonceValiditySeconds, ExpiredNonceRemover remover, Map nonces) { if (log.isTraceEnabled()) { log.trace("Created SimpleMemoryNonceProvider(b): nonceValiditySeconds: {}", nonceValiditySeconds); } this.nonces = nonces; this.nonceValiditySeconds = nonceValiditySeconds; this.remover = remover; } public SimpleMemoryNonceProvider(int nonceValiditySeconds) { if (log.isTraceEnabled()) { log.trace("Created SimpleMemoryNonceProvider(b): nonceValiditySeconds: {}", nonceValiditySeconds); } this.nonces = new ConcurrentHashMap<>(); this.nonceValiditySeconds = nonceValiditySeconds; this.remover = new ExpiredNonceRemover(nonces, nonceValiditySeconds); } public Nonce createNonceObject(Request request) { UUID id = UUID.randomUUID(); Date now = new Date(); Nonce n = new Nonce(id, now); nonces.put(n.getValue(), n); return n; } @Override public String createNonce(Request request) { String n = createNonceObject(request).getValue().toString(); if (log.isTraceEnabled()) { log.trace("Created nonce: {} in map of size: {}", n, nonces.size()); } return n; } @Override public NonceValidity getNonceValidity(String nonce, Long nc) { if (log.isTraceEnabled()) { log.trace("getNonceValidity: {}", nonce); } UUID value = null; try { value = UUID.fromString(nonce); } catch (Exception e) { log.warn("couldnt parse nonce"); return NonceValidity.INVALID; } Nonce n = nonces.get(value); if (n == null) { log.debug("not found in map of size: {}", nonces.size()); return NonceValidity.INVALID; } else { if (isExpired(n.getIssued())) { log.debug("nonce has expired"); return NonceValidity.EXPIRED; } else { if (nc == null) { log.trace("nonce ok"); return NonceValidity.OK; } else { if (enableNonceCountChecking && nc <= n.getNonceCount()) { log.warn("nonce-count was not greater then previous, possible replay attack. new: {} old: {}", nc, n.getNonceCount()); return NonceValidity.INVALID; } else { log.trace("nonce and nonce-count ok"); Nonce newNonce = n.increaseNonceCount(nc); nonces.put(newNonce.getValue(), newNonce); return NonceValidity.OK; } } } } } private boolean isExpired(Date issued) { long dif = (System.currentTimeMillis() - issued.getTime()) / 1000; return dif > nonceValiditySeconds; } /** * IE seems to send nc (nonce count) parameters out of order. To correctly * implement checking we need to record which nonces have been sent, and not * assume they will be sent in a monotonically increasing sequence. *

* The quick fix here is to disable checking of the nc param, since other * common servers seem to do so to. *

* Note that this will allow replay attacks. * * @return */ public boolean isEnableNonceCountChecking() { return enableNonceCountChecking; } public void setEnableNonceCountChecking(boolean enableNonceCountChecking) { this.enableNonceCountChecking = enableNonceCountChecking; } public Map getNonces() { return nonces; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy