Apache Tomcat имеет несколько механизмов аутентификации. По-умолчанию используется UserDatabaseRealm
, который использует данные из файла ../conf/tomcat-users.xml
.
Задача – перенастроить Tomcat на использование механизма JDBCRealm
с использованием базы данных (MySQL, Oracle).
Для примера возьмём такие настройки пользователя и его роли (группы):
$ cat conf/tomcat-users.xml | grep index <role rolename="indexadmin"/> <user username="indexadmin" password="password" roles="indexadmin"/>
Настройки ограничения доступа заданы в файле web.xml
, и описаны так:
<security-constraint> <web-resource-collection> <web-resource-name>Restricted Area</web-resource-name> <url-pattern>/index.jsp</url-pattern> </web-resource-collection> <auth-constraint> <role-name>indexadmin</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> <realm-name>JDBCRealm</realm-name> </login-config> <security-role> <role-name>indexadmin</role-name> </security-role>
Подробнее о назначении элементов в статье Tomcat: ограничение доступа с помощью файла web.xml.
Тут – мы ограничиваем доступ к файлу index.jsp
в корневой директории сервера, для аутентификации будем использовать BASIC
(логин/пароль, которые надо будет вводить в окне браузера), доступ к файлу будет разрешён членам группы indexadmin
.
Качаем драйвер JDBCR
.
Для MySQL:
http://dev.mysql.com/downloads/connector/j/
Для Oracle:
http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-112010-090769.html
В данном случае использовались ojdbc6.jar
и mysql-connector-java-5.1.27
.
Копируем архив с драйвером (только *.jar
файл) в каталог ../server/lib/
:
$ cp Opt/mysql-connector-java-5.1.27-bin.jar apache-tomcat-5.5.36_ssl_test/server/lib/
Создаём базу данных для MySQL:
mysql> create database tmc_access; Query OK, 1 row affected (0.03 sec)
mysql> use tmc_access; Database changed
Создаём таблицу, в которой будем хранить логины/пароли пользователей:
mysql> create table users (user_name varchar(100) not null primary key, user_pass varchar(100) not null); Query OK, 0 rows affected (0.08 sec)
Таблицу ролей:
mysql> create table user_roles (user_name varchar(100) not null, role_name varchar(100) not null, primary key (user_name, role_name)); Query OK, 0 rows affected (0.00 sec)
Oracle:
SQL> create table users (user_name varchar(100) not null primary key, user_pass varchar(100) not null); Table created.
Oracle:
SQL> create table user_roles (user_name varchar(100) not null, role_name varchar(100) not null, primary key (user_name, role_name)); Table created.
Создаём пользователя, под которым Tomcat будет работать с базой, привилегий SELECT
достаточно:
mysql> grant select on tmc_access.* to 'tmc_access'@'%' identified by 'password'; Query OK, 0 rows affected (0.15 sec)
Таблицы выглядят так:
MySQL:
mysql> desc user_roles; +-----------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------+--------------+------+-----+---------+-------+ | user_name | varchar(100) | NO | PRI | NULL | | | role_name | varchar(100) | NO | PRI | NULL | | +-----------+--------------+------+-----+---------+-------+ 2 rows in set (0.02 sec)
mysql> desc users; +-----------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------+--------------+------+-----+---------+-------+ | user_name | varchar(100) | NO | PRI | NULL | | | user_pass | varchar(100) | NO | | NULL | | +-----------+--------------+------+-----+---------+-------+ 2 rows in set (0.00 sec)
Oracle:
SQL> desc users; Name Null? Type ----------------------------------------- -------- ---------------------------- USER_NAME NOT NULL VARCHAR2(100) USER_PASS NOT NULL VARCHAR2(100)
SQL> desc user_roles; Name Null? Type ----------------------------------------- -------- ---------------------------- USER_NAME NOT NULL VARCHAR2(100) ROLE_NAME NOT NULL VARCHAR2(100)
Добавим пользователя indexadmin
с паролем password
:
MySQL:
mysql> insert into users (user_name, user_pass) values ('indexadmin', 'password'); Query OK, 1 row affected (0.02 sec)
Добавим роль indexadmin
, и назначим её пользователю indexadmin
:
mysql> insert into user_roles (user_name, role_name) values ('indexadmin', 'indexadmin'); Query OK, 1 row affected (0.02 sec)
Oracle:
SQL> insert into users (user_name, user_pass) values ('indexadmin', 'password'); 1 row created.
SQL> insert into user_roles (user_name, role_name) values ('indexadmin', 'indexadmin'); 1 row created.
Проверим:
MySQL:
mysql> select * from user_roles; +------------+------------+ | user_name | role_name | +------------+------------+ | indexadmin | indexadmin | +------------+------------+ 1 row in set (0.00 sec)
mysql> select * from users; +------------+-----------+ | user_name | user_pass | +------------+-----------+ | indexadmin | password | +------------+-----------+ 1 row in set (0.00 sec)
Oracle:
SQL> select * from users; USER_NAME -------------------------------------------------------------------------------- USER_PASS -------------------------------------------------------------------------------- indexadmin password
SQL> select * from user_roles; USER_NAME -------------------------------------------------------------------------------- ROLE_NAME -------------------------------------------------------------------------------- indexadmin indexadmin
Для Oracle не забываем выполнить комит:
SQL> commit; Commit complete.
Переходим к настройке самого Tomcat.
Комментируем часть, где описывается Realm
по-умолчанию, его мы использовать не будем вообще:
<!-- <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> -->
Далее, для MySQL, раскомментируем и отредактируем блок:
<Realm className="org.apache.catalina.realm.JDBCRealm" driverName="org.gjt.mm.mysql.Driver" connectionURL="jdbc:mysql://10.***.***.239/tmc_access" connectionName="tmc_access" connectionPassword="password" userTable="users" userNameCol="user_name" userCredCol="user_pass" userRoleTable="user_roles" roleNameCol="role_name" />
Тут:
driverName=
– полное имя драйвера, обычно уже есть в файле;
connectionURL=
– адрес сервера и база данных;
connectionName=
– логин пользователя базы данных;
connectionPassword=
– его пароль;
userTable=
– таблица с логинами/паролями пользователей;
userNameCol=
– колонка с логинами;
userCredCol=
– с паролями;
userRoleTable=
– таблица с ролями;
roleNameCol=
– колонка таблицы, содержащая имена ролей.
Для Oracle – практически тоже самое:
<Realm className="org.apache.catalina.realm.JDBCRealm" driverName="oracle.jdbc.driver.OracleDriver" connectionURL="jdbc:oracle:thin:@oraclehost:1521:schemename" connectionName="DBusername" connectionPassword="DBuserpass" userTable="tmc_users_set" userNameCol="user_name" userCredCol="user_pass" userRoleTable="user_roles_set" roleNameCol="role_name" />
Сохраняем файл, и перезапускаем Tomcat. В процессах MySQL должен появится запрос:
mysql> SHOW FULL PROCESSLISTG ... *************************** 20. row *************************** Id: 1750340 User: tmc_access Host: thucydides:24272 db: tmc_access Command: Sleep Time: 1 State: Info: NULL
В случае проблем – смотрим файл ../logs/catalina.out
.
Наиболее частые – это если неверно указаны параметры подключения к серверу баз данных, или неверная база/таблица:
Dec 16, 2013 1:43:13 PM org.apache.catalina.realm.JDBCRealm authenticate SEVERE: Exception performing authentication java.sql.SQLException: ORA-01017: invalid username/password; logon denied
// неверный логин/пароль для доступа к базе данных
Dec 16, 2013 1:16:25 PM org.apache.catalina.realm.JDBCRealm authenticate SEVERE: Exception performing authentication com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
// неверный адрес сервера MySQL, возможно – он прослушивает внешний IP
сервера, а не localhost/127.0.0.1
, можно проверить:
# netstat -anp | grep mysql tcp 0 0 10.***.***.239:3306 0.0.0.0:* LISTEN 27084/mysqld
Dec 16, 2013 12:14:00 PM org.apache.catalina.startup.ContextConfig applicationWebConfig SEVERE: Parse error in application web.xml file at jndi:/localhost/WEB-INF/web.xml java.lang.IllegalArgumentException: Invalid <url-pattern> index.jsp in security constraint
// ошибка в описании <url-pattern>
, файл необходимо указывать от корня webapps/ROOT
, т.е. со слешом /
Ссылки по теме:
http://tomcat.apache.org
http://tomcat.apache.org
http://josescalia.wordpress.com