2011-02-03 10 views
13

Estoy usando CAS con controlador de autenticación JDBC y me preguntaba si es posible obtener los otros atributos del objeto principal (por ejemplo, nombre, apellido) no solo el nombre de usuario de CAS después de una autenticación exitosa ?Obteniendo más atributos de CAS que simplemente identificación de usuario

+1

Quizás quiera echar un vistazo a esta publicación en el blog: http://beansgocrazy.blogspot.com.au/2012/05/cas-attribute-release-backed-by.html – n0rm1e

Respuesta

2

Acabo de pasar los últimos tres días tratando de configurar CAS correctamente. Uno de los problemas que encontré fue que tuve que instruir explícitamente a CAS para publicar las propiedades. Hice esto por:

  1. apertura https://localhost/cas/services
  2. ir a la pestaña 'Administrar servicios'
  3. clic en 'editar' para cada servicio
  4. resaltar las propiedades que desea publicar
  5. Haga clic en Guardar botón

FWIW, el otro problema es que casServiceValidationSuccess.jsp contiene cualquier código para pasar las propiedades de nuevo en el r respuesta Estaba buscando una solución para esto cuando encontré tu pregunta. Noté que ha reescrito su implementación.

+0

Hola Faron, había usado el maven war 2 overlay para instalar el CAS y no mostró de todos modos por qué podía publicar los atributos a través de la interfaz de servicios y es por eso que tuve que reescribir. Creo que puede beneficiarse de usar un SAML2.0 para obtener la respuesta de CAS sobre los atributos adicionales que ha publicado. –

+0

Gracias por la sugerencia con la selección de los atributos en la pestaña de servicio; ese fue un paso que no me había dado cuenta de que era necesario –

+0

Gracias por la sugerencia sobre 'casServiceValidationSuccess.jsp'. Aparentemente eso es necesario para pasar atributos a phpCAS. – Nic

11

En el casServiceValidationSuccess.jsp, añado, como a continuación:

<cas:attributes> 

    <c:forEach var="attr" items="${assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes}"> 
     **<cas:${fn:escapeXml(attr.key)}>${fn:escapeXml(attr.value)}</cas:${fn:escapeXml(attr.key)}>** 
    </c:forEach> 

</cas:attributes> 

En el deployerConfigContent.xml, añado, como a continuación:

<bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" > 

    **<property name="attributeRepository"> 
    <ref bean="attributeRepository" /> 
    </property>** 

</bean> 

<bean id="attributeRepository" class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao"> 

    <constructor-arg index="0" ref="dataSource"/> 
    <constructor-arg index="1" value="select * from bbs_members where {0}" /> 
    <property name="queryAttributeMapping"> 
     <map> 
      <entry key="username" value="username" /> 
     </map> 
    </property> 

    <property name="resultAttributeMapping"> 
     <map> 
      <entry key="uid" value="uid"/> 
      <entry key="email" value="email"/> 
      <entry key="password" value="password"/> 
     </map> 
    </property> 
</bean> 

Funciona.
Me encontré con este problema durante la depuración, cierre el navegador si cambia estos archivos JSP o XML; de lo contrario, los cambios no funcionarán. Ten cuidado.

+0

vea también: [/WEB-INF/view/jsp/protocol/3.0/casServiceValidationSuccess.jsp](https://github.com/Jasig/cas/blob/4.0.x/cas-server-webapp/src/main /webapp/WEB-INF/view/jsp/protocol/3.0/casServiceValidationSuccess.jsp), puede usarlo para superponer [/WEB-INF/view/jsp/protocol/2.0/casServiceValidationSuccess.jsp](https://github .com/Jasig/cas/blob/4.0.x/cas-server-webapp/src/main/webapp/WEB-INF/view/jsp/protocol/2.0/casServiceValidationSuccess.jsp) – btpka3

1

La solución definitiva y completa es la siguiente (para esta característica no documentada):

  1. lado del servidor:

    a. Agregue attributeRepository a su CredentialsToPrincipalResolver.

    b. Implemente el your.package.YourPersonAttributeDao como IPersonAttributeDao.

    c. Declare los atributos que se transmitirán en assertion al cliente.

    d. Modifique casServiceValidationSuccess.jsp para mostrar los atributos (thx a xiongjiabin).

  2. Lado del cliente. Obtiene todos los atributos al hacer esto:

    Debido a un problema de formato, no puedo publicar el código de la solución definitiva ... Háganme saber si está interesado, le enviaré un correo electrónico con todas las código.

+0

Autoricé a CAS para que tenga soporte para clientes de OAuth, está funcionando bien, ahora lo que necesito es tener todos los atributos del usuario para iniciar sesión en Facebook y agregar el mismo usuario a mi aplicación web, por favor envíeme el código y cualquier consejo para mi ID de correo [email protected] –

1

Además de la respuesta proporcionada por @xiongjiabin si está utilizando v4 CAS + es probable que desee utilizar assertion.primaryAuthentication en lugar de assertion.chainedAuthentications en casServiceValidationSuccess.jsp:

<cas:attributes> 
    <c:forEach var="attr" items="${assertion.primaryAuthentication.principal.attributes}"> 
     <cas:${fn:escapeXml(attr.key)}>${fn:escapeXml(attr.value)}</cas:${fn:escapeXml(attr.key)}>** 
    </c:forEach> 
</cas:attributes> 

Si utiliza assertion.chainedAuthentications con CAS v4 + luego se ignorará la lista serviceRegistryDao de allowedAttributes y se devolverán todos los atributos.

+0

Si usa CAS v4 + puede usar el punto final/p3/serviceValidate y tiene los atributos ya incluidos en casServiceValidationSuccess.jsp – REW

+0

Esta respuesta es excelente para saber si está actualizando desde CAS 3.x a 4.x y la mayoría de sus clientes todavía usan el protocolo CAS 2.0. Si tiene clientes nuevos y ejecuta CAS 4.x, puede recomendar que utilicen el punto final del protocolo CAS 3.0. – acvcu

3

Para obtener los atributos de cualquier usuario de DB hice lo siguiente: uso PersonDirectoryPrincipalResolver

en deployerConfigContext.xml:

<bean id="primaryPrincipalResolver" 
     class="org.jasig.cas.authentication.principal.PersonDirectoryPrincipalResolver" > 
    <property name="attributeRepository" ref="singleRowJdbcPersonMultiplyAttributeDao" /> 
</bean> 

en lugar de utilizar clase estándar SingleRowJdbcPersonAttributeDao crear su propia aplicación que devuelve no sólo uno fila de un resultado de consulta pero datos agregados de todas las filas devueltas:

copie todo el código de SingleRowJdbcPersonAttributeDao y cambie solo un método parseAttributeMapFromResults. tendrá algo así:

public class SingleRowJdbcPersonMultiplyAttributeDao extends AbstractJdbcPersonAttributeDao<Map<String, Object>> { 
    ... 

    @Override 
    protected List<IPersonAttributes> parseAttributeMapFromResults(final List<Map<String, Object>> queryResults, final String queryUserName) { 
     final List<IPersonAttributes> peopleAttributes = new ArrayList<IPersonAttributes>(queryResults.size()); 
     Map<String, List<Object>> attributes = new HashMap<String, List<Object>>(); 

     for (final Map<String, Object> queryResult : queryResults) { 

      for (final Map.Entry<String, Object> seedEntry : queryResult.entrySet()) { 
       final String seedName = seedEntry.getKey(); 
       final Object seedValue = seedEntry.getValue(); 

       if (attributes.get(seedName) != null && !attributes.get(seedName).get(0).equals(seedValue)) { 
        attributes.get(seedName).add(seedValue); 
       } else { 
        List<Object> list = new ArrayList<Object>(); 
        list.add(seedValue); 
        attributes.put(seedName, list); 
       } 

      } 
     } 

     final IPersonAttributes person; 
     final String userNameAttribute = this.getConfiguredUserNameAttribute(); 
     if (this.isUserNameAttributeConfigured() && attributes.containsKey(userNameAttribute)) { 
      // Option #1: An attribute is named explicitly in the config, 
      // and that attribute is present in the results from LDAP; use it 
      person = new CaseInsensitiveAttributeNamedPersonImpl(userNameAttribute, attributes); 
     } else if (queryUserName != null) { 
      // Option #2: Use the userName attribute provided in the query 
      // parameters. (NB: I'm not entirely sure this choice is 
      // preferable to Option #3. Keeping it because it most closely 
      // matches the legacy behavior there the new option -- Option #1 
      // -- doesn't apply. ~drewwills) 
      person = new CaseInsensitiveNamedPersonImpl(queryUserName, attributes); 
     } else { 
      // Option #3: Create the IPersonAttributes doing a best-guess 
      // at a userName attribute 
      person = new CaseInsensitiveAttributeNamedPersonImpl(userNameAttribute, attributes); 
     } 

     peopleAttributes.add(person); 
     return peopleAttributes; 
    } 

    ... 
} 

y en deployerConfigContext.xml:

<bean id="singleRowJdbcPersonMultiplyAttributeDao" 
      class="com.scentbird.SingleRowJdbcPersonMultiplyAttributeDao"> 
     <constructor-arg index="0" ref="dataSource" /> 
     <constructor-arg index="1" value="SELECT attributes_table1.*, attributes_table2.attr1, attributes_table2.roles AS roles FROM user_table ut LEFT JOIN roles_table rt ON <condition> LEFT JOIN another_table at ON <condition> WHERE {0}" /> 
    <property name="queryAttributeMapping"> 
     <map> 
      <entry key="username" value="username" /> 
     </map> 
    </property> 
</bean> 

También en mi caso he utilizado el protocolo SAML.

Como resultado, obtendrá en el cliente todos los atributos que su selección devuelve. Por ejemplo, si el usuario tiene muchos papeles que podría tener en el cliente:

usuario: nombre de usuario, nombre, apellido, correo electrónico, ..., [ROLE_1, ROLE_2, ROLE_3]

Mi caso trabaja con la primavera Seguridad y Grails.

No estoy seguro de que esto sea 100% Feng Shui solución :) ya que es rápido pero funciona en nuestro caso.

Espero que ayude.

Cuestiones relacionadas