Authentifizierung fuer Modul jdk.httpserver
ulrich
2021-06-04 83896588e20d7e532d0e2fdc17512772c29533a8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
  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 <https://www.gnu.org/licenses/>.
 */
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;
    }
  }
  
  
}