View Javadoc

    1   /*
    2    * Copyright 2009 University Corporation for Advanced Internet Development, Inc.
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    * http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16
    17  package edu.internet2.middleware.shibboleth.idp.util;
    18
    19  import java.util.UUID;
    20
    21  import javax.servlet.ServletContext;
    22  import javax.servlet.http.Cookie;
    23  import javax.servlet.http.HttpServletRequest;
    24  import javax.servlet.http.HttpServletResponse;
    25
    26  import org.opensaml.saml2.metadata.EntityDescriptor;
    27  import org.opensaml.saml2.metadata.provider.MetadataProviderException;
    28  import org.opensaml.util.storage.StorageService;
    29  import org.opensaml.xml.util.DatatypeHelper;
    30  import org.slf4j.Logger;
    31  import org.slf4j.LoggerFactory;
    32
    33  import edu.internet2.middleware.shibboleth.common.attribute.filtering.AttributeFilteringEngine;
    34  import edu.internet2.middleware.shibboleth.common.attribute.provider.SAML1AttributeAuthority;
    35  import edu.internet2.middleware.shibboleth.common.attribute.provider.SAML2AttributeAuthority;
    36  import edu.internet2.middleware.shibboleth.common.attribute.resolver.AttributeResolver;
    37  import edu.internet2.middleware.shibboleth.common.relyingparty.RelyingPartyConfigurationManager;
    38  import edu.internet2.middleware.shibboleth.common.relyingparty.provider.SAMLMDRelyingPartyConfigurationManager;
    39  import edu.internet2.middleware.shibboleth.common.session.SessionManager;
    40  import edu.internet2.middleware.shibboleth.idp.authn.LoginContext;
    41  import edu.internet2.middleware.shibboleth.idp.authn.LoginContextEntry;
    42  import edu.internet2.middleware.shibboleth.idp.profile.IdPProfileHandlerManager;
    43  import edu.internet2.middleware.shibboleth.idp.session.Session;
    44
    45  /** A helper class that provides access to internal state from Servlets and hence also JSPs. */
    46  public class HttpServletHelper {
    47
    48      /** Name of the cookie containing the IdP session ID: {@value} . */
    49      public static final String IDP_SESSION_COOKIE = "_idp_session";
    50
    51      /** Name of the key to the current authentication login context: {@value} . */
    52      public static final String LOGIN_CTX_KEY_NAME = "_idp_authn_lc_key";
    53
    54      /** {@link ServletContext} parameter name bearing the ID of the {@link AttributeFilteringEngine} service: {@value} . */
    55      public static final String ATTRIBUTE_FILTER_ENGINE_SID_CTX_PARAM = "AttributeFilterEngineId";
    56
    57      /** {@link ServletContext} parameter name bearing the ID of the {@link AttributeResolver} service: {@value} . */
    58      public static final String ATTRIBUTE_RESOLVER_SID_CTX_PARAM = "AttributeResolverId";
    59
    60      /**
    61       * {@link ServletContext} parameter name bearing the name of the {@link StorageService} partition into which
    62       * {@link LoginContext}s are stored: {@value} .
    63       */
    64      public static final String LOGIN_CTX_PARTITION_CTX_PARAM = "loginContextPartitionName";
    65
    66      /** {@link ServletContext} parameter name bearing the ID of the {@link IdPProfileHandlerManager} service: {@value} . */
    67      public static final String PROFILE_HANDLER_MNGR_SID_CTX_PARAM = "ProfileHandlerMngrId";
    68
    69      /**
    70       * {@link ServletContext} parameter name bearing the ID of the {@link RelyingPartyConfigurationManager} service: * *
    71       * * {@value} .
    72       */
    73      public static final String RP_CONFIG_MNGR_SID_CTX_PARAM = "RelyingPartyConfigurationManagerId";
    74
    75      /** {@link ServletContext} parameter name bearing the ID of the {@link SAML1AttributeAuthority} service: {@value} . */
    76      public static final String SAML1_AA_SID_CTX_PARAM = "SAML1AttributeAuthorityId";
    77
    78      /** {@link ServletContext} parameter name bearing the ID of the {@link SAML2AttributeAuthority} service: {@value} . */
    79      public static final String SAML2_AA_SID_CTX_PARAM = "SAML2AttributeAuthorityId";
    80
    81      /** {@link ServletContext} parameter name bearing the ID of the {@link SessionManager} service: {@value} . */
    82      public static final String SESSION_MNGR_SID_CTX_PARAM = "SessionManagerId";
    83
    84      /** {@link ServletContext} parameter name bearing the ID of the {@link SAML1AttributeAuthority} service: {@value} . */
    85      public static final String STORAGE_SERVICE_SID_CTX_PARAM = "StorageServiceId";
    86
    87      /** Default ID by which the {@link AttributeFilteringEngine} is know within the Servlet context: {@value} . */
    88      public static final String DEFAULT_ATTRIBUTE_FILTER_ENGINE_SID = "shibboleth.AttributeFilterEngine";
    89
    90      /** Default ID by which the {@link AttributeResolver} is know within the Servlet context: {@value} . */
    91      public static final String DEFAULT_ATTRIBUTE_RESOLVER_SID = "shibboleth.AttributeResolver";
    92
    93      /** Default name for the {@link StorageService} partition which holds {@link LoginContext}s: {@value} . */
    94      public static final String DEFAULT_LOGIN_CTX_PARITION = "loginContexts";
    95
    96      /** Default ID by which the {@link IdPProfileHandlerManager} is know within the Servlet context: {@value} . */
    97      public static final String DEFAULT_PROFILE_HANDLER_MNGR_SID = "shibboleth.HandlerManager";
    98
    99      /** Default ID by which the {@link RelyingPartyConfigurationManager} is know within the Servlet context: {@value} . */
    100     public static final String DEFAULT_RP_CONFIG_MNGR_SID = "shibboleth.RelyingPartyConfigurationManager";
    101
    102     /** Default ID by which the {@link SAML1AttributeAuthority} is know within the Servlet context: {@value} . */
    103     public static final String DEFAULT_SAML1_AA_SID = "shibboleth.SAML1AttributeAuthority";
    104
    105     /** Default ID by which the {@link SAML2AttributeAuthority} is know within the Servlet context: {@value} . */
    106     public static final String DEFAULT_SAML2_AA_SID = "shibboleth.SAML2AttributeAuthority";
    107
    108     /** Default ID by which the {@link SessionManager} is know within the Servlet context: {@value} . */
    109     public static final String DEFAULT_SESSION_MNGR_SID = "shibboleth.SessionManager";
    110
    111     /** Default ID by which the {@link StorageService} is know within the Servlet context: {@value} . */
    112     public static final String DEFAULT_STORAGE_SERVICE_SID = "shibboleth.StorageService";
    113
    114     /** Class logger. */
    115     private static final Logger log = LoggerFactory.getLogger(HttpServletHelper.class);
    116
    117     /**
    118      * Binds a {@link LoginContext} to the current request.
    119      *
    120      * @param loginContext login context to be bound
    121      * @param httpRequest current HTTP request
    122      */
    123     public static void bindLoginContext(LoginContext loginContext, HttpServletRequest httpRequest) {
    124         if (httpRequest == null) {
    125             throw new IllegalArgumentException("HTTP request may not be null");
    126         }
    127         httpRequest.setAttribute(LOGIN_CTX_KEY_NAME, loginContext);
    128     }
    129
    130     /**
    131      * Binds a {@link LoginContext} to the issuer of the current request. The binding is done by creating a random UUID,
    132      * placing that in a cookie in the request, and storing the context in to the storage service under that key.
    133      *
    134      * @param loginContext the login context to be bound
    135      * @param storageService the storage service which will hold the context
    136      * @param context the Servlet context
    137      * @param httpRequest the current HTTP request
    138      * @param httpResponse the current HTTP response
    139      */
    140     public static void bindLoginContext(LoginContext loginContext, StorageService storageService,
    141             ServletContext context, HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
    142         if (storageService == null) {
    143             throw new IllegalArgumentException("Storage service may not be null");
    144         }
    145         if (httpRequest == null) {
    146             throw new IllegalArgumentException("HTTP request may not be null");
    147         }
    148         if (loginContext == null) {
    149             return;
    150         }
    151
    152         bindLoginContext(loginContext, httpRequest);
    153
    154         String parition = getContextParam(context, LOGIN_CTX_PARTITION_CTX_PARAM, DEFAULT_LOGIN_CTX_PARITION);
    155         log.debug("LoginContext parition: {}", parition);
    156
    157         String contextKey = UUID.randomUUID().toString();
    158         while (storageService.contains(parition, contextKey)) {
    159             contextKey = UUID.randomUUID().toString();
    160         }
    161         log.debug("LoginContext key: {}", contextKey);
    162
    163         LoginContextEntry entry = new LoginContextEntry(loginContext, 1800000);
    164         storageService.put(parition, contextKey, entry);
    165
    166         Cookie contextKeyCookie = new Cookie(LOGIN_CTX_KEY_NAME, contextKey);
    167         contextKeyCookie.setVersion(1);
    168         contextKeyCookie.setPath(httpRequest.getContextPath() == "" ? "/" : httpRequest.getContextPath());
    169         contextKeyCookie.setSecure(httpRequest.isSecure());
    170         httpResponse.addCookie(contextKeyCookie);
    171     }
    172
    173     /**
    174      * Gets the {@link AttributeFilteringEngine} service bound to the Servlet context.
    175      *
    176      * @param context the Servlet context
    177      *
    178      * @return the service or null if there is no such service bound to the context
    179      */
    180     public static AttributeFilteringEngine<?> getAttributeFilterEnginer(ServletContext context) {
    181         return getAttributeFilterEnginer(context, getContextParam(context, ATTRIBUTE_FILTER_ENGINE_SID_CTX_PARAM,
    182                 DEFAULT_ATTRIBUTE_FILTER_ENGINE_SID));
    183     }
    184
    185     /**
    186      * Gets the {@link AttributeFilteringEngine} bound to the Servlet context.
    187      *
    188      * @param context the Servlet context
    189      * @param serviceId the ID under which the service bound
    190      *
    191      * @return the service or null if there is no such service bound to the context
    192      */
    193     public static AttributeFilteringEngine<?> getAttributeFilterEnginer(ServletContext context, String serviceId) {
    194         return (AttributeFilteringEngine<?>) context.getAttribute(serviceId);
    195     }
    196
    197     /**
    198      * Gets the {@link AttributeResolver} service bound to the Servlet context.
    199      *
    200      * @param context the Servlet context
    201      *
    202      * @return the service or null if there is no such service bound to the context
    203      */
    204     public static AttributeResolver<?> getAttributeResolver(ServletContext context) {
    205         return getAttributeResolver(context, getContextParam(context, ATTRIBUTE_RESOLVER_SID_CTX_PARAM,
    206                 DEFAULT_ATTRIBUTE_RESOLVER_SID));
    207     }
    208
    209     /**
    210      * Gets the {@link AttributeResolver} bound to the Servlet context.
    211      *
    212      * @param context the Servlet context
    213      * @param serviceId the ID under which the service bound
    214      *
    215      * @return the service or null if there is no such service bound to the context
    216      */
    217     public static AttributeResolver<?> getAttributeResolver(ServletContext context, String serviceId) {
    218         return (AttributeResolver<?>) context.getAttribute(serviceId);
    219     }
    220
    221     /**
    222      * Gets a value for a given context parameter. If no value is present the default value is used.
    223      *
    224      * @param context the Servlet context
    225      * @param name name of the context parameter
    226      * @param defaultValue default value of the parameter
    227      *
    228      * @return the value of the context parameter or the default value if the parameter is not set or does not contain a
    229      *         value
    230      */
    231     public static String getContextParam(ServletContext context, String name, String defaultValue) {
    232         String value = DatatypeHelper.safeTrimOrNullString(context.getInitParameter(name));
    233         if (value == null) {
    234             value = defaultValue;
    235         }
    236         return value;
    237     }
    238
    239     /**
    240      * Gets the first {@link Cookie} whose name matches the given name.
    241      *
    242      * @param cookieName the cookie name
    243      * @param httpRequest HTTP request from which the cookie should be extracted
    244      *
    245      * @return the cookie or null if no cookie with that name was given
    246      */
    247     public static Cookie getCookie(HttpServletRequest httpRequest, String cookieName) {
    248         Cookie[] requestCookies = httpRequest.getCookies();
    249         if (requestCookies != null) {
    250             for (Cookie requestCookie : requestCookies) {
    251                 if (requestCookie != null && DatatypeHelper.safeEquals(requestCookie.getName(), cookieName)) {
    252                     return requestCookie;
    253                 }
    254             }
    255         }
    256
    257         return null;
    258     }
    259
    260     /**
    261      * Gets the login context from the current request. The login context is only in this location while the request is
    262      * being transferred from the authentication engine back to the profile handler.
    263      *
    264      * @param httpRequest current HTTP request
    265      *
    266      * @return the login context or null if no login context is bound to the request
    267      */
    268     public static LoginContext getLoginContext(HttpServletRequest httpRequest) {
    269         return (LoginContext) httpRequest.getAttribute(LOGIN_CTX_KEY_NAME);
    270     }
    271
    272     /**
    273      * Gets the {@link LoginContext} for the user issuing the HTTP request. Note, login contexts are only available
    274      * during the authentication process.
    275      *
    276      * @param context the Servlet context
    277      * @param storageService storage service to use when retrieving the login context
    278      * @param httpRequest current HTTP request
    279      *
    280      * @return the login context or null if none is available
    281      */
    282     public static LoginContext getLoginContext(StorageService storageService, ServletContext context,
    283             HttpServletRequest httpRequest) {
    284         if (storageService == null) {
    285             throw new IllegalArgumentException("Storage service may not be null");
    286         }
    287         if (context == null) {
    288             throw new IllegalArgumentException("Servlet context may not be null");
    289         }
    290         if (httpRequest == null) {
    291             throw new IllegalArgumentException("HTTP request may not be null");
    292         }
    293
    294         LoginContext loginContext = getLoginContext(httpRequest);
    295         if (loginContext == null) {
    296             log.debug("LoginContext not bound to HTTP request, retrieving it from storage service");
    297             Cookie loginContextKeyCookie = getCookie(httpRequest, LOGIN_CTX_KEY_NAME);
    298             if (loginContextKeyCookie == null) {
    299                 log.debug("LoginContext key cookie was not present in request");
    300                 return null;
    301             }
    302
    303             String loginContextKey = DatatypeHelper.safeTrimOrNullString(loginContextKeyCookie.getValue());
    304             if (loginContextKey == null) {
    305                 log.warn("Corrupted LoginContext Key cookie, it did not contain a value");
    306             }
    307             log.debug("LoginContext key is '{}'", loginContextKey);
    308
    309             String partition = getContextParam(context, LOGIN_CTX_PARTITION_CTX_PARAM, DEFAULT_LOGIN_CTX_PARITION);
    310             log.debug("parition: {}", partition);
    311             LoginContextEntry entry = (LoginContextEntry) storageService.get(partition, loginContextKey);
    312             if (entry != null) {
    313                 if (entry.isExpired()) {
    314                     log.debug("LoginContext found but it was expired");
    315                 } else {
    316                     loginContext = entry.getLoginContext();
    317                 }
    318             } else {
    319                 log.debug("No login context in storage service");
    320             }
    321         }
    322
    323         return loginContext;
    324     }
    325
    326     /**
    327      * Gets the {@link IdPProfileHandlerManager} service bound to the Servlet context.
    328      *
    329      * @param context the Servlet context
    330      *
    331      * @return the service or null if there is no such service bound to the context
    332      */
    333     public static IdPProfileHandlerManager getProfileHandlerManager(ServletContext context) {
    334         return getProfileHandlerManager(context, getContextParam(context, PROFILE_HANDLER_MNGR_SID_CTX_PARAM,
    335                 DEFAULT_PROFILE_HANDLER_MNGR_SID));
    336     }
    337
    338     /**
    339      * Gets the {@link IdPProfileHandlerManager} bound to the Servlet context.
    340      *
    341      * @param context the Servlet context
    342      * @param serviceId the ID under which the service bound
    343      *
    344      * @return the service or null if there is no such service bound to the context
    345      */
    346     public static IdPProfileHandlerManager getProfileHandlerManager(ServletContext context, String serviceId) {
    347         return (IdPProfileHandlerManager) context.getAttribute(serviceId);
    348     }
    349
    350     /**
    351      * Gets the {@link RelyingPartyConfigurationManager} service bound to the Servlet context.
    352      *
    353      * @param context the Servlet context
    354      *
    355      * @return the service or null if there is no such service bound to the context
    356      */
    357     public static RelyingPartyConfigurationManager getRelyingPartyConfirmationManager(ServletContext context) {
    358         return getRelyingPartyConfirmationManager(context, getContextParam(context, RP_CONFIG_MNGR_SID_CTX_PARAM,
    359                 DEFAULT_RP_CONFIG_MNGR_SID));
    360     }
    361
    362     /**
    363      * Gets the {@link RelyingPartyConfigurationManager} bound to the Servlet context.
    364      *
    365      * @param context the Servlet context
    366      * @param serviceId the ID under which the service bound
    367      *
    368      * @return the service or null if there is no such service bound to the context
    369      */
    370     public static RelyingPartyConfigurationManager getRelyingPartyConfirmationManager(ServletContext context,
    371             String serviceId) {
    372         return (RelyingPartyConfigurationManager) context.getAttribute(serviceId);
    373     }
    374
    375     /**
    376      * Gets the metatdata for a given relying party.
    377      *
    378      * @param relyingPartyEntityId the ID of the relying party
    379      * @param rpConfigMngr relying party configuration manager
    380      *
    381      * @return the metadata for the relying party or null if no SAML metadata exists for the given relying party
    382      */
    383     public static EntityDescriptor getRelyingPartyMetadata(String relyingPartyEntityId,
    384             RelyingPartyConfigurationManager rpConfigMngr) {
    385         if (rpConfigMngr instanceof SAMLMDRelyingPartyConfigurationManager) {
    386             SAMLMDRelyingPartyConfigurationManager samlRpConfigMngr = (SAMLMDRelyingPartyConfigurationManager) rpConfigMngr;
    387             try {
    388                 return samlRpConfigMngr.getMetadataProvider().getEntityDescriptor(relyingPartyEntityId);
    389             } catch (MetadataProviderException e) {
    390
    391             }
    392         }
    393
    394         return null;
    395     }
    396
    397     /**
    398      * Gets the {@link SAML1AttributeAuthority} service bound to the Servlet context.
    399      *
    400      * @param context the Servlet context
    401      *
    402      * @return the service or null if there is no such service bound to the context
    403      */
    404     public static SAML1AttributeAuthority getSAML1AttributeAuthority(ServletContext context) {
    405         return getSAML1AttributeAuthority(context, getContextParam(context, SAML1_AA_SID_CTX_PARAM,
    406                 DEFAULT_SAML1_AA_SID));
    407     }
    408
    409     /**
    410      * Gets the {@link SAML1AttributeAuthority} bound to the Servlet context.
    411      *
    412      * @param context the Servlet context
    413      * @param serviceId the ID under which the service bound
    414      *
    415      * @return the service or null if there is no such service bound to the context
    416      */
    417     public static SAML1AttributeAuthority getSAML1AttributeAuthority(ServletContext context, String serviceId) {
    418         return (SAML1AttributeAuthority) context.getAttribute(serviceId);
    419     }
    420
    421     /**
    422      * Gets the {@link SAML2AttributeAuthority} service bound to the Servlet context.
    423      *
    424      * @param context the Servlet context
    425      *
    426      * @return the service or null if there is no such service bound to the context
    427      */
    428     public static SAML2AttributeAuthority getSAML2AttributeAuthority(ServletContext context) {
    429         return getSAML2AttributeAuthority(context, getContextParam(context, SAML2_AA_SID_CTX_PARAM,
    430                 DEFAULT_SAML2_AA_SID));
    431     }
    432
    433     /**
    434      * Gets the {@link SAML2AttributeAuthority} bound to the Servlet context.
    435      *
    436      * @param context the Servlet context
    437      * @param serviceId the ID under which the service bound
    438      *
    439      * @return the service or null if there is no such service bound to the context
    440      */
    441     public static SAML2AttributeAuthority getSAML2AttributeAuthority(ServletContext context, String serviceId) {
    442         return (SAML2AttributeAuthority) context.getAttribute(serviceId);
    443     }
    444
    445     /**
    446      * Gets the {@link SessionManager} service bound to the Servlet context.
    447      *
    448      * @param context the Servlet context
    449      *
    450      * @return the service or null if there is no such service bound to the context
    451      */
    452     public static SessionManager<Session> getSessionManager(ServletContext context) {
    453         return getSessionManager(context,
    454                 getContextParam(context, SESSION_MNGR_SID_CTX_PARAM, DEFAULT_SESSION_MNGR_SID));
    455     }
    456
    457     /**
    458      * Gets the {@link SessionManager} bound to the Servlet context.
    459      *
    460      * @param context the Servlet context
    461      * @param serviceId the ID under which the service bound
    462      *
    463      * @return the service or null if there is no such service bound to the context
    464      */
    465     public static SessionManager<Session> getSessionManager(ServletContext context, String serviceId) {
    466         return (SessionManager<Session>) context.getAttribute(serviceId);
    467     }
    468
    469     /**
    470      * Gets the {@link StorageService} service bound to the Servlet context.
    471      *
    472      * @param context the Servlet context
    473      *
    474      * @return the service or null if there is no such service bound to the context
    475      */
    476     public static StorageService<?, ?> getStorageService(ServletContext context) {
    477         return getStorageService(context, getContextParam(context, STORAGE_SERVICE_SID_CTX_PARAM,
    478                 DEFAULT_STORAGE_SERVICE_SID));
    479     }
    480
    481     /**
    482      * Gets the {@link StorageService} bound to the Servlet context.
    483      *
    484      * @param context the Servlet context
    485      * @param serviceId the ID under which the service bound
    486      *
    487      * @return the service or null if there is no such service bound to the context
    488      */
    489     public static StorageService<?, ?> getStorageService(ServletContext context, String serviceId) {
    490         return (StorageService<?, ?>) context.getAttribute(serviceId);
    491     }
    492
    493     /**
    494      * Gets the user session from the request. Retrieving the session in this manner does NOT update the last activity
    495      * time of the session.
    496      *
    497      * @param httpRequest current request
    498      *
    499      * @return the users session, if one exists
    500      */
    501     public static Session getUserSession(HttpServletRequest httpRequest) {
    502         return (Session) httpRequest.getAttribute(Session.HTTP_SESSION_BINDING_ATTRIBUTE);
    503     }
    504
    505     /**
    506      * Unbinds a {@link LoginContext} from the current request. The unbinding results in the destruction of the
    507      * associated context key cookie and removes the context from the storage service.
    508      *
    509      * @param storageService storage service holding the context
    510      * @param context the Servlet context
    511      * @param httpRequest current HTTP request
    512      * @param httpResponse current HTTP response
    513      *
    514      * @return the login context that was unbound or null if there was no bound context
    515      */
    516     public static LoginContext unbindLoginContext(StorageService storageService, ServletContext context,
    517             HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
    518         if (storageService == null || context == null || httpRequest == null || httpResponse == null) {
    519             return null;
    520         }
    521
    522         Cookie loginContextKeyCookie = getCookie(httpRequest, LOGIN_CTX_KEY_NAME);
    523         if (loginContextKeyCookie == null) {
    524             return null;
    525         }
    526
    527         String loginContextKey = DatatypeHelper.safeTrimOrNullString(loginContextKeyCookie.getValue());
    528         if (loginContextKey == null) {
    529             log.warn("Corrupted LoginContext Key cookie, it did not contain a value");
    530         }
    531
    532         httpRequest.setAttribute(LOGIN_CTX_KEY_NAME, null);
    533         loginContextKeyCookie.setMaxAge(0);
    534         httpResponse.addCookie(loginContextKeyCookie);
    535
    536         LoginContextEntry entry = (LoginContextEntry) storageService.remove(getContextParam(context,
    537                 LOGIN_CTX_PARTITION_CTX_PARAM, DEFAULT_LOGIN_CTX_PARITION), loginContextKey);
    538         if (entry != null && !entry.isExpired()) {
    539             return entry.getLoginContext();
    540         }
    541         return null;
    542     }
    543 }