我想使用自定义身份验证制作网络应用。但是我必须将Realm添加到server.xml中。这需要我将jar添加到tomcat lib文件夹中。我能把所有内容保存在我的战争文件中吗怎么样?
感谢名单!
答案 0 :(得分:5)
不幸的是,不可能在Tomcat中从WAR部署自定义领域。必须可以在CATALINA_HOME中访问自定义领域实现。它被视为容器工件,而不是应用程序工件。
我只能想到这三个选项:
至少 Glassfish 和 JBoss AS 支持从WAR部署的自定义域。
Tomcat 8现在允许自定义凭据处理。如果可能足以满足您的需求,而不是使用自定义的真实解决方案:
Apache Tomcat 8.0.15可用
[...]
通过新增功能为Realms添加可插拔密码派生支持 CredentialHandler接口。
请参阅http://www.tomcatexpert.com/blog/2014/11/14/apache-tomcat-8015-available
https://tomcat.apache.org/tomcat-8.0-doc/config/credentialhandler.html
如果您的解决方案已按预期工作,您可能希望保留它并直接处理部署问题。
答案 1 :(得分:0)
另一个好的选择是使用Tomcat的股票const content = '<p>' +
'<strong>Summary</strong><br />Some text with <strong>HTML</strong> tags...<br /><br />' +
'<strong>Keywords</strong> keyword1, keyword2,...<br /><br />' +
'</p>';
var summary = content.match('<strong>Summary</strong><br />(.*?)<br /><br />');
var keywords = content.match('<strong>Keywords</strong> (.*?)<br /><br />');
alert (summary[1]);
alert (keywords[1]);
(JAASRealm
)来实现自定义JAAS org.apache.catalina.realm.JAASRealm
。这种方法的优点在于,可以通过源自LoginModule
的类路径值来配置JAASRealm
,以便所有内容都捆绑在WAR文件中。来自https://tomcat.apache.org/tomcat-9.0-doc/config/realm.html#JAAS_Realm_-_org.apache.catalina.realm.JAASRealm的configFile
领域属性:
与此领域一起使用的JAAS配置文件的名称。将使用ClassLoader#getResource(String)进行搜索,因此可以将配置捆绑在Web应用程序中。如果未指定,将使用默认的JVM全局JAAS配置。
这是所有部分的简单示例:
configFile
package com.company.jaas;
import java.security.Principal;
public class User implements Principal {
private final String username;
public User(String username) {
this.username = username;
}
public String getUsername() {
return username;
}
@Override
public String getName() {
return getUsername();
}
@Override
public String toString() {
return "User{" + "username=" + username + '}';
}
}
package com.company.jaas;
import java.security.Principal;
public class Role implements Principal {
private final String name;
public Role(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public String toString() {
return "Role{" + "name=" + name + '}';
}
}
package com.company.jaas;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
public class DemoLoginModule implements LoginModule {
private CallbackHandler handler;
private Subject subject;
private User user;
private List<Role> roles;
@Override
public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {
this.handler = callbackHandler;
this.subject = subject;
}
@Override
public boolean login() throws LoginException {
Callback[] callbacks = new Callback[2];
callbacks[0] = new NameCallback("login");
callbacks[1] = new PasswordCallback("password", true);
try {
handler.handle(callbacks);
String username = ((NameCallback) callbacks[0]).getName();
String password = String.valueOf(((PasswordCallback) callbacks[1]).getPassword());
// todo: perform real validation here (using any desired mechanism)
if ("admin".equalsIgnoreCase(username) && "password".equals(password)) {
user = new User(username);
roles = List.of(new Role("admin"));
return true;
}
throw new FailedLoginException("Authentication failed");
}
catch (IOException | UnsupportedCallbackException ex) {
throw new LoginException(ex.getMessage());
}
}
@Override
public boolean commit() throws LoginException {
subject.getPrincipals().add(user);
subject.getPrincipals().addAll(roles);
return true;
}
@Override
public boolean abort() throws LoginException {
return false;
}
@Override
public boolean logout() throws LoginException {
subject.getPrincipals().remove(user);
subject.getPrincipals().removeAll(roles);
return true;
}
}
以上所有内容都可以打包在一个jar中,并作为一个库包含在另一个应用程序中。该应用程序可以通过使用以下tomcat领域配置来使用JAAS支持的身份验证:
DemoAuth {
com.company.jaas.DemoLoginModule required ;
};
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<security-role>
<role-name>admin</role-name>
</security-role>
<security-constraint>
<web-resource-collection>
<web-resource-name>action</web-resource-name>
<url-pattern>/admin/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/WEB-INF/jsp/login.jsp</form-login-page>
<form-error-page>/WEB-INF/jsp/login-error.jsp</form-error-page>
</form-login-config>
</login-config>
</web-app>
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/JaasDemo">
<Realm appName="DemoAuth"
configFile="jaas.config"
className="org.apache.catalina.realm.JAASRealm"
userClassNames="com.company.jaas.User"
roleClassNames="com.company.jaas.Role" />
</Context>
文件将在类路径中找到(在Web应用程序本地或在jar依赖项中)。只要使用我们简单的jaas.config
实现,通过admin / password凭据进行身份验证,就可以访问受admin角色保护的任何资源(即,任何具有模式/admin/*
的url)。