Из шага 6) клиент может получить credentials
(включая username
) из данных ответа.
credentials
, uniauth client
вызывает uniauth-server
, чтобы получить данные пользователя и все разрешения.4. Параметры конфигурации
Конфигурация находится в zookeeper путём добавления данных узла.
4.1. Основные настройки
(1) Настройки CAS:
# 是否 использовать HTTPS для записи cookie, установить значение true для производства
/com/dianrong/cfg/1.0.0/uniauth/cas_server.iscookiesecure true
# Адрес CAS, например: http://localhost:8080/cas
/com/dianrong/cfg/1.0.0/uniauth/cas_server http://localhost:8081/cas
# Настройка количества допустимых проверок билета службы CAS. По умолчанию — 2 раза. На самом деле, только одна проверка является наиболее безопасной.
/com/dianrong/cfg/1.0.0/uniauth/cas.st_use_times 2
# Установить значение true или false. Используется для указания того, требуется ли принудительная проверка доступа к запросу uniauth-сервера с информацией о клиенте.
/com/dianrong/cfg/1.0.0/uniauth/tenancyIdentity.check.switch true
# Конфигурация адреса uniauth-ws-endpoint. Например: http://localhost:8090/uniauth/ws/rs
/com/dianrong/cfg/1.0.0/uniauth/uniauth_ws_endpoint http://localhost:8090/uniauth/ws/rs
# Настройки шифрования и подписи объектов CAS и webflow. Эти настройки предназначены для обеспечения безопасности (необязательно).
Шаги:
1. Добавить четыре узла zookeeper:
/com/dianrong/cfg/1.0.0/uniauth/cas.tgc.encryption.key MvU58Xs7fOsGQL47K6AXVy7qyDzaSO7_Khh1nC5gbLo
/com/dianrong/cfg/1.0.0/uniauth/cas.tgc.signing.key 8hALJmFBEq1X4TD824cg15P5U8BjNrdoF9-XqH1KZQ8UdzFRmT_dX6Ao2M46hiCpvXRvRv-HhkQnpmPtG8oA_w
/com/dianrong/cfg/1.0.0/uniauth/cas.webflow.encryption.key C4SBogp_badO82wC
/com/dianrong/cfg/1.0.0/uniauth/cas.webflow.signing.key 8_G6JMTdkxiJ5rN0tqFrEOQj200VoxGrRzAp7bvjMFSGdA2IOzdFRsGv3m3GMNVmoSJ0O4miIBrYCHx_FWP4oQ
Эти четыре узла получают значения через следующий инструмент. Шаги:
a. git clone https://github.com/mitreid-connect/json-web-key-generator.git
b. Перейти в каталог json-web-key-generator
c. Использовать команду maven mvn package
d. Перейти в каталог target в каталоге json-web-key-generator
e. Выполнить по очереди:
java -jar json-web-key-generator-0.4-SNAPSHOT-jar-with-dependencies.jar -t oct -s 256
java -jar json-web-key-generator-0.4-SNAPSHOT-jar-with-dependencies.jar -t oct -s 512
java -jar json-web-key-generator-0.4-SNAPSHOT-jar-with-dependencies.jar -t oct -s 96
java -jar json-web-key-generator-0.4-SNAPSHOT-jar-with-dependencies.jar -t oct -s 512
Полученные четыре ключа k присваиваются четырём узлам zookeeper в указанном порядке.
(2) Настройки электронной почты
Электронная почта используется для отправки проверочных кодов и сброса паролей.
``` shell
# Хост почтового сервера, например: smtp-dev.sl.com (по умолчанию)
/com/dianrong/cfg/1.0.0/uniauth/internal.mail.smtp.host
# Порт почтового сервера, например: 25 (по умолчанию)
/com/dianrong/cfg/1.0.0/uniauth/internal.mail.smtp.port
# Отправитель системы уведомлений uniauth, например: TechOps-Notification<noreply@dianrong.com> (по умолчанию)
/com/dianrong/cfg/1.0.0/uniauth/internal.mail.smtp.femail
4.2. Настройки Redis
# Режим дозорного (необходимо указать конкретные настройки master, password, sentinels. Должны быть указаны адреса и порты sentinel)
/com/dianrong/cfg/1.0.0/uniauth/redis.database 0 # Индекс базы данных redis
/com/dianrong/cfg/1.0.0/uniauth/cas.iscluster true # true или false, по умолчанию — false. Определяет, будет ли CAS хранить билеты через redis. Если не хотите, чтобы CAS зависел от redis, установите значение false.
/com/dianrong/cfg/1.0.0/uniauth/redis.uniauth.use_redis # true или false, по умолчанию — true. Определяет, использует ли uniauth-сервер redis в качестве кэша. Если uniauth-сервер не должен зависеть от redis, установите значение false.
/com/dianrong/cfg/1.0.0/uniauth/redis.password 'password' # Пароль redis. Не требуется, если пароль отсутствует.
/com/dianrong/cfg/1.0.0/uniauth/redis.master mymaster # Имя главного узла
/com/dianrong/cfg/1.0.0/uniauth/redis.sentinels 10.18.19.51:5000,10.18.19.101:5000 # Список узлов кластера redis, например: 10.18.19.67:5000,10.18.19.51:5000,10.18.19.101:5000
4.3. Интеграция системы
Следующие xxx
представляют определённые домены, такие как techops, crm, pms, cms и т. д.
# Адрес системы xxx. Например: http://localhost:8100/techops/
/com/dianrong/cfg/1.0.0/uniauth/domains.xxx http://localhost:8100/techops/
# Если система xxx использует настраиваемую страницу входа, настройте её адрес здесь.
/com/dianrong/cfg/1.0.0/uniauth/domains.xxx.loginPage http://localhost:8100/techops/login.jsp
# Если при неудачной аутентификации в системе xxx необходимо перенаправить на страницу ошибки (требуется настройка клиента), настройте здесь адрес страницы ошибки.
/com/dianrong/cfg/1.0.0/uniauth/domains.xxx.auth_fail_url http://localhost:8100/techops/login_fail.jsp
# Явно укажите, можно ли перейти на страницу входа системы xxx с домашней страницы uniauth (например, должна ли отображаться опция). Например: true
/com/dianrong/cfg/1.0.0/uniauth/domains.xxx.showInHomePage true
Клиенту системы необходимо использовать spring security, импортировать jar-пакет модуля ss-client. Ниже приведён пример проекта techops.
<!-- spring session publisher --> ```
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
<!-- In generally Spring Security Filter order first before other filters -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>```
**applicationContext.xml**
Не следует помещать приведённую ниже конфигурацию в SpringMVC соответствующий xml, необходимо поместить её в Spring Bean xml.
```xml
<import resource="classpath:ss-uniauth-client.xml" /> // Импорт Spring конфигурации файла ss-client
<bean id="domainDefine" class="com.dianrong.common.uniauth.common.client.DomainDefine">
<property name="domainCode" value="techops">
</property> // Определение собственного кода домена и Uniauth zookper (с префиксом domains), сохранение согласованности определения домена TechOps
<!-- <property name="userInfoClass" value="com.dianrong.common.techops.sscustom.TechOpsUserExtInfo"></property> -->
// Определение класса свойств UserDetails, расширение от UserExtInfo, если не требуется, можно не настраивать
// Если установлено значение true, то если текущий запрос URL не находит никакого соответствия определению URL, доступ будет отклонён
// Если установлено значение true, необходимо удалить <sec:intercept-url pattern="/**" access="isAuthenticated()"/>, потому что это определение охватывает все URL по умолчанию
<property name="rejectPublicInvocations" value="false"></property>
// Когда доступ к бизнес-домену осуществляется через определённый URL, если сеанс недействителен или никогда не входил в систему, этот URL-адрес будет записан сервером бизнес-домена и перенаправлен на страницу входа в cas;
// После успешного входа он будет перенаправлен обратно на этот URL, и если необходимо переписать этот URL, его можно настроить здесь, а если нет настройки, по умолчанию будет перенаправлено на ранее записанный URL-адрес
<property name="customiedSavedRequestUrl" value="/jump/jump.html"></property>
</bean>
<sec:http pattern="/views/**" security="none" /> // Некоторые URL ресурсы не требуют защиты Spring Security
<sec:http entry-point-ref="casAuthEntryPoint" use-expressions="true" request-matcher="ant">
<sec:custom-filter ref="casAuthenticationFilter" position="CAS_FILTER"/>
<sec:custom-filter after="EXCEPTION_TRANSLATION_FILTER" ref="exceptionTranslationFilter" />
<sec:custom-filter ref="singleLogoutFilter" before="CAS_FILTER" />
<sec:custom-filter ref="requestSingleLogoutFilter" before="LOGOUT_FILTER" />
<sec:access-denied-handler error-page="/errors/403.jsp"/> // Настройка собственной страницы 403 Forbidden по мере необходимости
<sec:csrf disabled="true"/>
<sec:custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
<sec:session-management session-authentication-strategy-ref="sas" invalid-session-url="#{uniauthConfig['cas_server']}/logout?dupsession=true"/>
<sec:logout delete-cookies="JSESSIONID" />
<!-- Здесь можно добавить часто используемые стабильные определения intercept-url для бизнес-систем -->
// Важно: если ваша система основана на url_pattern для принятия решений о правах доступа, вы должны попытаться разделить и зарегистрировать защищённые URL-адреса,
// В противном случае вам придётся использовать это правило в качестве альтернативы, поскольку это определение охватывает любой URL по умолчанию, то есть зарегистрированный пользователь может получить доступ ко всем URL.
<sec:intercept-url pattern="/**" access="isAuthenticated()" />
</sec:http>
<bean id="exceptionTranslationFilter" class="com.dianrong.common.uniauth.client.custom.SSExceptionTranslationFilter">
<constructor-arg name="authenticationEntryPoint" ref="casAuthEntryPoint"></constructor-arg>
<property name="accessDeniedHandler">
<bean class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<property name="errorPage" value="/errors/403.jsp" />
</bean>
</property>
</bean>
<!-- Session параллельный контроль: начало -->
<bean id="concurrencyFilter" class="org.springframework.security.web.session.ConcurrentSessionFilter">
<constructor-arg name="sessionRegistry" ref="sessionRegistry">
</constructor-arg>
<constructor-arg name="expiredUrl" value="#{uniauthConfig['cas_server']}/logout?dupsession=true">
</constructor-arg>
</bean>
<bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
<bean id="sas" class="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy">
<constructor-arg>
<list>
<bean class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy">
<constructor-arg ref="sessionRegistry"/>
</bean>
<bean class="org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy">
<constructor-arg ref="sessionRegistry"/> **Перевод текста на русский язык:**
<property name="maximumSessions" value="1" />
<property name="exceptionIfMaximumExceeded" value="false" />
</bean>
</list>
</constructor-arg>
</bean>
<bean id="casAuthenticationFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="filterProcessesUrl" value="/login/cas"></property>
<property name="authenticationSuccessHandler" ref="ssAuthenticationSuccessHandler"></property>
<property name="sessionAuthenticationStrategy" ref="sas" />
</bean>
<!-- Session并发控制: end -->
<!--
注册PermissionEvaluator实现,以便支持hasPermission表达式,如果不使用则不用配置
注意:ID必须为uniauthPermissionEvaluator,且primary="true"
-->
<bean id="uniauthPermissionEvaluator" class="com.dianrong.common.techops.sscustom.TechOpsPermissionEvaluator" primary="true"></bean>
Можно через вызов метода getLoginUserInfo() класса Spring Bean UniClientCommonService получить объект текущего пользователя, вошедшего в систему.
SecurityContextHolder.getContext().getAuthentication().getPrincipal();
Если интегрированная система использует Spring Boot, необходимо внести некоторые изменения в способ интеграции не-Spring Boot систем.
<!-- Импорт конфигурации uniauth XML -->
<import resource="classpath:ss-uniauth-client.xml" />
<bean id="domainDefine" class="com.dianrong.common.uniauth.common.client.DomainDefine">
<property name="domainCode" value="springboot-ssclient"></property>
<property name="rejectPublicInvocations" value="false"></property>
<property name="customizedLoginRedirecUrl" value="/content"></property>
</bean>
<!-- do not change: start -->
<bean class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<property name="errorPage" value="/errors/403.jsp" />
</bean>
<bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
<bean id="sas" class="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy">
<constructor-arg>
<list>
<bean
class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy">
<constructor-arg ref="sessionRegistry" />
</bean>
<bean class="org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy">
<constructor-arg ref="sessionRegistry" />
<property name="maximumSessions" value="1" />
<property name="exceptionIfMaximumExceeded" value="false" />
</bean>
</list>
</constructor-arg>
</bean>
<!-- do not change: end -->
Примечание: эта конфигурация отличается от исходной конфигурации тем, что она удаляет конфигурацию фильтра и конфигурацию Spring Security.
Например, в конфигурации demo springboot-ssclient:
@Configuration
public class WebSecurityConfiguration extends UniauthSecurityConfig {
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/js/**", "/favicon.ico");
}
}
Примечание. При переопределении защищенного метода configure(HttpSecurity http) в родительском классе не забудьте вызвать super.configure(HttpSecurity http);
jar-пакеты: 'org.jasig.cas.client:cas-client-core:3.4.1'
Примечание: необходимо добавить три фильтра: SingleSignOutFilter (единый выход из системы), AuthenticationFilter (единая аутентификация) и Cas20ProxyReceivingTicketValidationFilter (проверка билетов).
Пример использования (на примере встроенного сервера Jetty, конфигурация для других контейнеров Tomcat аналогична):
// first
FilterHolder singleSignOutFilter = new FilterHolder(SingleSignOutFilter.class);
singleSignOutFilter.setInitParameter("casServerUrlPrefix", "http://localhost:8080/cas"); // 配置cas的统一地址cas_server
root.addFilter(singleSignOutFilter, "/*", Handler.DEFAULT);
// second
FilterHolder authenticationFilter = new FilterHolder(AuthenticationFilter.class);
authenticationFilter.setInitParameter("casServerLoginUrl", "http://localhost:8080/cas/login"); // 配置cas的登陆页面: cas_server/login
authenticationFilter.setInitParameter("gateway", Boolean.FALSE.toString()); // 默认采用false
authenticationFilter.setInitParameter("service", "http://localhost:8120/login/cas"); // 业务系统地址配置:custom_url/login/cas. 后缀/login/cas **Необходимо, для совместимости с единой страницей входа.**
root.addFilter(authenticationFilter, "/*", Handler.DEFAULT);
// third
FilterHolder ticketValidationFilter = new FilterHolder(Cas20ProxyReceivingTicketValidationFilter.class);
ticketValidationFilter.setInitParameter("service", "http://localhost:8120/login/cas"); // Конфигурируем адрес бизнес-системы: custom_url/login/cas. Суффикс /login/cas необходим для совместимости со страницей единого входа. Например: https://passport-dev.dianrong.com
ticketValidationFilter.setInitParameter("casServerUrlPrefix", "http://localhost:8080/cas"); // Настраиваем единый адрес cas: cas_server
root.addFilter(ticketValidationFilter, "/*", Handler.DEFAULT);
**Обратите внимание: можно заметить порядок добавления фильтров: SingleSignOutFilter -> AuthenticationFilter -> ticketValidationFilter**
#### 5.2.2 После прохождения через вышеуказанные фильтры, можно получить Principal пользователя из сессии
```java
Assertion assertion = (Assertion) session.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
AttributePrincipal principal = assertion.getPrincipal(); // В principal есть информация о пользователе, такая как электронная почта и сервис.
Объяснение: CONST_CAS_ASSERTION — это строка "const_cas_assertion", которую можно напрямую использовать с помощью AbstractCasFilter.CONST_CAS_ASSERTION.
// Создаём параметры входа
LoginParam loginParam = new LoginParam();
// Пользователь
emailloginParam.setAccount(userName);
// Устанавливаем арендатор
idloginParam.setTenancyId(tenancyId);// Устанавливаем идентификатор арендатора (используется для статистики вызовов uniauth)
CxfHeaderHolder.TENANCYID.set(tenancyId);
Response<UserDetailDto> response = uniClientFacade.getUserResource().getUserDetailInfo(loginParam);// Очищаем идентификатор арендатора
idCxfHeaderHolder.TENANCYID.set(null);
Модуль common
предоставляет клиентскую обёртку для Rest API, предоставляемых uniauth-server
. Клиенты могут внедрить com.dianrong.common.uniauth.common.client.UniClientFacade
, чтобы получить информацию о персонале, группах, доменах, ролях и разрешениях. Подробнее см. в UniClientFacade (http://xxx/com/dianrong/common/uniauth/common/client/UniClientFacade.java
):
public static void main(String args[]) {
//Этот конструктор принимает строку, которая является конечной точкой веб-сервиса uniauth-сервера
UniClientFacade uniClientFacade = new UniClientFacade("http://localhost:8080/ws/rs");
System.out.println(uniClientFacade.getConfigResource().getAllCfgTypes().getData());
}
URI_PATTERN:
Действует аналогично конфигурации <sec:intercept-url pattern="/xxx" access="hasAnyRole('ROLE_XXX','ROLE_YYY','ROLE_ZZZ')" />
в Spring Security и в основном используется для определения URL-ресурсов в веб-форме. Он может использоваться для защиты реальных URL-адресов доступа или для тегов <sec:authorize url="/xxx">
.
Следует особо отметить, что если несколько ролей совместно используют один и тот же role_code, использование URL_PATTERN может иметь влияние.
Примечание: независимо от того, используется ли Spring Security или база данных, вы можете определить разрешённый метод HTTP для доступа к URL-адресу в конфигурации или базе данных. Если не указано иное, этот URL-адрес по умолчанию поддерживает все типы методов HTTP. Например, в конфигурации: <sec:intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" **method="GET"**/>
при использовании метода для определения, Spring Security будет сравнивать метод запроса с определённым методом в первую очередь. Если они не совпадают, эта конфигурация будет проигнорирована, даже если URL-адрес сам по себе совпадает. Поэтому, если вы хотите использовать метод HTTP для защиты вашего URL-адреса, вам следует полностью определить режим URL-адреса и доступный метод контроллера, который необходимо защитить (в конфигурации или базе данных), чтобы он работал должным образом.
DOMAIN:
Используется TechOps и не применяется другими бизнес-системами.
PRIVILEGE:
Каждая бизнес-система может определять свои собственные списки контроля доступа на основе своих потребностей. Эти разрешения используются для защиты любых ресурсов, которые необходимо защитить, например, через SpEL-выражение principal.hasPrivilege('xxx'). Примечание: в отличие от URI_PATTERN, этот тип разрешений не участвует во внутреннем механизме контроля разрешений Spring Security, а предназначен для определения точек контроля разрешений на уровне бизнеса.
Вышеупомянутые три типа разрешений охватывают большинство потребностей бизнеса. Если этого недостаточно, вы можете связаться с нами, и мы обсудим это, чтобы добавить новые типы разрешений по мере необходимости.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )