How to save name-value pairs in Tomcat environment?

We have a servlet that needs certain variables, such as passwords, encryption salts, etc., so that they are not permanently stored in the file system. This is what we are currently doing (summary):

During initialization

  • The perl script sets ReadMode to 2 to mask the stdout echo, asks the user for the variables, filters the known file to insert them, and calls tomcat / bin / startup.sh

  • The servlet init () method reads the variables from the file and deletes it (the file).

Problem: When the WAR is recompiled, tomcat tries to deploy it (autodeploy = true), which we want. But the data file no longer exists, so a FileNotFoundException is thrown (correctly).

Question: Is there a property or some kind of HashMap / Table for servlets where several variables can be stored during manual start? The idea is that init () can check them if the data file does not exist during the redistribution. Thanks, MS.

+3
source share
5 answers

In Tomcat, nothing is done to do what you want. If you move the settings to the tomcat JTDI tree, you will need to put the user / name password combination in the server.xml or context.xml file. Here are some possible solutions to your problem.

Option 1: Use a Tomcat Listener

tomcat server.xml, , java-, tomcat. Tomcat-, , / Comobo , . tomcat tomcat, tomcat. tomcat CATALINA_HOME\lib.

/ , , , tomcat. , tomcat, , , , , .

JNDI tomcat , context.xml, ResourceLink, jndi . , , JNDI .

Spring , tomcat, Spring, tomcat. , / , .

2:

, , . . , .

3. JMX

JMX MBean, JVM MBeanServer, , username/password. MBean tomcat, perl script MBean /.

, .

+1

startup.sh, .. 'bin/startup.sh -DencryptionSalt= foobar'? System.getProperty( "encryptionSalt" ) JVM.

+4

JNDI. JNDI . init, JNDI .

, JNDI-/ , , - (, ConcurrentHashMap) .

MS:

==========
restart.pl:
==========
ReadMode 2; print "\nEnter spice: "; chomp ($spice = <STDIN>); print "\n";
ReadMode 0;
open (FP, ">$spicefile") or die "$0: Cannot write file $spicefile: $!\n";
print FP "$spice\n"; close (FP);
system "bin/shutdown.sh";       sleep 8;
system "bin/startup.sh";        sleep 8;        system "wget $tomcaturl";
system '/bin/rm -rf *spicefile*';               # delete wget output file
foreach $sCount (1..10) {                       # give it 10 more secs
    sleep 1;
    if (-f $spicefile) {
        print "$0: Waiting on servlet to delete spicefile [$sCount]\n"
    } else {
        print "$0: Successful servlet initialization, no spicefile\n";
        exit 0
}}
print "\n$0: deleting file $spicefile ...\n";   # Error condition
system "unlink $spicefile";
exit 1;

===========
context.xml
===========
    <Resource name="MyServlet/upsBean" auth="Container" type="packageName.UPSBean"
                factory="org.apache.naming.factory.BeanFactory" readOnly="false"/>

===================
app/WEB-INF/web.xml
===================
  <listener>
        <listener-class>packageName.DBInterface</listener-class>
  </listener>
  <resource-env-ref>
    <description>Use spice as transferable during redeployment</description>
    <resource-env-ref-name>MyServlet/upsBean</resource-env-ref-name>
    <resource-env-ref-type>packageName.UPSBean</resource-env-ref-type>
  </resource-env-ref>

==============
MyServlet.java:
==============
init() {
        if (new File (spiceFile).exists())      # Same name in restart.pl
                dbi = new DBInterface (spiceFile);
        else
                dbi = new DBInterface ();       # Redeployment
        otherInitializations (dbi.getSpice());
}

================
DBInterface.java:
================
public DBInterface () {
        // Comment out following block if contextInitialized works
        FileInputStream fin = new FileInputStream (safeDepositBox);
        ObjectInputStream ois = new ObjectInputStream (fin);
        UPSBean upsBean = (UPSBean) ois.readObject();
        ois.close();
        spice = upsBean.getSpice();
        dbiIndex = 2;
        // do stuff with spice
}

public DBInterface (String spiceFileName) {
        File file = new File (spiceFileName);
        BufferedReader br = new BufferedReader (new FileReader (file));
        spice = br.readLine();
        br.close();
        file.delete();
        dbiIndex = 1;

        // Delete following block if contextInitialized works
        UPSBean upsBean = new UPSBean();
        upsBean.setSpice (spice);
        FileOutputStream fout = new FileOutputStream (safeDepositBox);
        ObjectOutputStream oos = new ObjectOutputStream (fout);
        oos.writeObject (upsBean);
        oos.flush();
        oos.close();
        // do stuff with spice and if it works, ...
        // contextInitialized (null);
}

// Above is working currently, would like the following to work

public void contextDestroyed(ServletContextEvent sce) {
        System.setProperty ("spice", spice);
        System.out.println ("[DBInterface" + dbiIndex +
                                        "] Spice saved at " +
                        DateFormat.getDateTimeInstance (DateFormat.SHORT,
                                        DateFormat.LONG).format (new Date()));
}

public void contextInitialized(ServletContextEvent sce) {
        if (sce != null) {
                spice = System.getProperty ("spice");
                System.out.println ("[DBInterface" + dbiIndex +
                                        "] Spice retrieved at " +
                        DateFormat.getDateTimeInstance (DateFormat.SHORT,
                                        DateFormat.LONG).format (new Date()));
        }
        // do stuff with spice
}

============
UPSBean.java:
============
public class UPSBean implements Serializable {
        private String  spice = "parsley, sage, rosemary and thyme";
        public UPSBean() { }
        public String getSpice() {      return spice;   }
        public void setSpice (String s) {       spice = s;      }
}

, get/setProperty . JNDI , Spice, MyServlet/upsBean contextDestroyed() Initialized(), (, ). .xml, resource-env-ref . - ( ).

+2

, , , , ServletContextListener. , Initialized (ServletContextEvent sce) -, . .

+1

Tomcat , .

.

... , , servlet-api, , Tomcat. .

  • Tomcat Listener - Listener. , , ..
  • api ServletContextListener Webapp,
  • tomcat - , JAVA_OPTS. - ps.
  • my-app.xml( my-app - )
  • CATALINA_BASE/conf/context.xml init/env webapp, -.
  • , / .

, "" . , , System - ServletContextListener . reset - , webapp - .

, :

  • Admin pw ( )
  • webapp - ServletContextListner . -
  • Webapp - System.properties
  • When restarting webapp - ServletContextListner sees that the file is missing and uses System.properties. Then removes system.properties

With the above, you can relocate without writing passwords to disk and, hopefully, minimize any attack vectors while temporarily saving them as system.properties.

Good luck.

+1
source

Source: https://habr.com/ru/post/1791551/


All Articles