Защищенный сервлет с использованием @EmbeddedIdentityStoreDefinition, работает с TomEE Plume, а не в WildFly20 - PullRequest
1 голос
/ 18 июня 2020

Я пытаюсь реализовать Java EE 8 security с очень простыми примерами кодов. Это сервлет , который защищен:

@WebServlet(name = "/InitiateRead", urlPatterns = {"/initread.do"})
@DeclareRoles({"user","admin","guest"})
@ServletSecurity(@HttpConstraint(rolesAllowed = {"user","admin"}))
@BasicAuthenticationMechanismDefinition(realmName="secured-basic")
@EmbeddedIdentityStoreDefinition({
    @Credentials(callerName = "user",  password = "password",   groups = {"user" }),
    @Credentials(callerName = "admin", password = "admin",      groups = {"admin"}),
    @Credentials(callerName = "guest", password = "guest",      groups = {"guest" })}
)
public class InitiateRead extends HttpServlet {
  private static final long serialVersionUID = 1L;
  @Override
  public void doGet(HttpServletRequest request, HttpServletResponse response) throws 
           ServletException, IOException {
    System.out.println("inside read initiator servlet.");
  }
  @Override
  public void doPost(HttpServletRequest request, HttpServletResponse response) throws 
           ServletException, IOException {
      doGet(request,response);
  }

Это реализация HttpAuthenticationMechanism :

@ApplicationScoped
public class ContentAuthenticationMechanism implements HttpAuthenticationMechanism{
    private Map<String,String> users;
    private Map<String,Set<String>> roles;

    @PostConstruct
    public void init() {
        users= new HashMap<>();roles= new HashMap<>();      
        users.put("admin", "admin");users.put("user", "password");users.put("guest", "guest");      
        roles.put("admin", new HashSet<>(Arrays.asList("admin")));
        roles.put("user", new HashSet<>(Arrays.asList("user")));
        roles.put("guest", new HashSet<>(Arrays.asList("guest")));      
    }
    @Override
    public AuthenticationStatus validateRequest(HttpServletRequest request, HttpServletResponse response,
            HttpMessageContext httpMessageContext) throws AuthenticationException {
        String username= request.getParameter("username");
        String password= request.getParameter("password");
        System.out.println("username:"+username+" password:"+password);
        if(username!=null && password != null) {
            if(users.containsKey(username)){
                if(users.get(username).equals(password)) {
                    return httpMessageContext.notifyContainerAboutLogin(username,roles.get(username));
                }
            }
            return httpMessageContext.responseUnauthorized();                       
        }
        return httpMessageContext.doNothing();
    }   
}

Простой index.jsp отправляет имя пользователя и пароль сервлету. Вот обрезанный POM.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <packaging>war</packaging>
    <dependencies>
        <dependency> 
            <groupId>javax</groupId> 
            <artifactId>javaee-api</artifactId> 
            <version>8.0</version> 
            <scope>provided</scope>
        </dependency> 
        <dependency> 
            <groupId>org.glassfish.soteria</groupId>  
            <artifactId>jakarta.security.enterprise</artifactId>  
            <version>1.0.1</version>  
        </dependency> 
    </dependencies>
    <build>
        <finalName>secured</finalName>
    </build>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>12</maven.compiler.source>
        <maven.compiler.target>12</maven.compiler.target>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </properties>
</project>

теперь в TomEE Plume , после предоставления правильных учетных данных и отправки формы в обращении сервлет печатает сообщение System.out.println() в консоли. Но в WildFly 20 , даже после предоставления учетных данных для входа и отправки формы jsp, отображается Запрещено . Один и тот же код в двух случаях ведет себя по-разному. Пожалуйста, помогите мне, я думаю, мне не хватает здесь очень важной c точки.

Ответы [ 2 ]

0 голосов
/ 31 августа 2020

Wildfly использует встроенный HttpAuthenticationMechanism. Вам необходимо активировать собственную реализацию HttpAuthenticationMechanism. Чтобы использовать собственную реализацию HttpAuthenticationMechanism, вам необходимо сделать следующее:

@ApplicationScoped

@Alternative
@Priority(javax.interceptor.Interceptor.Priority.APPLICATION)

public class ContentAuthenticationMechanism implements HttpAuthenticationMechanism {
    // Your code
}

Кроме того, вам необходимо удалить BasicAuthenticationMechanismDefinition и EmbeddedIdentityStoreDefinition из вашего сервлета, поскольку вы используете свой собственный HttpAuthenticationMechanism.

0 голосов
/ 12 июля 2020

Если JASPI C включен путем размещения jboss-web.xml, любая реализация HttpAuthenticationMechanism вызывает AmbiguousResolutionException от WildFly. soteria реализация конфликтует с пользовательской реализацией. обходится путем реализации IdentityStore и переопределения validate() для целей проверки учетных данных. Без jboss-web.xml JASPI C не сработает. При попадании в защищенный сервлет он всегда будет возвращать HTTP - 403, даже если пользовательский HttpAuthenticationMechanism на месте, он не сможет перехватить, это будет 403 без jboss-web. xml. В этой модифицированной реализации механизм проверки делегирован soteria ' s собственная реализация HttpAuthenticationMechanism. Только этот сервлет используется здесь для тестового запуска @EmbeddedIdentityStoreDefinition.

@WebServlet(name = "/InitiateRead", urlPatterns = {"/initread.do"})    
@DeclareRoles({"user","admin","guest"})
@ServletSecurity(@HttpConstraint(rolesAllowed = {"user","admin"}))
@BasicAuthenticationMechanismDefinition(realmName="security-realm")
@EmbeddedIdentityStoreDefinition({
    @Credentials(callerName = "user",  password = "password123",    groups = {"user" }),
    @Credentials(callerName = "admin", password = "admin123",       groups = {"admin"}),
    @Credentials(callerName = "guest", password = "guest123",       groups = {"guest"}) 
    })
public class InitiateRead extends HttpServlet {
  private static final long serialVersionUID = 1L;
  @Inject
  private Logger logger;
  @Override
  public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      logger.log(Level.INFO,"inside  read initiator servlet's .doPost() .");
  }
  @Override
  public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      doGet(request,response);
  }  
}

Тестовые коды https://github.com/eclipse-ee4j/soteria/tree/1.0.1/test, предоставленные @ArjanTijms, оказались единственными -stop решение для новичков, таких как я, чтобы усвоить asp основные концепции Jakarta EE s API безопасности .

...