Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通过代码进行基本身份验证的嵌入式Tomcat_Java_Tomcat_Servlets_Basic Authentication - Fatal编程技术网

Java 通过代码进行基本身份验证的嵌入式Tomcat

Java 通过代码进行基本身份验证的嵌入式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

我打算在嵌入式tomcat中添加两个servlet。在这个场景中,一个servlet应该受到基本身份验证的“保护”。我只想通过代码添加安全约束。关于这一点,不应该太难

我构建了一个测试场景:

项目:EmbeddedTomcatTest

-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