[英]ClassNotFoundException after adding the jar to the lib folder of a Tomcat Service installation
[英]Is it possible to create custom realm in tomcat without adding jar to lib folder?
我想用自定義身份驗證制作Web應用程序。 但是我必須將Realm添加到server.xml中。 這需要我將jar添加到tomcat lib文件夾中。 我能把所有內容保存在我的戰爭文件中嗎 怎么樣?
感謝名單!
遺憾的是,不可能在Tomcat中從WAR部署自定義領域。 必須可以在CATALINA_HOME中訪問自定義領域實現。 它被視為容器工件,而不是應用程序工件。
我只能想到這三個選項:
至少Glassfish和JBoss AS支持從WAR部署的自定義領域。
Tomcat 8現在允許自定義憑證處理。 如果可能足以滿足您的需求,而不是使用自定義的解決方案:
Apache Tomcat 8.0.15可用
[...]
通過新的CredentialHandler接口向Realms添加可插入密碼派生支持。
請參閱http://www.tomcatexpert.com/blog/2014/11/14/apache-tomcat-8015-available
並https://tomcat.apache.org/tomcat-8.0-doc/config/credentialhandler.html
如果您的解決方案已按預期工作,您可能希望保留它並直接處理部署問題。
另一個不錯的選擇是使用Tomcat的股票JAASRealm
( org.apache.catalina.realm.JAASRealm
)來實現自定義JAAS LoginModule
。 這種方法的JAASRealm
是可以通過類路徑源configFile
值配置JAASRealm
以便所有內容都捆綁在WAR文件中。 來自https://tomcat.apache.org/tomcat-9.0-doc/config/realm.html#JAAS_Realm_-_org.apache.catalina.realm.JAASRealm關於configFile
領域屬性:
與此Realm一起使用的JAAS配置文件的名稱。 將使用ClassLoader#getResource(String)搜索它,以便可以將配置捆綁在Web應用程序中。 如果未指定,將使用缺省JVM全局JAAS配置。
這是所有部分的簡單示例:
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;
}
}
DemoAuth {
com.company.jaas.DemoLoginModule required ;
};
以上所有內容都可以打包在一個jar中,並作為庫包含在另一個應用程序中。 該應用程序可以使用以下tomcat領域配置使用JAAS支持的身份驗證:
<?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>
jaas.config
文件將在類路徑中找到(Web應用程序的本地或jar依賴項)。 在給定我們簡單的DemoLoginModule
實現的情況下,通過admin / password憑證進行身份驗證后,將可以訪問受admin角色保護的任何資源(即任何帶有pattern /admin/*
url)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.