簡體   English   中英

如何從web.xml檢索權限

[英]How to retrieve permissions from web.xml

我想知道是否有更好的方法(無反射)來獲取特定URL和Role的java.security.Permissions。

例如:

 boolean canAccess = SecurityController.isAllowedToAccessUrl("/pages/confirmOrders.action", Collections.singletonList(new UserPrincipal("Dave")));

可以使用以下約束條件(web.xml):

<security-constraint>
 <web-resource-collection>
   <web-resource-name></web-resource-name>
   <url-pattern>/pages/confirmOrders.action</url-pattern>
 </web-resource-collection>
 <auth-constraint>
   <role-name>Dave</role-name>
 </auth-constraint>

我寫的下面的代碼效果很好。 我不喜歡的是,我必須使用反射從DelegatingPolicy.getInstance()調用getContextPolicy,並從ContextPolicy調用getPermissionsForRole。

import org.jboss.security.jacc.ContextPolicy;
import org.jboss.security.jacc.DelegatingPolicy;

import javax.security.jacc.PolicyConfigurationFactory;
import javax.security.jacc.PolicyContext;
import javax.security.jacc.PolicyContextException;
import javax.security.jacc.WebResourcePermission;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.Permissions;
import java.security.Principal;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

public class SecurityController {
  private static final Logger LOG  = Logger.getLogger(SecurityController.class.getName());

  static boolean isAllowedToAccessUrl(final String url, final List<Principal> principalRoles) {
    initializeConfigurationInService();

    boolean result = false;
    for (Principal principalRole : principalRoles) {
      try{
        final ContextPolicy contextPolicy = getContextPolicy();
        final Permissions permissions = getPermissionsFromContextPolicy(contextPolicy, principalRole.getName());
        result |= permissions.implies(new WebResourcePermission(url, new String[] {"GET","POST"}));
      }catch (Exception e){
        LOG.log(Level.SEVERE, "checkAllowed failed checking if : ", e);
      }
    }
    return result;
  }

  private static void initializeConfigurationInService() {
    try {
      final PolicyConfigurationFactory policyConfigurationFactory = PolicyConfigurationFactory.getPolicyConfigurationFactory();
      policyConfigurationFactory.getPolicyConfiguration(PolicyContext.getContextID(), false);
    } catch (PolicyContextException | ClassNotFoundException e) {
      LOG.log(Level.INFO, "initializeConfigurationInService", e);
    }
  }

  private static Permissions getPermissionsFromContextPolicy(ContextPolicy contextPolicy, String loginName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
    final Method getPermissionsForRole = contextPolicy.getClass().getDeclaredMethod("getPermissionsForRole", String.class);
    getPermissionsForRole.setAccessible(true);
    return (Permissions) getPermissionsForRole.invoke(contextPolicy, loginName);
  }


  private static ContextPolicy getContextPolicy() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
    final DelegatingPolicy delegatingPolicy = DelegatingPolicy.getInstance();
    final Method getContextPolicy = delegatingPolicy.getClass().getDeclaredMethod("getContextPolicy", String.class);
    getContextPolicy.setAccessible(true);
    return (ContextPolicy) getContextPolicy.invoke(delegatingPolicy, PolicyContext.getContextID());
  }
}

我以編程方式閱讀了從web.xml檢索安全約束的信息,但發現它不是很有用。

任何意見,想法都非常歡迎。 謝謝!

多虧了Uux的評論,我得以縮短代碼並擺脫了使用反射的麻煩 現在,我可以驗證代碼中是否允許特定角色訪問特定URL。

可行的代碼如下:

import javax.security.jacc.WebResourcePermission;
import java.security.CodeSource;
import java.security.Policy;
import java.security.Principal;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

public class SecurityController {
  private static final Logger LOG = Logger.getLogger(SecurityController.class.getName());

  static boolean isAllowedToAccessUrl(final String url, final List<Principal> principalRoles) {
    try {
      final CodeSource codesource = new CodeSource(null, (Certificate[]) null);
      final Principal[] principals = principalRoles.toArray(new Principal[0]);
      final ProtectionDomain domain = new ProtectionDomain(codesource, null, null, principals);
      return Policy.getPolicy().implies(domain, (new WebResourcePermission(url, new String[] {"GET", "POST"})));
    } catch (Exception e) {
      LOG.log(Level.SEVERE, "checkAllowed failed checking if : ", e);
    }
    return false;
  }
}

Java EE 8中提供了執行'isAllowedToAccessUrl'函數的類似標准方法。

boolean hasAccessToWebResource(String resource, String... methods)

按照Servlet規范的第13.8節的規定,檢查調用者是否可以使用給定的方法訪問提供的“ Web資源”。 如果Web資源未受保護(約束),或者當Web資源受角色保護且呼叫者處於該角色時,則呼叫者有權訪問。

請參閱: SecurityContext#hasAccessToWebResource

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM