2011-02-03 2 views
13

Я использую CAS с обработчиком проверки подлинности JDBC и задавался вопросом, возможно ли получить другие атрибуты основного объекта (например, firstname, lastname) не только имя пользователя из CAS после успешной аутентификации ?Получение дополнительных атрибутов из CAS, а не только идентификатор пользователя

+1

Вы можете взглянуть на это сообщение в блоге: http://beansgocrazy.blogspot.com.au/2012/05/cas-attribute-release-backed-by.html – n0rm1e

ответ

2

Я только что провел последние три дня, пытаясь правильно настроить CAS. Одна из проблем, с которыми я столкнулась, заключалась в том, что я должен был явно указать CAS для публикации свойств. Я сделал это:

  1. открытия https://localhost/cas/services
  2. собирается на вкладку «Управление службами»
  3. нажмите «Изменить» для каждого сервиса
  4. выделить свойства, которые вы хотите опубликовать
  5. нажмите сохранить кнопка

FWIW, другая проблема заключается в том, что casServiceValidationSuccess.jsp содержит любой код для передачи свойств обратно в r esponse. Я искал решение этого вопроса, когда нашел свой вопрос. Я замечаю, что вы переписали свою реализацию.

+0

Привет, Фарон, я использовал maven war 2 для установки CAS, и он так и не показал, что я мог бы публиковать атрибуты через интерфейс служб, и именно поэтому мне пришлось переписать. Я думаю, вы можете воспользоваться SAML2.0, чтобы получить ответ от CAS о дополнительных атрибутах, которые вы опубликовали. –

+0

Спасибо за подсказку с выбором атрибутов на вкладке сервиса - это был шаг, который я не осознал, был необходим –

+0

Спасибо за отзыв о 'casServiceValidationSuccess.jsp'. По-видимому, это необходимо для передачи атрибутов в phpCAS. – Nic

11

В casServiceValidationSuccess.jsp, я добавляю, как показано ниже:

<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> 

В deployerConfigContent.xml, я добавляю, как показано ниже:

<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> 

Он работает.
Я столкнулся с этой проблемой во время отладки, пожалуйста, закройте браузер, если вы измените этот JSP или XML-файл, иначе изменения не будут работать. Быть осторожен.

+0

см. Также: [/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), вы можете использовать его для наложения [/WEB-INF/view/jsp/protocol/2.0/casServiceValidationSuccess.jsp](https://github .com/Jasig/КАС/блоб/4.0.x/КАС-сервера веб-приложение/SRC/Главный/WebApp/WEB-INF/просмотр/JSP/протокол/2.0/casServiceValidationSuccess.jsp) – btpka3

1

Окончательное и полное решение состоит в следующем (для этой функции недокументированного):

  1. стороне сервера:

    а. Добавьте attributeRepository в ваш CredentialsToPrincipalResolver.

    b. Внесите your.package.YourPersonAttributeDao, как IPersonAttributeDao.

    c. Объявите атрибуты, которые будут переданы в утверждение клиенту.

    d. Измените значение casServiceValidationSuccess.jsp, чтобы отобразить атрибуты (thx to xiongjiabin).

  2. Сторона клиента. Вы получаете все атрибуты, выполнив следующие действия:

    Из-за проблемы с форматированием я не могу опубликовать код окончательного решения .... Сообщите мне, если вы заинтересованы, я пришлю вам письмо со всеми код.

+0

Я разрешаю CAS иметь поддержку OAuth Client, он отлично работает, теперь мне нужно, чтобы все атрибуты пользователя регистрировались через Facebook и добавляли одного и того же пользователя в мое веб-приложение, пожалуйста, пришлите мне код и какие-либо подсказки мой почтовый идентификатор [email protected] –

1

В дополнение к ответу, предоставленной @xiongjiabin, если вы используете CAS v4 + вы, вероятно, хотите использовать assertion.primaryAuthentication вместо assertion.chainedAuthentications в 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> 

Если вы используете assertion.chainedAuthentications с CAS v4 +, то список serviceRegistryDao из allowedAttributes будет проигнорирован и все атрибуты будут возвращены.

+0

Если вы используете CAS v4 +, вы можете использовать конечную точку/p3/serviceValidate, и у нее есть атрибуты, уже включенные в casServiceValidationSuccess.jsp – REW

+0

. Этот ответ замечательный, если вы обновляетесь с CAS 3.x до 4.x, и большинство ваших клиентов все еще используют протокол CAS 2.0. Если у вас есть новые клиенты и запущена CAS 4.x, вы можете порекомендовать использовать конечную точку протокола CAS 3.0. – acvcu

3

Чтобы получить любые атрибуты пользователей из БД я сделал следующее: использование PersonDirectoryPrincipalResolver

в deployerConfigContext.xml:

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

вместо того, чтобы использовать стандартный класс SingleRowJdbcPersonAttributeDao создать свою собственную реализацию, которая возвращает не только один строка из результата запроса, но агрегированные данные из всех возвращенных строк:

копию всего кода с SingleRowJdbcPersonAttributeDao и изменение только одним способом parseAttributeMapFromResults. вы будете иметь что-то вроде этого:

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; 
    } 

    ... 
} 

и в 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> 

Кроме того, в моем случае я использовал протокол SAML.

В результате вы получите на клиенте все атрибуты, которые ваш выбор возвращает. Например, если пользователь имеет много ролей, вы могли бы иметь на клиенте:

пользователя: имя пользователя, Имя, фамилия, адрес электронной почты, ..., [ROLE_1, ROLE_2, ROLE_3]

Мой случай работает с весны Безопасность и Грайлы.

Я не уверен, что это 100% решение фэн-шуй :), поскольку оно быстро приготовлено, но оно работает в нашем случае.

Надеюсь, это поможет.