Я использую CAS с обработчиком проверки подлинности JDBC и задавался вопросом, возможно ли получить другие атрибуты основного объекта (например, firstname, lastname) не только имя пользователя из CAS после успешной аутентификации ?Получение дополнительных атрибутов из CAS, а не только идентификатор пользователя
ответ
Я только что провел последние три дня, пытаясь правильно настроить CAS. Одна из проблем, с которыми я столкнулась, заключалась в том, что я должен был явно указать CAS для публикации свойств. Я сделал это:
- открытия https://localhost/cas/services
- собирается на вкладку «Управление службами»
- нажмите «Изменить» для каждого сервиса
- выделить свойства, которые вы хотите опубликовать
- нажмите сохранить кнопка
FWIW, другая проблема заключается в том, что casServiceValidationSuccess.jsp содержит любой код для передачи свойств обратно в r esponse. Я искал решение этого вопроса, когда нашел свой вопрос. Я замечаю, что вы переписали свою реализацию.
Привет, Фарон, я использовал maven war 2 для установки CAS, и он так и не показал, что я мог бы публиковать атрибуты через интерфейс служб, и именно поэтому мне пришлось переписать. Я думаю, вы можете воспользоваться SAML2.0, чтобы получить ответ от CAS о дополнительных атрибутах, которые вы опубликовали. –
Спасибо за подсказку с выбором атрибутов на вкладке сервиса - это был шаг, который я не осознал, был необходим –
Спасибо за отзыв о 'casServiceValidationSuccess.jsp'. По-видимому, это необходимо для передачи атрибутов в phpCAS. – Nic
В 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-файл, иначе изменения не будут работать. Быть осторожен.
см. Также: [/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
Окончательное и полное решение состоит в следующем (для этой функции недокументированного):
стороне сервера:
а. Добавьте
attributeRepository
в вашCredentialsToPrincipalResolver
.b. Внесите
your.package.YourPersonAttributeDao
, какIPersonAttributeDao
.c. Объявите атрибуты, которые будут переданы в утверждение клиенту.
d. Измените значение
casServiceValidationSuccess.jsp
, чтобы отобразить атрибуты (thx to xiongjiabin).Сторона клиента. Вы получаете все атрибуты, выполнив следующие действия:
Из-за проблемы с форматированием я не могу опубликовать код окончательного решения .... Сообщите мне, если вы заинтересованы, я пришлю вам письмо со всеми код.
Я разрешаю CAS иметь поддержку OAuth Client, он отлично работает, теперь мне нужно, чтобы все атрибуты пользователя регистрировались через Facebook и добавляли одного и того же пользователя в мое веб-приложение, пожалуйста, пришлите мне код и какие-либо подсказки мой почтовый идентификатор [email protected] –
В дополнение к ответу, предоставленной @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
будет проигнорирован и все атрибуты будут возвращены.
Если вы используете CAS v4 +, вы можете использовать конечную точку/p3/serviceValidate, и у нее есть атрибуты, уже включенные в casServiceValidationSuccess.jsp – REW
. Этот ответ замечательный, если вы обновляетесь с CAS 3.x до 4.x, и большинство ваших клиентов все еще используют протокол CAS 2.0. Если у вас есть новые клиенты и запущена CAS 4.x, вы можете порекомендовать использовать конечную точку протокола CAS 3.0. – acvcu
Чтобы получить любые атрибуты пользователей из БД я сделал следующее: использование 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% решение фэн-шуй :), поскольку оно быстро приготовлено, но оно работает в нашем случае.
Надеюсь, это поможет.
Вы можете взглянуть на это сообщение в блоге: http://beansgocrazy.blogspot.com.au/2012/05/cas-attribute-release-backed-by.html – n0rm1e