Bearer Token Authentifizierung fuer neon
ulrich
2024-02-20 177043dea9f4efe18cea2ee7864ddb7b25c4646a
commit | author | age
177043 1 /*
U 2   neon-auth - Authentication Extensions to Neon
3   Copyright (C) 2024  Ulrich Hilger
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.neon.auth;
19
20 import java.io.BufferedReader;
21 import java.io.File;
22 import java.io.FileReader;
23 import java.io.IOException;
24 import java.security.NoSuchAlgorithmException;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29
30 /**
31  * Eine einfache Implementierung der Schnittstelle Directory, die 
32  * Benutzerinformationen aus einer Datei liest. Die Datei ist dabei 
33  * wie folgt aufgebaut.
34  * 
35  * test=test,testRolle
36  * ulrich=ulrich,testRolle,andereRolle
37  * 
38  * Der erste Eintrag nach dem Gleichheitszeichen ist das Passwort, die restlichen 
39  * Eintraege sind Rollen.
40  * 
41  * Unschoen und daher nur fuer nicht kritische Anwendungen oder fuer Tests 
42  * geeignet: Die Kennworte sind nach dem Lesen der Benutzerddaten 
43  * dann in einer Map im RAM. Sie werden dort zwar nur verglichen mit 
44  * einem Kennwort-Parameter, der ueber isValid hereinkommt, es ist aber dennoch 
45  * unschoen, dass die Kennworte im RAM liegen.
46  * 
47  * @author Ulrich Hilger
48  * @version 1, 03.06.2021
49  */
50 public class SimpleDirectory implements Directory {
51   
52   public static final String LIST_INDICATOR = "=";
53   public static final String ROLE_SEPARATOR = ",";
54   public static final String COMMENT_INDICATOR = "#";
55   
56   private final Map<String, User> users;
57   private final Map<String, List> userRoles;
58   
59   /**
60    * Ein neues Objekt der Klasse SimpleRealm erzeugen
61    */
62   public SimpleDirectory() {
63     users = new HashMap<>();
64     userRoles = new HashMap<>();
65   }
66
67   /**
68    * Nutzerinformationen aus einer Datei lesen
69    * @param file die Datei mit Nutzerinformationen
70    * @throws IOException 
71    */
72   public void readFromFile(File file) throws IOException {
73     BufferedReader r = new BufferedReader(new FileReader(file));
74     String line = r.readLine();
75     while(line != null) {
76       parse(line);
77       line = r.readLine();
78     }
79     r.close();
80   }
81   
82   /**
83    * Eine Zeile aus der Datei mit Nutzerinformationen verarbeiten
84    * @param line die Zeile, die verarbeitet werden soll
85    */
86   private void parse(String line) {
87     if(!line.startsWith(COMMENT_INDICATOR)) {
88       String[] teile = line.split(LIST_INDICATOR);
89       String[] rollen = teile[1].split(ROLE_SEPARATOR);
90       String userId = teile[0];
91       User user = new User();
92       user.setName(userId);
93       user.setPassword(rollen[0]);
94       try {
95         Encoder encoder = new Encoder();
96         String hex = encoder.bytesToHex(encoder.encode(rollen[0]));
97         //logger.fine(hex);
98       } catch (NoSuchAlgorithmException ex) {
99         //logger.log(Level.SEVERE, null, ex);
100       }
101       ArrayList rollenListe = new ArrayList(); 
102       for(int i = 1; i < rollen.length; i++) {
103         rollenListe.add(rollen[i]);
104       }
105       users.put(userId, user);
106       userRoles.put(userId, rollenListe);
107     }
108   }
109   
110   /* ------------ Realm implementation -------------- */
111
112   /**
113    * Uberpruefen, ob die Benutzerkennung und das Kennwort gueltig sind.
114    * 
115    * @param userId  der Benutzer
116    * @param password das Kennwort des Benutzers
117    * @return true, wenn die Angaben stimmen, false wenn nicht
118    */  
119   @Override
120   public boolean isValid(String userId, String password) {
121     Object o = users.get(userId);
122     if(o instanceof User) {
123       User user = (User) o;
124       return user.getPassword().equals(password);
125     } else {
126       return false;
127     }
128   }
129
130   /**
131    * Pruefen, ob ein Benutzer eine Rolle hat
132    * 
133    * @param userId der Benutzer
134    * @param roleId die Kennung der Rolle
135    * @return  true, wenn der Benutzer die Rolle hat, false wenn nicht
136    */
137   @Override
138   public boolean hasRole(String userId, String roleId) {
139     Object o = userRoles.get(userId);
140     if(o instanceof List) {
141       List roles = (List) o;
142       return roles.contains(roleId);
143     } else {
144       return false;
145     }
146   }    
147 }