3

Мне нужно настроить оба метода проверки подлинности BASIC и FORM в зависимости от веб-ресурса в приложении Java EE. Это означает, что, например, для путей/приложений/служб, которые я хочу выполнить проверку подлинности с использованием BASIC, а для остальной части метода приложения будет FORM.Как настроить методы проверки подлинности BASIC и FORM в одном и том же приложении Java EE

Возможно ли это даже без весны, но в чистой Java EE?

+1

Это невозможно в одном «войне», но вы можете создать два веб-модуля в одном «ухе» и настроить их по-разному и разделить бизнес-логику. Любая конкретная причина, почему вам нужны оба механизма в одном приложении? – Gas

+0

Да, причина в том, что мне нужны услуги по уходу, разрешенные BASIC, и веб-приложение, разрешенное FORM. Спасибо за ответ. –

+1

Тогда я бы предложил создать отдельный веб-модуль для службы отдыха и обмениваться общей бизнес-логикой через библиотеку или модуль ejb, это было бы самым простым и обеспечило бы хорошее разделение обязанностей. Также можно сделать 'post' в' j_security_check' от вашего клиента для отдыха. И если это внутренние службы, они могут использовать cookie из браузера. – Gas

ответ

2

Возможно, но вам нужно создать и установить свой собственный модуль аутентификации вместо использования двух встроенных BASIC и FORM.

Java EE имеет API/SPI для этого JASPIC. Кроме того, для многих серверов приложений для этого используется альтернативный API.

-1

Весна безопасности устанавливает собственный фильтр. Вы можете написать свой собственный фильтр/фильтры и установить их вместо этого. Если вы можете легко определить, какие шаблоны URL используют один auth, а другой - довольно простой с двумя фильтрами

1

Да, есть обходное решение (я сделал это для Tomcat 7.0.68).

1) Настройте ваш web.xml использовать FORM аутентификации-метод:

<login-config> 
<auth-method>FORM</auth-method> 
    <form-login-config> 
    <form-login-page>/login.jsp</form-login-page> 
    <form-error-page>/loginError.jsp</form-error-page> 
    </form-login-config> 
</login-config> 

2) Установите url-pattern вы хотите проверить подлинность BASIC путь без каких-либо auth-constraint:

<security-constraint> 
    <web-resource-collection> 
    <web-resource-name>BASIC auth path</web-resource-name> 
     <url-pattern>/app/services/*</url-pattern> 
    </web-resource-collection> 
    </security-constraint> 

3) Настройка фильтра для этой модели:

<filter> 
    <filter-name>BasicLoginFilter</filter-name> 
    <filter-class>pa.cka.ge.BasicLoginFilter</filter-class> 
    <init-param> 
    <param-name>role-names-comma-sep</param-name> 
    <param-value>role1,andRole2,andRole3</param-value> 
    </init-param> 
</filter> 
<filter-mapping> 
    <filter-name>BasicLoginFilter</filter-name> 
    <url-pattern>/app/services/*</url-pattern> 
</filter-mapping> 

enter code here 

, где role-names-comma-sep - это ваш настраиваемый параметр, определяющий роли для доступа к /app/services. Это полезно, потому что путь /app/services не должен иметь ограничений auth (см. Выше), и вы, как правило, не можете определять роли как обычно. В моем примере реализация проверяет эти роли с помощью AND (вы можете ее изменить).

4) Войти Процесс вручную в фильтре:

package pa.cka.ge; 

import java.io.IOException; 
import java.security.Principal; 
import java.util.ArrayList; 
import java.util.Iterator; 
import java.util.List; 

import javax.servlet.Filter; 
import javax.servlet.FilterChain; 
import javax.servlet.FilterConfig; 
import javax.servlet.ServletException; 
import javax.servlet.ServletRequest; 
import javax.servlet.ServletResponse; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

import org.apache.catalina.Role; 
import org.apache.catalina.users.MemoryUser; 
import org.apache.tomcat.util.buf.B2CConverter; 
import org.apache.tomcat.util.codec.binary.Base64; 

public class BasicLoginFilter implements Filter { 

    /** 
    * List of roles the user must have to authenticate 
    */ 
    private final List&lt;String&gt; roleNames = new ArrayList&lt;String&gt;(); 

    @Override 
    public void init(FilterConfig filterConfig) throws ServletException { 
    String roleNamesParam = filterConfig.getInitParameter("role-names-comma-sep"); 
    if (roleNamesParam != null) { 
     for (String roleName: roleNamesParam.split(",")) { 
     roleNames.add(roleName); 
     } 
    } 
    } 

    private static final String AUTHORIZATION_HEADER = "Authorization"; 
    private static final String BASIC_PREFIX = "Basic "; 

    @Override 
    public void doFilter(ServletRequest req, ServletResponse resp, 
     FilterChain chain) throws IOException, ServletException { 
    HttpServletRequest request = (HttpServletRequest)req; 
    HttpServletResponse response = (HttpServletResponse)resp; 

    // get username and password from the Authorization header 
    String authHeader = request.getHeader(AUTHORIZATION_HEADER); 
    if (authHeader == null || !authHeader.startsWith(BASIC_PREFIX)) { 
     throwBasicAuthRequired(); 
    } 

    String userPassBase64 = authHeader.substring(BASIC_PREFIX.length()); 
    String userPassDecoded = new String(Base64.decodeBase64(userPassBase64), B2CConverter.ISO_8859_1);// decode from base64 any other way, if this won't work for you. Finally userPassDecoded must contain readable "username:password" 
    if (!userPassDecoded.contains(":")) { 
     throwBasicAuthRequired(); 
    } 

    String authUser = userPassDecoded.substring(0, userPassDecoded.indexOf(':')); 
    String authPass = userPassDecoded.substring(userPassDecoded.indexOf(':') + 1); 

    // do login manually 
    request.login(authUser, authPass); 

    // check roles for the user 
    final Principal userPrincipal = request.getUserPrincipal(); 

    // Your Principal will be another class, not MemoryUser. Run in debug mode to see what class you actually have. The role checking will depend on that class. 
    MemoryUser user = (MemoryUser)userPrincipal; 

    boolean hasRoles = true; 
    for (String role: roleNames) { 
     if (role == null) { 
     continue; 
     } 
     boolean hasRole = false; 
     Iterator&lt;Role&gt; roles = user.getRoles(); 
     while (roles.hasNext()) { 
     if (role.equals(roles.next().getName())) { 
      hasRole = true; 
      break; 
     } 
     } 
     if (!hasRole) { 
     hasRoles = false; 
     break; 
     } 
    } 

    if (hasRoles) { 
     // login successful 
     chain.doFilter(request, response); 
     request.logout();// optional 
    } else { 
     // login failed 
     throwLoginFailed(); 
    } 
    } 

    @Override 
    public void destroy() { 
    } 

    public static void throwBasicAuthRequired() throws ServletException { 
    throw new ServletException("The /app/services resources require BASIC authentication"); 
    } 

    public static void throwLoginFailed() throws ServletException { 
    throw new ServletException("Login failed"); 
    } 
} 

Готово! Теперь /app/services поддерживает BASIC auth, но остальное приложение поддерживает FORM.

0

Начиная с Servlet 3.0 (Tomcat 7+) можно программно сделать HttpServletRequest.login()

Получить пользователь: пароль, как в ответ и логин Романовы.