Java 通过代码进行基本身份验证的嵌入式Tomcat
我打算在嵌入式tomcat中添加两个servlet。在这个场景中,一个servlet应该受到基本身份验证的“保护”。我只想通过代码添加安全约束。关于这一点,不应该太难 我构建了一个测试场景: 项目:EmbeddedTomcatTestJava 通过代码进行基本身份验证的嵌入式Tomcat,java,tomcat,servlets,basic-authentication,Java,Tomcat,Servlets,Basic Authentication,我打算在嵌入式tomcat中添加两个servlet。在这个场景中,一个servlet应该受到基本身份验证的“保护”。我只想通过代码添加安全约束。关于这一点,不应该太难 我构建了一个测试场景: 项目:EmbeddedTomcatTest -Source Packages --tomcat.test ---ServletOne.java ---ServletTwo.java ---StartEmbeddedTomcat.java (contains main method) -Test Packag
-Source Packages
--tomcat.test
---ServletOne.java
---ServletTwo.java
---StartEmbeddedTomcat.java (contains main method)
-Test Packages
-Other Sources
--src/main/resources
---Tomcat-users.xml
-Project Files
--pom.xml
我的pom的依赖项如下所示:
<dependencies>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>8.5.4</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
<web-app>
<display-name>Test Service</display-name>
<servlet>
<servlet-name>ServletOne</servlet-name>
<servlet-class>tomcat.test.test.ServletOne</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ServletOne</servlet-name>
<url-pattern>/servletOne/*</url-pattern>
</servlet-mapping>
</web-app>
tomcat users.xml不是很特别
<tomcat-users>
<role rolename="manager-gui"/>
<role rolename="test"/>
<user name="admin" password="" roles="manager-gui"/>
<user name="test" password="test" roles="test"/>
</tomcat-users>
我认为我的servletOne也可以通过
localhost:8080/servletOne/*
访问。不是。。实际上我很困惑。我希望有人能帮助我。问题是您正在尝试保护上下文。上下文不安全,即
tomcat.addContext(“/”,新文件(“.”).getAbsolutePath()代码>
必须改为
tomcat.addWebapp(“/”,新文件(“.”).getAbsolutePath()代码>
您必须处理一些异常处理,因为添加一个新的web应用程序可能会抛出一个ServletException
,但是它应该会像您预期的那样在以后工作
如果不想加载默认值(即MIME类型映射、静态内容servlet、JSP等),只需重写getDefaultWebXmlListener
方法即可
tomcat = new Tomcat() {
@Override
public LifecycleListener getDefaultWebXmlListener() {
return event -> {};
}
};
也许现在回答这个问题有点晚了,但它可能对其他人有用。最近,当我试图用SpringBoot为嵌入式Tomcat配置安全性时,我遇到了类似的问题,安全约束根本不起作用,我的领域根本没有被调用。
问题出现在org.apache.catalina.authenticator.SSLAuthenticator中,该阀未添加到Tomcat管道,因此未检查安全约束
添加tomcatFactory.addContextValves(新的SSLAuthenticator())代码>解决了问题
如果您需要基本的身份验证,则阀类是
org.apache.catalina.authenticator.BasicAuthenticator
嵌入式tomcat上双向SSL和安全域的完整工作配置:
Java配置
@Configuration
public class EmbeddedTomcatConfiguration {
private static final String LOGIN_CONFIG_AUTH_METHOD = "CLIENT-CERT";
@Bean
public RealmBase createPkiRealm() {
//Create your custom realm or use some standard one here
return realm;
}
@Bean
public EmbeddedServletContainerCustomizer createTomcatCustomizer(RealmBase pkiRealm) {
return (container) -> {
TomcatEmbeddedServletContainerFactory tomcatFactory = (TomcatEmbeddedServletContainerFactory) container;
//tomcatFactory.addAdditionalTomcatConnectors(createSslConnector()); //connector is configured in application.properties
tomcatFactory.addContextCustomizers(createTomcatContextCustomizer(pkiRealm));
tomcatFactory.addEngineValves(new SingleSignOn());
tomcatFactory.addContextValves(new SSLAuthenticator()); //this is where PKI realm is invoked
};
}
private TomcatContextCustomizer createTomcatContextCustomizer(RealmBase pkiRealm) {
return (context) -> {
context.setRealm(pkiRealm);
context.setLoginConfig(createLoginConfig());
context.addSecurityRole("new_role");
context.addConstraint(createSecurityConstraint());
};
}
private LoginConfig createLoginConfig() {
LoginConfig config = new LoginConfig();
config.setAuthMethod(LOGIN_CONFIG_AUTH_METHOD);
return config;
}
private SecurityConstraint createSecurityConstraint() {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setDisplayName("Employee certificate required");
SecurityCollection securityCollection = new SecurityCollection("sec_collection");
securityCollection.addPattern("/test/*");
securityConstraint.addCollection(securityCollection);
securityConstraint.addAuthRole("new_role");
securityConstraint.setAuthConstraint(true);
securityConstraint.setUserConstraint("CONFIDENTIAL");
return securityConstraint;
}
}
具有新SSL连接器配置的application.properties
server.port=8443
server.ssl.enabled=true
server.ssl.client-auth=need
server.ssl.key-store=classpath:certs/serverkeystore.p12
server.ssl.key-store-password=changeit
server.ssl.key-store-type=PKCS12
server.ssl.key-alias=serverkey
server.ssl.trust-store=classpath:certs/servertruststore.jks
server.ssl.trust-store-password=changeit
server.ssl.trust-store-type=jks
使用独立的Tomcat和用xml编写的相同配置,不需要额外的SSLAuthenticator阀
server.port=8443
server.ssl.enabled=true
server.ssl.client-auth=need
server.ssl.key-store=classpath:certs/serverkeystore.p12
server.ssl.key-store-password=changeit
server.ssl.key-store-type=PKCS12
server.ssl.key-alias=serverkey
server.ssl.trust-store=classpath:certs/servertruststore.jks
server.ssl.trust-store-password=changeit
server.ssl.trust-store-type=jks