2008-12-05 9 views
11

Есть ли способ получить строку [] с ролями, которые пользователь имеет в JSP или сервлет?Как получить роли пользователя в JSP/Servlet

Я знаю о request.isUserInRole ("role1"), но также хочу знать все роли пользователя.

Я искал источник сервлетов, и кажется, что это невозможно, но это кажется странным для меня.

Итак ... любые идеи?

ответ

6

Прочитайте все возможные роли или список жестких кодов. Затем перейдем к запуску isUserInRole и создадим список ролей, в котором находится пользователь, а затем преобразуем список в массив.

String[] allRoles = {"1","2","3"}; 
HttpServletRequest request = ... (or from method argument) 
List userRoles = new ArrayList(allRoles.length); 
for(String role : allRoles) { 
if(request.isUserInRole(role)) { 
    userRoles.add(role); 
} 
} 

// I forgot the exact syntax for list.toArray so this is prob wrong here 
return userRoles.toArray(String[].class); 
+0

Да, я могу сделать это, когда пользователь выполнит логин ... Это хороший хак. Но все же, это невозможно сделать в JBoss, например userPrincipal.getRoles(); ? – AlfaTeK 2008-12-05 15:56:09

+0

Когда дело доходит до написания webapps, я всегда избегаю любого кода сервера. Вы хотите поддерживать переносимость на таких серверах, как Tomcat и Resin и Jetty. Поэтому вам нужно будет увидеть, есть ли что-то в спецификации или способ получить список из контекста. – Josh 2008-12-16 23:58:10

10

Ответ грязный.

Сначала вам нужно выяснить, какой тип request.getUserPrincipal() возвращается в ваш webapp.

System.out.println("type = " + request.getUserPrincipal().getClass()); 

Предположим, что возвращает org.apache.catalina.realm.GenericPrincipal.

Затем введите результат getUserPrincipal() в этот тип и используйте методы, которые он предоставляет.

final Principal userPrincipal = request.getUserPrincipal(); 
    GenericPrincipal genericPrincipal = (GenericPrincipal) userPrincipal; 
    final String[] roles = genericPrincipal.getRoles(); 

Я сказал, что это будет грязно. Это тоже не очень портативно.

+1

Он возвращает класс org.jboss.security.SimplePrincipal и этот класс не имеет getRoles() ... что очень глупо ... К сожалению, я должен был упомянуть: я использую JBoss 4.2.3GA AS – AlfaTeK 2008-12-05 15:47:10

4

В WebLogic вы можете сделать это с:

import weblogic.security.Security; 
import weblogic.security.SubjectUtils; 
... 
private List<String> getUserRoles() { 
    return Arrays.asList(SubjectUtils.getPrincipalNames(Security.getCurrentSubject()).split("/")); 
} 

Обратите внимание, что первый элемент в списке имя пользователя.

0

На серверах приложений, совместимых с JACC - в теории каждая реализация полной платформы Java Java - Java SE Policy может быть опрошена для оценки любого типа декларативного ограничения безопасности, заданного Servlet и EJB.

Следующий пример демонстрирует тестирование назначения ролей:

package com.example; 

import java.security.CodeSource; 
import java.security.Permission; 
import java.security.PermissionCollection; 
import java.security.Policy; 
import java.security.Principal; 
import java.security.ProtectionDomain; 
import java.security.cert.Certificate; 
import java.util.Collections; 
import java.util.Enumeration; 
import java.util.HashSet; 
import java.util.Set; 

import javax.security.auth.Subject; 
import javax.security.jacc.PolicyContext; 
import javax.security.jacc.PolicyContextException; 
import javax.security.jacc.WebRoleRefPermission; 

public final class Util { 


    private static final Set<String> NO_ROLES = Collections.emptySet(); 
    private static final Permission DUMMY_WEB_ROLE_REF_PERM = new WebRoleRefPermission("", "dummy"); 

    /** 
    * Retrieves the declared Servlet security roles that have been mapped to the {@code Principal}s of 
    * the currently authenticated {@code Subject}, optionally limited to the scope of the Servlet 
    * referenced by {@code servletName}. 
    * 
    * @param servletName 
    *   The scope; {@code null} indicates Servlet-context-wide matching. 
    * @return the roles; empty {@code Set} iff: 
    *   <ul> 
    *   <li>the remote user is unauthenticated</li> 
    *   <li>the remote user has not been associated with any roles declared within the search 
    *   scope</li> 
    *   <li>the method has not been called within a Servlet invocation context</li> 
    *   </ul> 
    */ 
    public static Set<String> getCallerWebRoles(String servletName) { 
     // get current subject 
     Subject subject = getSubject(); 
     if (subject == null) { 
      // unauthenticated 
      return NO_ROLES; 
     } 
     Set<Principal> principals = subject.getPrincipals(); 
     if (principals.isEmpty()) { 
      // unauthenticated? 
      return NO_ROLES; 
     } 
     // construct a domain for querying the policy; the code source shouldn't matter, as far as 
     // JACC permissions are concerned 
     ProtectionDomain domain = new ProtectionDomain(new CodeSource(null, (Certificate[]) null), null, null, 
       principals.toArray(new Principal[principals.size()])); 
     // get all permissions accorded to those principals 
     PermissionCollection pc = Policy.getPolicy().getPermissions(domain); 
     // cause resolution of WebRoleRefPermissions, if any, in the collection, if still unresolved 
     pc.implies(DUMMY_WEB_ROLE_REF_PERM); 
     Enumeration<Permission> e = pc.elements(); 
     if (!e.hasMoreElements()) { 
      // nothing granted, hence no roles 
      return NO_ROLES; 
     } 
     Set<String> roleNames = NO_ROLES; 
     // iterate over the collection and eliminate duplicates 
     while (e.hasMoreElements()) { 
      Permission p = e.nextElement(); 
      // only interested in Servlet container security-role(-ref) permissions 
      if (p instanceof WebRoleRefPermission) { 
       String candidateRoleName = p.getActions(); 
       // - ignore the "any-authenticated-user" role (only collect it if your 
       // application has actually declared a role named "**") 
       // - also restrict to the scope of the Servlet identified by the servletName 
       // argument, unless null 
       if (!"**".equals(candidateRoleName) && ((servletName == null) || servletName.equals(p.getName())) 
         && ((roleNames == NO_ROLES) || !roleNames.contains(candidateRoleName))) { 
        if (roleNames == NO_ROLES) { 
         roleNames = new HashSet<>(); 
        } 
        roleNames.add(candidateRoleName); 
       } 
      } 
     } 
     return roleNames; 
    } 

    private static Subject getSubject() { 
     return getFromJaccPolicyContext("javax.security.auth.Subject.container"); 
    } 

    @SuppressWarnings("unchecked") 
    private static <T> T getFromJaccPolicyContext(String key) { 
     try { 
      return (T) PolicyContext.getContext(key); 
     } 
     catch (PolicyContextException | IllegalArgumentException e) { 
      return null; 
     } 
    } 

    private Util() { 
    } 

} 

Ссылки:

Смежные вопросы