2008-12-05 77 views
11

有沒有什麼方法可以通過用戶在JSP或Servlet中具有的角色來獲取String []?如何獲取JSP/Servlet中的用戶角色

我知道request.isUserInRole(「role1」),但我也想知道用戶的所有角色。

我搜索了servlet源代碼,看起來這是不可能的,但這對我來說似乎很奇怪。

那麼...有什麼想法?

回答

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()的結果轉換爲該類型並使用它提供的方法。

​​

我說這會變得混亂。它也不是很便攜。

+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 EE平臺實現 - 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() { 
    } 

} 

參考文獻: