OAuth-Unterstuetzung fuer jdk.httpserver
ulrich
2021-07-05 8c1928946cb3b4f2d9ead70c7362ce1dbe045fa4
src/de/uhilger/httpserver/oauth/BearerAuthenticator.java
@@ -22,7 +22,7 @@
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpPrincipal;
import de.uhilger.httpserver.auth.realm.Realm;
import de.uhilger.httpserver.base.handler.HttpResponder;
import de.uhilger.httpserver.base.HttpResponder;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
@@ -132,8 +132,9 @@
   * @param password  das Kennwort des Benutzers
   * @return Token oder null, wenn die Anmeldung misslang
   */
  public LoginResponse login(String userId, String password) {
  public LoginResponse login(HttpExchange e, String userId, String password) {
    if (realm.isValid(userId, password)) {
      logger.info(userId + " logged in from IP." + e.getRemoteAddress());
      LoginResponse r = new LoginResponse();
      String token = createToken(userId, expireSeconds);
      r.setToken(token);
@@ -141,6 +142,7 @@
      r.setExpiresIn(expireSeconds);
      return r;
    } else {
      logger.info("Invalid log in attempt for " + userId + " from IP " + e.getRemoteAddress());
      return null;
    }
  }
@@ -227,6 +229,22 @@
      String[] parts = auth.split(BEARER);
      if(parts != null && parts.length > 1) {
        token = parts[1].trim();
      }
    } else {
      // unschoen, aber fuer Image-Links in HTML-Inhalten
      // mit Query versuchen
      // z.B.
      //   GET /resource?access_token=mF_9.B5f-4.1JqM HTTP/1.1
      //   Host: server.example.com
      String query = exchange.getRequestURI().getQuery();
      if(query != null && query.toLowerCase().contains("access_token")) {
        String[] parts = query.split("&");
        for(String part : parts) {
          String[] keyVal = part.split("=");
          if(keyVal[0].equalsIgnoreCase("access_token")) {
            token = keyVal[1].trim();
          }
        }
      }
    }
    return token;
@@ -329,26 +347,69 @@
    return new Authenticator.Retry(SC_UNAUTHORIZED);
  }
  
  /**
   * Den Realm dieses Authenticators setzen
   * @param realm der Realm
   */
  public void setRealm(Realm realm) {
    this.realm = realm;
  }
  
  /**
   * Pruefen, ob ein Nutzer eine Rolle hat
   * @param userId die Kennung des Nutzers
   * @param roleId  die Rollen-ID des Nutzers
   * @return true, wenn der Nutzer die Rolle hat, false wenn nicht
   */
  public boolean hasRole(String userId, String roleId) {
    return realm.hasRole(userId, roleId);
  }
  /**
   * Den Eintrag fuer das 'realm'-Attribut
   * zur Nutzung im WWW-Authenticate Header setzen
   *
   * @param wwwAuthRealm der Text fuer das realm-Attribut im
   * WWW-Autehnticate-Header
   */
  public void setWWWAuthRealm(String wwwAuthRealm) {
    this.wwwAuthRealm = wwwAuthRealm;
  }
  
  /**
   * Den Namen des Realms setzen, wie er fuer authentifizierte Benutzer
   * vom Principal ausgegeben werden soll
   *
   * @param principalAuthRealm der Name des Realms fuer authentifizierte
   * Benutzer
   */
  public void setPrincipalAuthRealm(String principalAuthRealm) {
    this.principalAuthRealm = principalAuthRealm;
  }
  
  /**
   * Die Dauer der Gueltigkeit einer Authentifizierung in Sekunden
   * @param seconds die Sekunden, nach denen die Authentifizierung
   * ungueltig wird
   */
  public void setExpireSeconds(long seconds) {
    this.expireSeconds = seconds;
  }
  
  /**
   * Die Dauer bis eine Authentifizierung eine Erneuerung benoetigt in Sekunden
   * @param seconds die Sekunden, nach denen die Authentifizierung
   * eine Erneuerung benoetigt
   */
  public void setRefreshSeconds(long seconds) {
    this.refreshSeconds = seconds;
  }
  
  /**
   * Die Dauer der Gueltigkeit eines Refresh-Token in Sekunden
   *
   * @param seconds die Anzhal Sekunden, die ein Refresh-Token gueltig ist
   */
  public void setRefreshExpireSeconds(long seconds) {
    this.refreshExpire = seconds;
  }