Pour utiliser MongoDB comme source de données à l'authentification Tomcat, il faut :
- Configurer le server.xml
- Configurer le web.xml
- Créer une librairie à mettre dans $CATALINA_HOME/lib (Y ajouter également le driver Mongo)
- Modifier ses services pour qu'ils prennent en compte les rôles associés
Configurer server.xml :
<Realm className="com.netapsys.MongoRealm.MongoRealm"
connectionString="127.0.0.1" port="27017" userDbName="NomBaseDeDonnéesMongo"userClName="NomCollectionUserMongo">
</Realm>
=> On pourrait également rendre encore plus ré-utilisable ce fonctionnement en précisant le nom du champ login/password à utiliser dans la collection
Configurer web.xml :
<security-constraint>
<web-resource-collection>
<web-resource-name>my webapp</web-resource-name>
<url-pattern>/private/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>webapp-user</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>My secured Webapp</realm-name>
</login-config>
Librairie :
Il faut étendre org.apache.catalina.realm.RealmBase :
public class MongoRealm extends RealmBase
{
// Adresse de la base
private static String connectionString;
// Port de la base
private static int port;
// Nom de la base
private static String userDbName;
// Collection qui contient les login/mdp
private static String userClName;
private static Mongo mongo;
private static DB database;
// Users
private static DBCollection userCollection;
public static DBCollection getUserCollection()
{
if(userCollection==null)
{
try
{
mongo = new MongoClient(connectionString, port);
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
database = mongo.getDB(userDbName);
userCollection = database.getCollection(userClName);
}
return userCollection;
}
public static void setUserCollection(DBCollection userCollection) {
MongoRealm.userCollection = userCollection;
}
public String getConnectionString() {
return connectionString;
}
public void setConnectionString(String connectionString) {
MongoRealm.connectionString = connectionString;
}
public int getPort() {
return port;
}
public void setPort(int port) {
MongoRealm.port = port;
}
public String getUserDbName() {
return userDbName;
}
public void setUserDbName(String userDbName) {
MongoRealm.userDbName = userDbName;
}
public String getUserClName() {
return userClName;
}
public void setUserClName(String userClName) {
MongoRealm.userClName = userClName;
}
@Override
protected String getName() {
return this.getClass().getSimpleName();
}
@Override
protected String getPassword(final String username)
{
String password = "";
DBObject myDoc = getUserCollection().findOne(new BasicDBObject("email", username));
if(myDoc!=null)
password=(String) myDoc.get("passwordhash");
return password;
}
@Override
@SuppressWarnings("unchecked")
protected Principal getPrincipal(final String username)
{
String password = "";
List<String> roles = new ArrayList<String>();
DBObject myDoc = getUserCollection().findOne(new BasicDBObject("email", username));
if(myDoc!=null)
{
password=(String) myDoc.get("passwordhash");
roles=(List<String>) myDoc.get("roles");
}
return new GenericPrincipal(username, password, roles);
}
Services :
Pour des services REST, il faut avoir 2 services de base :
Le premier accessible sans authentification pour permettre à l'utilisateur de créer son compte :
@Path("public")
public class PublicService
{
// CREATE USER
@POST
@Path("/user")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Success createUser(User user)
{
DAO.insertUser(user);
Success success = new Success();
success.setCode(0);
success.setDetails("Compte : " + user.getEmail());
success.setTitle("Compte créé");
return success;
}
}
Le second avec authentification pour se connecter à la partie privée :
@Path("private/user")
@DeclareRoles({"webapp-user"})
public class UserService
{
// TEST
@GET
@Path("/test")
@RolesAllowed({"webapp-user"})
public String test(@Context HttpServletRequest req)
{
return "Hello World" + req.getUserPrincipal();
}
}
Pour créer un compte, avec votre application client REST favorite :
Créer le compte :
http://localhost:8080/PROJET/rest/public/user
Dans le body de type application/json :
{"email":"email@netapsys.fr","passwordhash":"888da5db853449fff82b07cbdbf7c755ece0783aa670bb36cc5c4cc9a68fb864"}
Pour se connecter à la partie privée :
http://localhost:8080/PROJET/rest/private/user/test
Saisir le login/hash
Elements à revoir/compléter/modifier :
- Saler le Hash
- Rendre encore plus réutilisable la librairie
Bonjour,
merci pour cet article très utile !
le paragraphe ci dessous est en double au début de l’article
Pour utiliser MongoDB comme source de données à l’authentification Tomcat, il faut :
Configurer le server.xml
Configurer le web.xml
Créer une librairie à mettre dans $CATALINA_HOME/lib (Y ajouter également le driver Mongo)
Modifier ses services pour qu’ils prennent en compte les rôles associés
Cordialement
attention également au doubles quote (« ) converties en guillemets («) dans le bloc de code
il devrai être