/** Basic constructor, should be run automatically by Tapestry. */
  public PortalSecurityManagerImpl() throws IOException {
    // Get system configuration
    config = new JsonSimpleConfig();

    // For all SSO providers configured
    sso = new LinkedHashMap<String, SSOInterface>();
    for (String ssoId : config.getStringList("sso", "plugins")) {
      // Instantiate from the ServiceLoader
      SSOInterface valid = getSSOProvider(ssoId);
      if (valid == null) {
        log.error("Invalid SSO Implementation requested: '{}'", ssoId);
      } else {
        // Store valid implementations
        sso.put(ssoId, valid);
        log.info("SSO Provider instantiated: '{}'", ssoId);
      }
    }

    defaultPortal = config.getString(PortalManager.DEFAULT_PORTAL_NAME, "portal", "defaultView");
    serverUrlBase = config.getString(null, "urlBase");
    ssoLoginUrl = serverUrlBase + defaultPortal + SSO_LOGIN_PAGE;

    // Get exclusions Strings from config
    excStarts = config.getStringList("sso", "urlExclusions", "startsWith");
    excEnds = config.getStringList("sso", "urlExclusions", "endsWith");
    excEquals = config.getStringList("sso", "urlExclusions", "equals");

    // Trust tokens
    Map<String, JsonSimple> tokenMap = config.getJsonSimpleMap("sso", "trustTokens");
    tokens = new HashMap<String, String>();
    tokenExpiry = new HashMap<String, Long>();
    for (String key : tokenMap.keySet()) {
      JsonSimple tok = tokenMap.get(key);
      String publicKey = tok.getString(null, "publicKey");
      String privateKey = tok.getString(null, "privateKey");
      String expiry = tok.getString(TRUST_TOKEN_EXPIRY, "expiry");
      if (publicKey != null && privateKey != null) {
        // Valid key
        tokens.put(publicKey, privateKey);
        tokenExpiry.put(publicKey, Long.valueOf(expiry));
      } else {
        log.error("Invalid token data: '{}'", key);
      }
    }
  }