Authentifizierung fuer Modul jdk.httpserver
ulrich
2021-06-03 c7d492742233c73d4594e5ff3b3b448809d93209
commit | author | age
9ee357 1 /*
c7d492 2   http-auth - Authentication Extensions to jdk.httpserver
9ee357 3   Copyright (C) 2021  Ulrich Hilger
U 4
5   This program is free software: you can redistribute it and/or modify
6   it under the terms of the GNU Affero General Public License as
7   published by the Free Software Foundation, either version 3 of the
8   License, or (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU Affero General Public License for more details.
14
15   You should have received a copy of the GNU Affero General Public License
16   along with this program.  If not, see <https://www.gnu.org/licenses/>.
17  */
18 package de.uhilger.httpserver.auth;
19
20 import de.uhilger.httpserver.auth.session.SweepThread;
21 import com.sun.net.httpserver.Authenticator;
22 import com.sun.net.httpserver.Headers;
23 import com.sun.net.httpserver.HttpExchange;
24 import de.uhilger.httpserver.auth.session.LoginSession;
25 import de.uhilger.httpserver.auth.session.SessionManager;
26 import de.uhilger.httpserver.auth.session.Sessions;
27 import de.uhilger.httpserver.base.handler.HttpResponder;
28 import io.jsonwebtoken.Jwts;
29 import java.io.File;
30 import java.io.IOException;
31 import java.util.Date;
32 import java.util.logging.Level;
33 import java.util.logging.Logger;
34
35 /**
36  *
37  * @author Ulrich Hilger
38  * @version 1, 30.05.2021
39  */
40 public class FormAuthenticator extends TokenAuthenticator {
41   
42   /* Der Logger fuer diesen FormAuthenticator */
43   private static final Logger logger = Logger.getLogger(FormAuthenticator.class.getName());
44   
45   /** Zwei Minuten fuer das Login */
46   public static final long LOGIN_EXPIRATION = 120;
47   
48   /** Die Datei mit dem Login Formular */
49   private final File loginForm;
50   
51   /** die zur Zeit im Gange befindlichen Logins */
52   private SessionManager logins;
53   
54   //private String ctx;
55   
56   public FormAuthenticator(File loginForm) {
57     super();
58     //this.ctx = ctx;
59     logins = new Sessions();
60     this.loginForm = loginForm;
61   }
62   
63   protected Authenticator.Result login(HttpExchange exchange) {
64     try {
65       serveLoginForm(exchange);
66       return new Authenticator.Retry(SC_UNAUTHORIZED);
67     } catch (IOException ex) {
68       logger.log(Level.SEVERE, null, ex);
69       return new Authenticator.Failure(SC_UNAUTHORIZED);
70     }
71   }
72   
73   private void serveLoginForm(HttpExchange e) throws IOException {
74     Date now = new Date();
75     Date exp = Date.from(new Date().toInstant().plusSeconds(LOGIN_EXPIRATION));       
76     String jws = Jwts
77             .builder()
78             .setSubject("login-" + now.toString())
79             .setIssuedAt(now)
80             .setExpiration(exp)
81             .signWith(key)
82             .compact();
83     String uriPath = e.getRequestURI().getPath();      
84     LoginSession s = new LoginSession();
85     s.setId(jws);
86     s.setUri(uriPath);
87     s.setExp(exp);
88     logins.add(s);
89     Headers headers = e.getResponseHeaders();
90     headers.add(SET_COOKIE_HEADER, cookieBilden(JWT_INDICATOR, jws, exp));
91     HttpResponder fs = new HttpResponder();
92     fs.serveFile(e, loginForm);
93   }
94   
95   protected void housekeeping() {
96     Date sweepTime = Date.from(lastSweep.toInstant().plusSeconds(TOKEN_EXPIRATION));
97     Date now = new Date();
98     if(now.after(sweepTime)) {
99       SweepThread sweeper = new SweepThread(logins);
100       sweeper.start();
101     }
102     super.housekeeping();
103   }
104   
105   public String getReferer(String jws) {
106     Object o = logins.get(jws);
107     if(o instanceof LoginSession) {
108       LoginSession s = (LoginSession) o;
109       logins.remove(s.getId());
110       return s.getUri();
111     } else {
112       return null;
113     }
114   }
115   
116   
117 }