/* http-auth - Authentication Extensions to jdk.httpserver Copyright (C) 2021 Ulrich Hilger This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package de.uhilger.httpserver.auth; import de.uhilger.httpserver.auth.session.SweepThread; import com.sun.net.httpserver.Authenticator; import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.HttpExchange; import de.uhilger.httpserver.auth.session.LoginSession; import de.uhilger.httpserver.auth.session.SessionManager; import de.uhilger.httpserver.auth.session.Sessions; import de.uhilger.httpserver.base.handler.HttpResponder; import io.jsonwebtoken.Jwts; import java.io.File; import java.io.IOException; import java.util.Date; import java.util.logging.Level; import java.util.logging.Logger; /** * * @author Ulrich Hilger * @version 1, 30.05.2021 */ public class FormAuthenticator extends TokenAuthenticator { /* Der Logger fuer diesen FormAuthenticator */ private static final Logger logger = Logger.getLogger(FormAuthenticator.class.getName()); /** Zwei Minuten fuer das Login */ public static final long LOGIN_EXPIRATION = 120; /** Die Datei mit dem Login Formular */ private final File loginForm; /** die zur Zeit im Gange befindlichen Logins */ private SessionManager logins; //private String ctx; public FormAuthenticator(File loginForm) { super(); //this.ctx = ctx; logins = new Sessions(); this.loginForm = loginForm; } protected Authenticator.Result login(HttpExchange exchange) { try { serveLoginForm(exchange); return new Authenticator.Retry(SC_UNAUTHORIZED); } catch (IOException ex) { logger.log(Level.SEVERE, null, ex); return new Authenticator.Failure(SC_UNAUTHORIZED); } } private void serveLoginForm(HttpExchange e) throws IOException { Date now = new Date(); Date exp = Date.from(new Date().toInstant().plusSeconds(LOGIN_EXPIRATION)); String jws = Jwts .builder() .setSubject("login-" + now.toString()) .setIssuedAt(now) .setExpiration(exp) .signWith(key) .compact(); String uriPath = e.getRequestURI().getPath(); LoginSession s = new LoginSession(); s.setId(jws); s.setUri(uriPath); s.setExp(exp); logins.add(s); Headers headers = e.getResponseHeaders(); headers.add(SET_COOKIE_HEADER, cookieBilden(JWT_INDICATOR, jws, exp)); HttpResponder fs = new HttpResponder(); fs.serveFile(e, loginForm); } protected void housekeeping() { Date sweepTime = Date.from(lastSweep.toInstant().plusSeconds(TOKEN_EXPIRATION)); Date now = new Date(); if(now.after(sweepTime)) { SweepThread sweeper = new SweepThread(logins); sweeper.start(); } super.housekeeping(); } public String getReferer(String jws) { Object o = logins.get(jws); if(o instanceof LoginSession) { LoginSession s = (LoginSession) o; logins.remove(s.getId()); return s.getUri(); } else { return null; } } }