当前位置: 首页 > article >正文

CAS单点登录(第7版)20.用户界面

如有疑问,请看视频:CAS单点登录(第7版)

  1. 用户界面
    1. 概述
      1. 概述

对 CAS 用户界面 (UI) 进行品牌化涉及编辑 CSS 样式表以及一小部分相对简单的 HTML 包含文件,也称为视图。(可选)您可能还希望修改显示的文本和/或在这些视图上添加其他 JavaScript 效果。

      1. 浏览器支持

CAS 用户界面应该适当且舒适地适合所有主要的浏览器供应商:

  1. 谷歌浏览器
  2. Mozilla 火狐浏览器
  3. 苹果 Safari 浏览器
  4. Microsoft Edge
  5. Internet Explorer(仅限 v11)

请注意,某些旧版本的 IE,尤其是 IE 9 及更低版本,可能会给获得正确的 UI 配置带来额外的困难。用于用户界面的库(Bootstrap 和 Material.io)不支持 Internet Explorer 9 或更低版本。

 支持的浏览器

此处列出的受支持浏览器是指默认的 CAS 用户界面。可以实施自定义以支持使用覆盖、主题等的其他浏览器。

IE浏览器

要指示 CAS 在兼容模式下呈现 UI,以下内容会自动添加到相关 UI 组件中:

1

<meta http-equiv="X-UA-Compatible" content="IE=edge" />

      1. CSS & JavaScript

有关更多信息,请参阅本指南。

      1. 视图

有关更多信息,请参阅本指南。

      1. 地方化

有关更多信息,请参阅本指南。

      1. 主题

有关更多信息,请参阅本指南。

    1. CSS & JavaScript
      1. CSS

默认样式都包含在位于 src/main/resources/static/css/cas.css 中的单个文件中。此位置在 cas-theme-default.properties 中设置。默认情况下,CAS 使用 Material.io 库和设计规范作为其用户体验的基础。

例如,如果您想创建自己的 css/my.css file,则需要更新该文件中的 cas.standard.css.file 密钥。

1

2

cas.standard.css.file=/css/cas.css

cas.standard.js.file=/js/cas.js

请注意,

  1. 可以定义多个 CSS 或 Javascript 文件,并用逗号分隔。
  2. 文件的顺序很重要。文件将按照定义的顺序加载。
  3. 默认情况下,CAS 将始终加载 /css/custom.css 和 /js/custom.js,以允许覆盖和自定义。
      1. 响应式设计

CSS 媒体查询为 CAS 带来了响应式设计功能,这将使采用者能够专注于所有适用设备和平台的一个主题。这些查询在同一个 cas.css 文件中定义。它们遵循 Twitter Bootstrap 断点和网格。

      1. JavaScript

如果你需要添加一些 JavaScript,请随意附加 src/main/resources/static/js/cas.js。

例如,您还可以创建自己的自定义 javascript 文件,并从 scripts.html 中调用它,如下所示:

1

<script type="text/javascript" src="/js/my.js"></script>

如果要为每个服务开发主题,则每个主题还可以在 cas.standard.js.file 设置下指定自定义 cas.js 文件。

最重要的是,CAS 会自动使用以下 Javascript 库:

  1. JQuery
  2. 网格 / Flex 实用程序的 Bootstrap
  3. Material.io
      1. 脚本加载

CAS 提供了一个回调函数,允许在脚本加载完成时通知采用者,这将是执行/加载其他依赖于实际页面内 JQuery 的 Javascript 相关函数的安全时间。

1

2

3

function jqueryReady() {

// Custom Javascript tasks can be carried out now via JQuery...

}

      1. 检查 CAPSLOCK

在键入凭据密码期间打开 CAPSLOCK 密钥时,CAS 将显示一个简短的警告。此检查由 cas.js 文件强制执行。

      1. 浏览器 Cookie 支持

要使 CAS 支持单点登录会话,浏览器必须支持并接受 Cookie。如果浏览器已关闭对 Cookie 的支持,CAS 将通知用户。此行为通过 cas.js 文件进行控制。

      1. 保留锚点片段

锚点/片段可能会在重定向中丢失,因为表单帖子的服务器端处理程序会忽略客户端锚点,除非附加到表单 POST URL。如果您希望经过 CAS 身份验证的应用程序在为书签时能够使用锚点/片段,则需要这样做。默认情况下,CAS 配置为在指定的位置和时间保留锚点片段。您无需再做任何事情。

        1. 用于 Javascript/CSS 库的 WebJAR

CAS 应用程序将第三方静态资源打包在 CAS Web 应用程序中,而不是引用 CDN 链接,以便 CAS 可以部署在 Internet 访问受限的网络上。

第三方静态资源打包在 “WebJAR” jar 文件中,并通过 servlet 3.0 功能提供,该功能将 Web 应用程序 jar 中 META-INF/resources 下的任何文件夹与应用程序的 Web 根合并。

        1. 构建 WebJAR

您可以在 http://webjars.org 中搜索 webjar。您可以阅读三种风格的 WebJARs,但只要您要使用的 Web 资源存在 NPM 或 Bower 包,就可以为任何版本自动创建 NPM 和 Bower 类型(如果它们尚不存在)。单击 “Add a webjar” 按钮并按照说明进行操作。如果自定义覆盖中的 UI,则部署程序可以将 webjar 作为依赖项添加到其覆盖项目中,并直接在 html 文件中或通过向覆盖项目的 src\main\resources 文件夹中的 common_messages.properties 文件添加条目来引用资源的 URL。

    1. 视图和模板
      1. 概览
        1. 视图

这些视图位于 CAS Web 应用程序内的 templates文件夹中的 WEB-INF\lib\cas-server-support-thymeleaf-<cas.version>.jar 中。将任何需要自定义的视图添加到 CAS 覆盖项目的 src/main/resources/templates 文件夹中。通过在 CAS 覆盖项目中的 src/main/resources 下的相同位置,可以覆盖在该模块中找到的任何文件。覆盖的 Gradle 构建脚本包含有助于将资源从 CAS Web 应用程序获取到 CAS 覆盖中的正确位置的任务。

        1. 模板

CAS 提供并认可以下用户界面模板,用于各种模块和功能:

Show  entries

搜索:

类别

名字

完整路径

所有者

acct

casMyAccountProfile.html

/src/main/resources/templates/acct/casMyAccountProfile.html

Thymeleaf

acct-mgmt

casAccountSignupView.html

/src/main/resources/templates/acct-mgmt/casAccountSignupView.html

Thymeleaf

acct-mgmt

casAccountSignupViewComplete.html

/src/main/resources/templates/acct-mgmt/casAccountSignupViewComplete.html

Thymeleaf

acct-mgmt

casAccountSignupViewCompleted.html

/src/main/resources/templates/acct-mgmt/casAccountSignupViewCompleted.html

Thymeleaf

acct-mgmt

casAccountSignupViewSentInfo.html

/src/main/resources/templates/acct-mgmt/casAccountSignupViewSentInfo.html

Thymeleaf

adaptive-authn

casRiskAuthenticationBlockedView.html

/src/main/resources/templates/adaptive-authn/casRiskAuthenticationBlockedView.html

Thymeleaf

adaptive-authn

casRiskAuthenticationVerifiedView.html

/src/main/resources/templates/adaptive-authn/casRiskAuthenticationVerifiedView.html

Thymeleaf

admin

casAdminLoginView.html

/src/main/resources/templates/admin/casAdminLoginView.html

Thymeleaf

aup

casAcceptableUsagePolicyView.html

/src/main/resources/templates/aup/casAcceptableUsagePolicyView.html

Thymeleaf

consent

casConsentView.html

/src/main/resources/templates/consent/casConsentView.html

Thymeleaf

delegated-authn

casDelegatedAuthnErrorView.html

/src/main/resources/templates/delegated-authn/casDelegatedAuthnErrorView.html

Thymeleaf

delegated-authn

casDelegatedAuthnSelectionView.html

/src/main/resources/templates/delegated-authn/casDelegatedAuthnSelectionView.html

Thymeleaf

delegated-authn

casDelegatedAuthnStopWebflow.html

/src/main/resources/templates/delegated-authn/casDelegatedAuthnStopWebflow.html

Thymeleaf

delegated-authn

casDynamicDiscoveryView.html

/src/main/resources/templates/delegated-authn/casDynamicDiscoveryView.html

Thymeleaf

error

error.html

/src/main/resources/templates/error.html

Thymeleaf

显示 1 到 15 的 143 个条目

上一页12345...10下一页

        1. 配置

以下设置和属性可从CAS配置曲库获得:

可选

笔记

下面列出的配置设置在CAS配置元数据中被标记为可选。该标志表示在最终用户CAS配置中不需要立即存在该设置,因为分配了默认值或功能的激活不受设置值的有条件控制。换句话说,如果您需要修改默认值或如果您需要打开由设置控制的功能,您应该只在您的配置中包含此字段。

Show  entries

搜索:

·  cas.view.template-prefixes=

可以找到CAS模板的逗号分隔路径。示例可能是classpath:templates,file:/templates。

 org.apereo.cas.configuration.model.core.web.view.ViewProperties.

如何配置此属性?

显示1到1个条目中的1个

上一个1下一个

        1. 访问应用程序前的警告

CAS 能够在用户重定向到服务之前发出警告。这样,每当应用程序使用 CAS 登录时,用户都会收到通知。(如果他们不选择警告,则在访问成功依赖现有 CAS 单点登录会话的应用程序时,他们可能不会看到任何 CAS 屏幕。一些 CAS 采用者删除了 CAS 登录视图中的“警告”复选框,并且不提供这种正在进行单点登录的插页式建议。

1

2

3

4

5

6

7

8

...

<input id="warn"

   name="warn"

   value="true"

   th:accesskey="#{screen.welcome.label.warn.accesskey}"

   type="checkbox" />

<label for="warn" th:utext="#{screen.welcome.label.warn}"/>

...

      1. Thymeleaf
        1. 用户界面 - Thymeleaf

CAS 使用 Thymeleaf 作为其标记渲染引擎。每个模板都由layout.html模板文件装饰,该文件为模板的内容提供布局结构。为在多个模板之间重复使用而优化的单个组件存储在 src/main/resources/templates/fragments 文件夹中,并由 src/main/resources/templates 中的模板引用。

有关其用法和语法的更多信息,请参阅 Lymeleaf 文档。

CAS 配置目录中提供了以下设置和属性:

自选

笔记

下面列出的配置设置在 CAS 配置元数据中标记为 Optional(可选)。This标志表示在最终用户 CAS 配置中不需要立即存在该设置,因为分配了默认值,或者该功能的激活不受设置值有条件地控制。换句话说,仅当需要修改默认值或需要打开由设置控制的功能时,才应在配置中包含此字段。

Show  entries

搜索:

·  spring.thymeleaf.cache=true

是否启用模板缓存。

 org.springframework.boot.autoconfigure.thymeleaf.ThymeleafProperties.

如何配置此属性?

·  spring.thymeleaf.check-template-location=true

是否检查 templates 位置是否存在。

 org.springframework.boot.autoconfigure.thymeleaf.ThymeleafProperties.

如何配置此属性?

·  spring.thymeleaf.check-template=true

是否在渲染模板之前检查模板是否存在。

 org.springframework.boot.autoconfigure.thymeleaf.ThymeleafProperties.

如何配置此属性?

·  spring.thymeleaf.enable-spring-el-compiler=false

在 SpringEL 表达式中启用 SpringEL 编译器。

 org.springframework.boot.autoconfigure.thymeleaf.ThymeleafProperties.

如何配置此属性?

·  spring.thymeleaf.enabled=true

是否为 Web 框架启用 Thymeleaf 视图解析。

 org.springframework.boot.autoconfigure.thymeleaf.ThymeleafProperties.

如何配置此属性?

显示 1 到 5 的 19 个条目

上一页1234下一页

      1. 外部视图
        1. 用户界面 - 外部视图

视图也可以有条件地和单独地在 Web 应用程序外部化,前提是通过 CAS 设置提供外部路径。如果在外部化路径中找不到视图样板文件,则 CAS 附带的默认文件将用作回退。

也可以使用 CAS 设置中的外部 URL 找到视图,该 URL 负责在响应中生成完整的视图正文。此 URL 端点将在其请求中接收可用的请求标头以及以下标头:

表头

owner

template

resource

theme如果可用)

locale(如果可用)

在成功获得 200 状态结果后,响应正文应包含 CAS 将呈现的视图。

CAS 配置目录中提供了以下设置和属性:

必填

自选

笔记

下面列出的配置设置在 CAS 配置元数据中标记为 Required。此标志表示可能需要该设置的存在才能激活或影响 CAS 功能的行为,并且通常应进行审查、可能拥有和调整。如果为该设置分配了默认值,则无需严格将该设置放在配置副本中,但仍应对其进行检查以确保它符合您的部署预期。

Show  entries

搜索:

·  cas.view.rest.url=

用于联系和检索属性的终端节点 URL。

此设置支持 Spring 表达式语言。

 org.apereo.cas.configuration.model.core.web.view.RestfulViewProperties.

如何配置此属性?

显示 1 到 1 的 1 个条目

上一页1下一页

      1. 自定义字段
        1. 用户界面 - 自定义字段

CAS 允许通过包含其他字段来动态扩展登录表单,以供用户填写。这些字段使用设置教给 CAS,然后绑定到身份验证流,并提供给所有希望使用上述字段施加其他进程和规则的身份验证处理程序。

CAS 配置目录中提供了以下设置和属性:

自选

笔记

下面列出的配置设置在 CAS 配置元数据中标记为 Optional(可选)。This标志表示在最终用户 CAS 配置中不需要立即存在该设置,因为分配了默认值,或者该功能的激活不受设置值有条件地控制。换句话说,仅当需要修改默认值或需要打开由设置控制的功能时,才应在配置中包含此字段。

Show  entries

搜索:

·  cas.view.custom-login-form-fields.[key].converter=

用于转换绑定属性值的自定义转换器的 ID。

 org.apereo.cas.configuration.model.core.web.view.CustomLoginFieldViewProperties.

如何配置此属性?

·  cas.view.custom-login-form-fields.[key].message-bundle-key=

在消息包中找到的此字段的键用于在 CAS 视图中显示标签/文本。

 org.apereo.cas.configuration.model.core.web.view.CustomLoginFieldViewProperties.

如何配置此属性?

·  cas.view.custom-login-form-fields.[key].required=

此字段是否必须具有值。

 org.apereo.cas.configuration.model.core.web.view.CustomLoginFieldViewProperties.

如何配置此属性?

显示 1 到 3 个条目中的 3 个

上一页1下一页

      1. CAS协议视图
        1. CAS v1
          1. 用户界面 - CAS v1 视图

当客户端应用程序使用 CAS v1 协议与 CAS 交互时,您可以控制响应输出。

CAS 配置目录中提供了以下设置和属性:

自选

笔记

下面列出的配置设置在 CAS 配置元数据中标记为 Optional(可选)。This标志表示在最终用户 CAS 配置中不需要立即存在该设置,因为分配了默认值,或者该功能的激活不受设置值有条件地控制。换句话说,仅当需要修改默认值或需要打开由设置控制的功能时,才应在配置中包含此字段。

Show  entries

搜索:

·  cas.view.cas1.attribute-renderer-type=DEFAULT

指示应如何设置最终验证响应中的属性的格式。可用值如下:

DEFAULT使用 CAS 协议建议呈现属性。

VALUES_PER_LINE:每行的内联属性值。

 org.apereo.cas.configuration.model.core.web.view.Cas10ViewProperties.

如何配置此属性?

显示 1 到 1 的 1 个条目

上一页1下一页

        1. CAS v2
          1. 用户界面 - CAS v2 视图

当客户端应用程序使用 CAS v2 协议与 CAS 交互时,您可以控制响应输出。

CAS 配置目录中提供了以下设置和属性:

自选

笔记

下面列出的配置设置在 CAS 配置元数据中标记为 Optional(可选)。This标志表示在最终用户 CAS 配置中不需要立即存在该设置,因为分配了默认值,或者该功能的激活不受设置值有条件地控制。换句话说,仅当需要修改默认值或需要打开由设置控制的功能时,才应在配置中包含此字段。

Show  entries

搜索:

·  cas.view.cas2.failure=protocol/2.0/casServiceValidationFailure

CAS3 失败视图 Bean 的相对位置。

 org.apereo.cas.configuration.model.core.web.view.Cas20ViewProperties.

如何配置此属性?

·  cas.view.cas2.proxy.failure=protocol/2.0/casProxyFailureView

CAS2 代理故障视图 Bean 的相对位置。

 org.apereo.cas.configuration.model.core.web.view.Cas20ProxyViewProperties.

如何配置此属性?

·  cas.view.cas2.proxy.success=protocol/2.0/casProxySuccessView

CAS2 代理成功视图 Bean 的相对位置。

 org.apereo.cas.configuration.model.core.web.view.Cas20ProxyViewProperties.

如何配置此属性?

·  cas.view.cas2.success=protocol/2.0/casServiceValidationSuccess

CAS2 成功视图 Bean 的相对位置。

 org.apereo.cas.configuration.model.core.web.view.Cas20ViewProperties.

如何配置此属性?

·  cas.view.cas2.v3-forward-compatible=true

v2 协议支持是否应该向前兼容,以像 v3 一样工作并匹配其响应,主要用于属性发布。

 org.apereo.cas.configuration.model.core.web.view.Cas20ViewProperties.

如何配置此属性?

显示 1 到 5 个条目中的 5 个

上一页1下一页

        1. CAS v3
          1. 用户界面 - CAS v3 视图

当客户端应用程序使用 CAS v3 协议与 CAS 交互时,您可以控制响应输出。

CAS 配置目录中提供了以下设置和属性:

自选

笔记

下面列出的配置设置在 CAS 配置元数据中标记为 Optional(可选)。This标志表示在最终用户 CAS 配置中不需要立即存在该设置,因为分配了默认值,或者该功能的激活不受设置值有条件地控制。换句话说,仅当需要修改默认值或需要打开由设置控制的功能时,才应在配置中包含此字段。

Show  entries

搜索:

·  cas.view.cas3.attribute-renderer-type=DEFAULT

指示应如何设置最终验证响应中的属性的格式。可用值如下:

DEFAULT使用 CAS 协议建议呈现属性。

INLINE作为 XML 属性的内联属性名称/值。

 org.apereo.cas.configuration.model.core.web.view.Cas30ViewProperties.

如何配置此属性?

·  cas.view.cas3.failure=protocol/3.0/casServiceValidationFailure

CAS3 成功验证 Bean 的相对位置。

 org.apereo.cas.configuration.model.core.web.view.Cas30ViewProperties.

如何配置此属性?

·  cas.view.cas3.success=protocol/3.0/casServiceValidationSuccess

CAS3 成功验证 Bean 的相对位置。

 org.apereo.cas.configuration.model.core.web.view.Cas30ViewProperties.

如何配置此属性?

显示 1 到 3 个条目中的 3 个

上一页1下一页

    1. 本地化
      1. 本地化

CAS Web 应用程序包括许多本地化的消息文件:

  1. 英语(美式)
  2. 西班牙语
  3. 法语
  4. 俄语
  5. Dutch (荷兰)
  6. 英语 (瑞典语)
  7. 意大利语
  8. 乌尔都语
  9. 中文 (简体)
  10. 德语 (Deutsch)
  11. 日语
  12. 克罗地亚语
  13. 捷克语
  14. 斯洛文尼亚语
  15. 波兰语
  16. 葡萄牙语 (巴西)
  17. 土耳其语
  18. 要使
  19. 阿拉伯语

为了“调用”UI 的特定语言,可以向 /login 端点传递一个 locale 参数,如下所示:

1

https://cas.server.org/login?locale=it

 使用警告!

请注意,并非所有语言在 CAS 服务器版本中都是完整和准确的,因为翻译完全取决于社区的贡献。有关本地化消息的准确完整列表,请始终参阅英语捆绑包。

      1. 配置

所有消息包都标记在 src/main/resources 的 messages_xx.properties 文件下。默认语言包用于英语,因此称为 messages.properties。如果有任何自定义消息需要呈现到视图中,它们也可以在 custom_messages.properties 文件下格式化。

如果在激活的资源包中找不到代码,则将逐字使用代码本身。

        1. 本地化

CAS 配置目录中提供了以下设置和属性:

自选

笔记

下面列出的配置设置在 CAS 配置元数据中标记为 Optional(可选)。This标志表示在最终用户 CAS 配置中不需要立即存在该设置,因为分配了默认值,或者该功能的激活不受设置值有条件地控制。换句话说,仅当需要修改默认值或需要打开由设置控制的功能时,才应在配置中包含此字段。

Show  entries

搜索:

·  cas.locale.cookie.domain=

Cookie 域。指定应在其中显示此 Cookie 的域。域名的形式由 RFC 2965 指定。域名以点 (.foo.com) 开头,表示该 Cookie 对指定域名系统 (DNS) 区域中的服务器可见(例如,www.foo.com,但不是 a.b.foo.com)。默认情况下,Cookie 仅返回给发送它们的服务器。

 org.apereo.cas.configuration.model.core.web.LocaleCookieProperties.

如何配置此属性?

·  cas.locale.cookie.http-only=true

如果此 Cookie 包含 HttpOnly 属性,则为 true。这意味着脚本引擎(如 javascript)不应访问 cookie。

 org.apereo.cas.configuration.model.core.web.LocaleCookieProperties.

如何配置此属性?

·  cas.locale.cookie.max-age=-1

Cookie 的最长期限,以秒为单位指定。默认情况下,-1 表示 Cookie 将一直存在,直到浏览器关闭。正值表示 Cookie 将在该秒数后过期。请注意,该值是 Cookie 过期的最长期限,而不是 Cookie 的当前期限。负值表示 Cookie 不会永久存储,并且将在 Web 浏览器退出时删除。零值会导致 Cookie 被删除。

此设置支持java.time.Duration 语法 [?]。

 org.apereo.cas.configuration.model.core.web.LocaleCookieProperties.

如何配置此属性?

·  cas.locale.cookie.name=

Cookie 名称。构造具有指定名称和值的 Cookie。该名称必须符合 RFC 2965。这意味着它只能包含 ASCII 字母数字字符,不能包含逗号、分号或空格,也不能以 $ 字符开头。Cookie 的名称在创建后无法更改。默认情况下,Cookie 是根据 RFC 2965 Cookie 规范创建的。Cookie 名称由 CAS 在运行时自动计算,分配,通常无需自定义名称或为其分配不同的值,除非有特殊用例需要更改。

 org.apereo.cas.configuration.model.core.web.LocaleCookieProperties.

如何配置此属性?

·  cas.locale.cookie.path=

Cookie 路径。指定客户端应将 Cookie 返回到的 Cookie 的路径。该 Cookie 对您指定的目录中的所有页面以及该目录的子目录中的所有页面都可见。Cookie 的路径必须包含设置 Cookie 的 Servlet,例如 /catalog,它使 Cookie 对 /catalog 下服务器上的所有目录可见。有关为 cookie 设置路径名的更多信息,请参阅 RFC 2965(可在 Internet 上找到)。

 org.apereo.cas.configuration.model.core.web.LocaleCookieProperties.

如何配置此属性?

显示 1 到 5 的 10 个条目

上一页12下一页

        1. 消息包

CAS 配置目录中提供了以下设置和属性:

自选

笔记

下面列出的配置设置在 CAS 配置元数据中标记为 Optional(可选)。This标志表示在最终用户 CAS 配置中不需要立即存在该设置,因为分配了默认值,或者该功能的激活不受设置值有条件地控制。换句话说,仅当需要修改默认值或需要打开由设置控制的功能时,才应在配置中包含此字段。

Show  entries

搜索:

·  cas.message-bundle.base-names=

表示此消息包的基本名称的字符串列表。设置一个基名称数组,每个基名称都遵循不指定文件扩展名或语言代码的基本 ResourceBundle 约定。资源位置格式取决于特定的MessageSource实现。支持常规和 XMl 属性文件:例如,“messages”会找到 “messages.properties”、“messages_en.properties” 等排列方式,以及 “messages.xml”、“messages_en.xml” 等。在解析消息代码时,将按顺序检查关联的资源包。请注意,由于顺序查找,先前资源包中的消息定义将覆盖后面的资源包中的消息定义。

 org.apereo.cas.configuration.model.core.web.MessageBundleProperties.

如何配置此属性?

·  cas.message-bundle.cache-seconds=PT180S

缓存大小。

此设置支持java.time.Duration 语法 [?]。

 org.apereo.cas.configuration.model.core.web.MessageBundleProperties.

如何配置此属性?

·  cas.message-bundle.common-names=

姓氏公用名中的条目将覆盖姓氏的第一个值(与消息包中使用的 baseNames 相反)。

 org.apereo.cas.configuration.model.core.web.MessageBundleProperties.

如何配置此属性?

·  cas.message-bundle.encoding=

消息束字符编码。

 org.apereo.cas.configuration.model.core.web.MessageBundleProperties.

如何配置此属性?

·  cas.message-bundle.fallback-system-locale=false

该标志,用于控制在未明确指定区域设置时是否回退到默认系统区域设置。设置如果未找到特定 Locale 的文件,是否回退到系统 Locale。如果关闭此选项,则唯一的回退将是默认文件(例如,basename “messages” 的 “messages.properties”) 。回退到系统 Locale 是 java.util.ResourceBundle 的默认行为。但是,这在应用程序服务器环境中通常是不可取的,因为系统 Locale 与应用程序完全无关:在这种情况下,将此标志设置为 false。

 org.apereo.cas.configuration.model.core.web.MessageBundleProperties.

如何配置此属性?

显示 1 到 5 的 6 个条目

上一页12下一页

      1. 每项服务

语言区域设置也可以根据每个服务确定:

1

2

3

4

5

6

7

{

  "@class" : "org.apereo.cas.services.CasRegisteredService",

  "serviceId" : "^https://www.example.org",

  "name" : "MyTheme",

  "locale" : "de",

  "id" : 1

}

区域设置名称可以使用 Spring 表达式语言语法。

    1. 主题
      1. 概览
        1. 主题 - 用户界面自定义

随着 Service Management 应用程序的推出,部署人员现在能够根据不同的服务切换主题。例如,您可能希望为教职员工应用程序和学生应用程序使用不同的登录屏幕(不同的样式),或者您希望为白天和夜间显示两种布局。本文档可以帮助您完成基本设置以实现此目的。

主题

描述

静态的

请参阅本指南

视图

请参阅本指南

收集

请参阅本指南

Groovy

请参阅本指南

REST

请参阅本指南

      1. 静态
        1. 静态主题

CAS 配置为根据 Service Registry 中给定注册服务的 theme 属性来装饰视图。通过此方法激活的主题仍将保留 CAS 的默认视图,但会将 CSS 和 Javascript 等装饰应用于视图。视图的物理结构不能通过此方法修改。

CAS 配置目录中提供了以下设置和属性:

自选

Groovy 脚本

笔记

下面列出的配置设置在 CAS 配置元数据中标记为 Optional(可选)。This标志表示在最终用户 CAS 配置中不需要立即存在该设置,因为分配了默认值,或者该功能的激活不受设置值有条件地控制。换句话说,仅当需要修改默认值或需要打开由设置控制的功能时,才应在配置中包含此字段。

Show  entries

搜索:

·  cas.theme.default-theme-name=cas-theme-default

此 CAS 部署的默认主题名称。默认的主题文件 cas-theme-default.properties 可以通过主题文件 cas-theme-custom.properties 进行修改和扩展。

 org.apereo.cas.configuration.model.support.themes.ThemeProperties.

如何配置此属性?

·  cas.theme.description=

此主题的描述,用于描述其用途

如何配置此属性?

·  cas.theme.name=

此主题的名称用于各种标题/说明。

如何配置此属性?

·  cas.theme.param-name=theme

用于切换主题的参数名称。

 org.apereo.cas.configuration.model.support.themes.ThemeProperties.

如何配置此属性?

显示 1 到 4 的 4 个条目

上一页1下一页

要创建主题,请按照以下说明操作:

添加一个 [theme_name].properties 到 src/main/resources 文件夹的根目录。此文件的内容可能包含以下设置:

设置

描述

价值

cas.standard.css.file

主题 CSS 文件的路径;多个文件可以用逗号分隔。

/themes/[theme_name]/css/cas.css

cas.standard.js.file

主题 Javascript 文件的路径;多个文件可以用逗号分隔。

/themes/[theme_name]/js/js/css

cas.standard.fragments.head

在 custom.html fragment 中找到custom.html fragment 的名称,包含在 layout <head> 标记中

空白

cas.logo.file

通过通用布局显示的主题 logo 的路径。

/images/logo.png

cas.drawer-menu.enabled

决定是否应显示抽屉菜单。

true

cas.theme.name

各种标题/说明中使用的主题名称。

Example Theme

cas.theme.description

各种标题/说明中使用的主题描述。

Example Theme Description

cas.pm-links.enabled

是否应显示密码管理/重置链接。

true

cas.login-form.enabled

何时应显示 CAS 登录表单。

true

cas.notifications-menu.enabled

启用并显示通知菜单。

true

cas.favicon.file

主题网站图标文件的路径。

/themes/example/images/favicon.ico

cas.hero-banner.file

登录表单上“hero”样式图像/徽标的路径。

/themes/example/images/hero.png

cas.js.core.enabled

是否应包含核心/默认 Javascript 库。

true

cas.css.core.enabled=true

是否应包含核心/默认 CSS 库。

true

cas.successful-login.display-attributes

登录时是否应显示属性/应用程序。

true

cas.public-workstation.enabled

用户是否可以在登录时指定公共工作站选项。

false

cas.warn-on-redirect.enabled

在重定向到应用程序之前是否应警告用户。

false

cas.browser-storage.show-progress

是否在读取/写入浏览器存储数据时显示进度。

true

cas.footer.show

是否显示 CAS 页脚。

true

cas.footer.show-version

是否在页脚中显示 CAS 版本详细信息..

true

  1. 创建目录 src/main/resources/static/themes/[theme_name]将特定于主题的 cas.css 和 cas.js 放在 css 和 js 的相应目录中。
  2. 在 theme 属性下为服务定义指定 [theme_name]

1

2

3

4

5

6

7

{

  "@class" : "org.apereo.cas.services.CasRegisteredService",

  "serviceId" : "^https://www.example.org",

  "name" : "MyTheme",

  "theme" : "[theme_name]",

  "id" : 1000

}

值可以使用 Spring 表达式语言语法。

      1. 视图
        1. 主题视图 - 用户界面自定义

CAS还可以利用服务的关联主题来选择性地选择将使用哪组UI视图来生成标准视图(login/casLoginView.html等)。这在针对不同类型受众的主题的页面集在结构上完全不同的情况下特别有用,使用简单的主题来增强默认视图是不切实际的。在这种情况下,可能需要新的视图页面。

默认情况下,与特定主题关联的视图应在以下位置找到:src/main/resources/templates/<theme-id>。请注意,CAS视图和基于主题的视图都可能在Web应用程序上下文之外进行外部化。外部化时,主题视图应通过以主题命名的目录下的CAS属性在指定路径中找到。例如,如果CAS视图的外部路径是/etc/cas/templates,则主题sample的视图模板文件可能位于/etc/cas/templates/sample/。

以下设置和属性可从CAS配置曲库获得:

可选

笔记

下面列出的配置设置在CAS配置元数据中被标记为可选。该标志表示在最终用户CAS配置中不需要立即存在该设置,因为分配了默认值或功能的激活不受设置值的有条件控制。换句话说,如果您需要修改默认值或如果您需要打开由设置控制的功能,您应该只在您的配置中包含此字段。

Show  entries

搜索:

·  cas.view.template-prefixes=

可以找到CAS模板的逗号分隔路径。示例可能是classpath:templates,file:/templates。

 org.apereo.cas.configuration.model.core.web.view.ViewProperties.

如何配置此属性?

显示1到1个条目中的1个

上一个1下一个

        1. 配置

添加一个 [theme_name].properties 到 src/main/resources 文件夹的根目录。此文件的内容应与以下内容匹配:

1

2

cas.standard.css.file=/themes/[theme_name]/css/cas.css

cas.standard.js.file=/themes/[theme_name]/js/cas.js

根据主题 ID(即 src/main/resources/templates/<theme-id>)将默认视图页面集克隆到新目录中。

在 theme 属性下为服务定义指定主题的名称。

      1. 收藏
        1. 主题集合 - 用户界面自定义

CAS 提供了一个模块,该模块提供了许多现成的主题。每个主题的目的是在用户界面修改和示例方面考虑常见用例并提供常见用例,并尝试自动执行大部分配置。

通过在 WAR 覆盖中包含以下模块来启用支持:

Apache Maven

Gradle

BOM - Spring

BOM - Gradle

资源

1

2

3

4

5

6

7

8

9

10

dependencies {

    /*

        The following platform references should be included automatically and are listed here for reference only.

        implementation enforcedPlatform("org.apereo.cas:cas-server-support-bom:${project.'cas.version'}")

        implementation platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)

        

    */

    implementation "org.apereo.cas:cas-server-support-themes-collection"}

本模块提供了以下主题,可以将其分配给服务定义:

主题

描述

example

一个结合了自定义 CSS、Javascript 和视图的参考示例主题

twbs

使用 Bootstrap for CSS 和 Javascript 的基本主题

上面的主题集合也可以用作如何使用自定义 CSS、Javascript 以及关联的视图和片段定义主题的参考示例。

      1. Groovy 
        1. Groovy 主题 - 用户界面自定义

如果定义了多个主题,则可能需要动态确定给定服务定义的主题。为此,您可以通过自己设计的 Groovy 脚本计算最终的主题名称。分配给服务定义的主题需要指向脚本的位置:

1

2

3

4

5

6

7

{

  "@class" : "org.apereo.cas.services.CasRegisteredService",

  "serviceId" : "^https://www.example.org",

  "name" : "MyTheme",

  "theme" : "file:///etc/cas/config/themes.groovy",

  "id" : 1000}

脚本本身可以设计为:

1

2

3

4

5

6

7

8

9

import java.util.*

def run(final Object... args) {

    def (service,registeredService,queryStrings,headers,logger) = args

    // Determine theme ...

    return null}

返回 null 或空白将使 CAS 切换到默认主题。可以将以下参数传递给 Groovy 脚本:

参数

描述

service

表示请求服务的对象。

registeredService

表示注册表中匹配的已注册服务的对象。

queryStrings

在请求中找到的所有查询字符串的文本表示形式(如果有)。

headers

Map请求中找到的所有请求标头及其值的映射(如果有)。

logger

负责发出日志消息的对象,例如 logger.info(...)

要准备 CAS 以支持 Apache Groovy 并与之集成,请查看本指南。

      1. REST
        1. RESTful 主题 - 用户界面自定义

与上述选项有点类似,您可以通过自己设计的 REST 端点计算最终的主题名称。分配给服务定义的主题需要指向 REST API 的位置。端点必须设计为通过 GET 请求接受/处理 application/json。返回的状态代码 200 允许 CAS 读取响应的正文以确定主题名称。空响应正文将使 CAS 切换到默认主题。

1

2

3

4

5

6

7

{

  "@class" : "org.apereo.cas.services.CasRegisteredService",

  "serviceId" : "^https://www.example.org",

  "name" : "MyTheme",

  "theme" : "https://themes.example.org",

  "id" : 1000}

可以将以下参数传递给 REST 端点:

参数

描述

service

请求服务标识符。

    1. Webflow 装饰
      1. Webflow 装饰

有时,您可能需要修改 CAS webflow 以包含其他数据,这些数据通常从外部资源和终端节点获取,这些数据也可能被视为敏感资源和终端节点,并且可能需要凭据才能访问。示例包括在 CAS 登录屏幕上显示公告或其他类型的动态数据。您当然可以扩展 webflow,将其他状态和操作包含在登录流中,以调用终端节点和数据源来获取数据。一个更简单的选择是让 CAS 通过访问您的 REST 端点等来自动装饰 webflow,并处理内部 webflow 配置。当 CAS 开始渲染登录视图时,会专门调用此类装饰器,同时保留将来装饰 webflow 其他部分的权利。

请注意,装饰器只会将数据注入到 webflow 上下文中,这些数据稍后可用于 CAS 视图,等等。一旦数据可用,您仍然有责任使用该数据在适当的视图中正确显示它并正确设置其样式。

 用法

请记住,放入 webflow 上下文中的对象和数据必须始终是 Serializable 的。未通过序列化要求的 Complexobjects 和数据结构很可能会中断流程。

      1. 装饰

可以使用以下装饰器:

选择

参考

Groovy

请参阅本指南

REST

请参阅本指南

请注意,装饰器通常在 webflow 运行时执行特定操作之前执行,并且它们几乎总是针对所有 webflow 操作执行,而不管拥有的流如何。这样,如有必要,您可以选择使用其他数据装饰所有 CAS Web 流和子流,并且您不仅限于装饰登录流或登录页面。

      1. 自定义

可以使用@Bean以下将在 @AutoConfiguration 类中注册的 webflow 装饰器来设计 webflow 装饰器并将其注入 CAS 中:

1

2

3

4

@Beanpublic WebflowDecorator myWebflowDecorator() {

    return new MyWebflowDecorator();}

您的配置类需要向 CAS 注册。有关更多详细信息,请参阅本指南。

    1. 用户界面配置
      1. application.yml

cas\src\main\resources\application.yml

# 需要的应用程序属性

# 嵌入在web应用程序中的内容可以包含在这里

cas:

    authn:

        accept:

            # 关闭CAS身份验证静态凭据

            enabled: "false"

        jdbc:

            query[0]:

                # 活动身份验证处理程序,默认情况下自动调用以全局验证凭据。

                state: "ACTIVE"

                # 用于连接到数据库的 JDBC 驱动程序。

                driver-class: "com.mysql.cj.jdbc.Driver"

                # 数据库连接URL。

                url: "jdbc:mysql://localhost:3306/cas?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true"

                # SQL查询要执行。例子:SELECT * FROM table WHERE name=?。

                sql: "SELECT * FROM pm_table_accounts WHERE userid=?"

                # 数据库用户。

                user: "root"

                # 数据库连接密码。

                password: "123456"

                # 要检索的密码字段/列名称。

                field-password: "password"

                # 数据库方言是平台独立软件(JPA、Hibernate 等)的配置设置,

                # 它允许此类软件将其通用 SQL 语句转换为供应商特定的 DDL、DML。

                dialect: "org.hibernate.dialect.HSQLDialect"

                # 指示帐户是否过期的布尔字段。

                field-expired: "false"

                # 指示帐户是否被禁用的布尔字段。

                field-disabled: "false"

                password-encoder:

                    # 要使用的编码算法,例如 MD5。

                    encoding-algorithm: "MD5"

                    # 不进行密码编码(即纯文本)。

                    type: "DEFAULT"

                    # 要使用的编码算法,例如“UTF-8”。当使用的类型是DEFAULT时相关。

                    character-encoding: "UTF-8"

                    # 使用时PasswordEncoderTypes#ARGON2,它表示哈希强度/长度。

                    hash-length: "32"

                    # 用于密码散列的强度或迭代次数。

                    # 通常在处理PasswordEncoderTypes#BCRYPT,PasswordEncoderTypes#PBKDF2或PasswordEncoderTypes#GLIBC_CRYPT时相关。

                    # 当与PasswordEncoderTypes#ARGON2或PasswordEncoderTypes#PBKDF2一起使用时,表示盐的强度。

                    strength: "32"

        

        pm:

            # webflow:

                # 是否应启用webflow自动配置。

                # enabled: "true"

                # 配置Web流的顺序。

                # order: "0"

            core:

                # 指示是否启用密码管理工具的标志。

                enabled: "true"

                # 表示密码策略正则表达式模式的字符串值。

                # 最少8个和最多10个字符,至少1个大写字母、1个小写字母、1个数字和1个特殊字符。

                # password-policy-pattern: "^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&]{8,10}"

                # 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线)

                password-policy-pattern: "^[a-zA-Z]\\w{5,17}$"

                # 标记,指示成功更改密码是否应自动触发登录。

                auto-login: "false"

                

            # CAS密码管理-密码重置

            reset:

                # 过期分钟数

                # expiration-minutes: "30"

                # 是重置操作是否需要安全问题,还是应将其标记为可选。

                security-questions-enabled: "true"

                mail:

                    # 主属性名称,指示此消息的目标电子邮件地址。

                    attribute-name: "mail"

                    # 发件人邮箱地址。

                    from: "361604199@qq.com"

                    # 电子邮件主题可以定义为verbaitm,也可以使用语法#{subject-language-key}指向语言包中的消息键。

                    subject: "CAS密码管理-密码重置-电子邮件主题"

                    # 电子邮件主体。可以是纯文本或对将用作模板的外部文件的引用。

                    text: "尊敬的用户:您好,要重置 CAS 密码,请单击以下链接: ${url} 请注意:为安全起见,此链接将在自发送之时起 30 分钟后过期。如果您无法访问此链接,请将整个 URL 复制并粘贴到浏览器中,谢谢! 猴王软件学院"

                    # 电子邮件密送地址(如果有)。

                    # bcc:

                    # 电子邮件抽送地址(如果有)。

                    # cc:

                    

            # CAS密码管理-忘记用户名

            forgot-username:

                # 过期分钟数

                # expiration-minutes: "30"

                # 是否应启用忘记/重置用户名功能。

                enabled: "true"

                mail:

                    # 主属性名称,指示此消息的目标电子邮件地址。

                    attribute-name: "mail"

                    # 地址的电子邮件。

                    from: "361604199@qq.com"

                    # 电子邮件主题行。

                    subject: "CAS密码管理-忘记用户名-电子邮件主题"

                    # 电子邮件主体。可以是纯文本或对将用作模板的外部文件的引用。

                    text: "尊敬的用户:您好,要重置 CAS 密码,请单击以下链接: ${url} 请注意:为安全起见,此链接将在自发送之时起 30 分钟后过期。如果您无法访问此链接,请将整个 URL 复制并粘贴到浏览器中,谢谢! 猴王软件学院"

                    # 电子邮件回复地址(如果有)。

                    # reply-to: "361604199@qq.com"

                    # 电子邮件密送地址(如果有)。

                    # bcc:

                    # 电子邮件抽送地址(如果有)。

                    # cc:

            

            jdbc:

                password-encoder:

                    # 要使用的编码算法,例如MD5。当使用的类型为DEFAULT或GLIBC_CRYPT时相关。

                    encoding-algorithm: "MD5"

                    # 可以使用类型

                    type: "DEFAULT"

                    # Secret通常是一个可选设置。

                    # secret: "..."

                    # 用于密码哈希的强度或迭代次数。

                    strength: "32"

                    # 要使用的编码算法,如“UTF-8”。当使用的类型为DEFAULT时相关。

                    character-encoding: "UTF-8"

                    

                # 用于连接数据库的JDBC驱动程序。

                driver-class: "com.mysql.cj.jdbc.Driver"      

                # 数据库方言是独立于平台的软件(JPA、Hibernate等)的配置设置,

                # 它允许此类软件将其通用SQL语句转换为特定于供应商的DDL、DML。

                dialect: "org.hibernate.dialect.HSQLDialect"                

                # 数据库连接URL。

                url: "jdbc:mysql://localhost:3306/cas?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true"

                # 数据库用户。

                user: "root"

                # 数据库连接密码。

                password: "123456"

                # SQL查询来更改和更新密码。

                sql-change-password: "UPDATE pm_table_accounts SET password = ? WHERE userid=?"

                # SQL查询以定位用户电子邮件地址。

                sql-find-email: "SELECT email FROM pm_table_accounts WHERE userid=?"

                # SQL查询以定位用户电话号码。

                sql-find-phone: "SELECT phone FROM pm_table_accounts WHERE userid=?"

                # 通过用户定位用户的SQL查询。

                sql-find-user: "SELECT userid FROM pm_table_accounts WHERE email=?"

                # SQL查询以查找帐户的安全问题(如果有的话)。

                sql-get-security-questions: "SELECT question, answer FROM pm_table_questions WHERE userid=?"

                

    jdbc:

        # SQL 查询是否应显示在控制台/日志中。

        show-sql: "true"

        # 选择物理表名称时,确定名称是否应视为不区分大小写。

        case-insensitive: "false"

        # 是否在EntityManagerFactory初始化/更新所有相关表之后生成DDL。

        # gen-ddl: "true"

    

    # logout:

        # 注销之前,允许在 Web 界面上确认选项。

        # confirm-logout: "true"

        # 是否应允许 CAS 在注销后重定向到备用位置。

        # follow-service-redirects: "true"

        # 在此处,将指示 CAS 在注销后应重定向到的目标目标,并按您选择的参数名称提取。

        # 如果未指定,则默认值将用作 service。

        # redirect-parameter: ""

        # CAS 必须在所有注销作完成后立即重定向到的 URL。

        # 在 CAS 充当代理并需要重定向到外部身份提供商的注销端点以删除会话等情况下,通常很有用。

        # redirect-url: "https://casserver.houwang.edu:8443/cas/logout"

  

    # slo:

        # 是否应通过 HTTP 客户端以异步方式完成 SLO 回调。

        # 如果为 true,则 CAS 不会等待作完全完成,而是恢复控制以继续进行。

        # asynchronous: "true"

        # 是否应为 CAS 部署全局完全禁用 SLO。

        # disabled: "false"

        # 注销传播类型确定如何将 SLO 请求发送到应用程序。

        # 当使用前通道机制处理 SLO 请求时,这尤其适用。

        # logout-propagation-type: "AJAX"

        

    # sso:

        # 指示是否应为服务器全局启用并支持单点登录。

        # sso-enabled: "true"

        # 指示是否在重新续订的身份验证事件上创建 SSO 会话的标志。

        # create-sso-cookie-on-renew-authn: "true"

        # 指示此服务器实现是否支持 CAS 代理身份验证/票证。

        # proxy-authn-enabled: "true"

        # 指示此服务器实现是否应全局支持标记为“renew=true”的 CAS 协议身份验证请求。

        # renew-authn-enabled: "true"

        #

        # services:

            # 默认情况下,如果初始身份验证请求未识别目标应用程序,CAS 将显示通用成功页面。

            # allow-missing-service-parameter: "true"

            # 一种正则表达式模式,表示一个应用程序,

            # 该应用程序必须先与 CAS 建立会话,然后 CAS 才能允许访问其他应用程序。

            # required-service-pattern: "..."

    

    # service-registry:

        # json:

            # 在 CAS 能够自动监视底层资源的更改并动态检测更新和修改的情况和场景中。

            # location: "classpath:/services"

        # core:

            # 当设置为 true 时,CAS 会为已注册服务的特定预选字段创建内存中索引,

            # 从而允许它按其友好名称、客户端 ID 等查找服务定义。

            # index-services: "true"

            # 指示是否应将默认随 CAS 附带的服务定义包含在初始化过程中并导入到 CAS 服务注册表中的标志。

            # init-default-services: "true"

            # 您还可以通过 #isInitDefaultServices() 控制是否应包含和初始化 default 服务。

            # init-from-json: "true"

            

    # view:

        # default-redirect-url: "https://casserver.houwang.edu:8443/cas/logout"

    

    # tgc:

        # 如果发送此 cookie 应仅限于安全协议,则为 true,

        # 如果可以使用任何协议发送,则为 false。

        # secure: "false"

        

    server:

        name: "https://casserver.houwang.edu:8443"

        prefix: "https://casserver.houwang.edu:8443/cas"

    # ssl:

        # key-store: thekeystore

        # key-store-password: "changeit"

        # key-password: "changeit"

    

    # view:

        # 可以找到CAS模板的逗号分隔路径。

        # template-prefixes: "classpath:templates/casclient1,classpath:templates/casclient2"

        

    # theme:

        # 此CAS部署的默认主题名称。

        # default-theme-name: "cas-theme-default"

        # 此主题的描述以描述其目的

        # description: "CAS Theme Description"

        # 主题的名称用于各种标题/标题。

        # name: "cas-theme"

        # 用于切换主题的参数名称。

        # param-name: "theme"

        

spring:

    mail:

        # 默认MimeMessage编码。

        default-encoding: "UTF-8"

        # SMTP服务器主机。例如,smtp.example.com。

        host: "smtp.qq.com"

        # SMTP服务器端口。

        port: "465"

        # SMTP服务器使用的协议。

        protocol: "smtp"

        # 是否在启动时测试邮件服务器是否可用。

        test-connection: "true"

        # SMTP服务器的登录用户。

        username: "361604199@qq.com"

        # SMTP服务器的登录密码。

        password: "pcjgofodyebmcahi"

        properties:

            mail:

                smtp:

                    auth: "true"

                    starttls:

                        enable: "true"

                    ssl:

                        enable: "true"

    

    # 本地化

    locale:

        # 默认区域设置。

        default-value: "zh_cn"

        # 切换语言环境时要使用的参数名称。

        param-name: "locale"

        

    # 消息包

    message-bundle:

        # 表示此消息包的基本名称的字符串列表。

        base-names: "classpath:messages_zh_CN,classpath:messages"

        # 表示此消息包的常用名称的字符串列表。

        common-names: "classpath:/messages_zh_CN.properties"

        # 缓存大小。

        cache-seconds: "PT180S"

        # 消息包字符编码。

        encoding: "UTF-8"

        # 如果未显式指定语言环境,则控制是否回退到默认系统语言环境的标志。

        fallback-system-locale: "false"

        # 控制是否使用代码消息的标志。

        use-code-message: "true"

        

    thymeleaf:

        # 是否为Web框架启用Thymeleaf视图解析。

        enabled: "true"

      1. casclient1.properties

cas\src\main\resources\casclient1.properties

# 主题CSS文件的路径;多个文件可以逗号分隔。

cas.standard.css.file=/themes/casclient1/css/bootstrap.css

# 主题Javascript文件的路径;多个文件可以逗号分隔。

cas.standard.js.file=/themes/casclient1/js/bootstrap.js

# 在custom.html片段中找到的片段名称,包含在布局<head>标记中

cas.standard.fragments.head=

# 通过通用布局显示主题徽标的路径。

cas.logo.file=/images/logo.png

# 决定是否显示抽屉菜单。

cas.drawer-menu.enabled=true

# 各种标题/字幕中使用的主题名称。

cas.theme.name=CAS Client 1 Theme

# 各种标题/标题中使用的主题描述。

cas.theme.description=CAS Client 1 Theme Description

# 是否应显示密码管理/重置链接。

cas.pm-links.enabled=true

# 应显示CAS登录表单的时间。

cas.login-form.enabled=true

# 启用并显示通知菜单。

cas.notifications-menu.enabled=true

# 主题网站图标文件的路径。

cas.favicon.file=/themes/casclient1/images/favicon.ico

# 登录表单上“英雄”样式图像/徽标的路径。

cas.hero-banner.file=/themes/casclient1/images/cas-logo.png

# 是否应该包括核心/默认Javascript库。

cas.js.core.enabled=true

# 是否应该包括核心/默认CSS库。

cas.css.core.enabled=true

# 登录时是否应显示属性/应用程序。

cas.successful-login.display-attributes=true

# 用户是否可以在登录时指示公共工作站选项。

cas.public-workstation.enabled=false

# 在重定向到应用程序之前是否应警告用户。

cas.warn-on-redirect.enabled=false

# 读取/写入浏览器存储数据时是否显示进度。

cas.browser-storage.show-progress=true

# 是否显示CAS页脚。

cas.footer.show=true

# 是否在页脚中显示CAS版本详细信息…

cas.footer.show-version=true

      1. Casclient2.properties

cas\src\main\resources\casclient2.properties

# 主题CSS文件的路径;多个文件可以逗号分隔。

cas.standard.css.file=/themes/casclient2/css/bootstrap.css

# 主题Javascript文件的路径;多个文件可以逗号分隔。

cas.standard.js.file=/themes/casclient2/js/bootstrap.js

# 在custom.html片段中找到的片段名称,包含在布局<head>标记中

cas.standard.fragments.head=

# 通过通用布局显示主题徽标的路径。

cas.logo.file=/images/logo.png

# 决定是否显示抽屉菜单。

cas.drawer-menu.enabled=true

# 各种标题/字幕中使用的主题名称。

cas.theme.name=CAS Client 2 Theme

# 各种标题/标题中使用的主题描述。

cas.theme.description=CAS Client 2 Theme Description

# 是否应显示密码管理/重置链接。

cas.pm-links.enabled=true

# 应显示CAS登录表单的时间。

cas.login-form.enabled=true

# 启用并显示通知菜单。

cas.notifications-menu.enabled=true

# 主题网站图标文件的路径。

cas.favicon.file=/themes/casclient2/images/favicon.ico

# 登录表单上“英雄”样式图像/徽标的路径。

cas.hero-banner.file=/themes/casclient2/images/cas-logo.png

# 是否应该包括核心/默认Javascript库。

cas.js.core.enabled=true

# 是否应该包括核心/默认CSS库。

cas.css.core.enabled=true

# 登录时是否应显示属性/应用程序。

cas.successful-login.display-attributes=true

# 用户是否可以在登录时指示公共工作站选项。

cas.public-workstation.enabled=false

# 在重定向到应用程序之前是否应警告用户。

cas.warn-on-redirect.enabled=false

# 读取/写入浏览器存储数据时是否显示进度。

cas.browser-storage.show-progress=true

# 是否显示CAS页脚。

cas.footer.show=true

# 是否在页脚中显示CAS版本详细信息…

cas.footer.show-version=true

      1. messages.properties

cas\src\main\resources\messages.properties

screen.welcome.security=For security reasons, please <a href="logout">log out</a> and exit your web browser when you are done accessing \

  services that require authentication!

screen.welcome.cas.client1=CAS Client 1 Login Form

screen.welcome.cas.client2=CAS Client 2 Login Form

screen.welcome.instructions=Enter Username & Password

screen.welcome.forcedsso=Welcome back, <code><strong>{0}</strong></code>. We have detected an existing single sign-on session for you. However, \

  you are being asked to re-authenticate again as CAS cannot successfully accept your previous single sign-on participation status which may be \

  related to the policy assigned to <code><strong>{1}</strong></code>. Please enter your Username and Password and proceed.

screen.welcome.label.source=Source:

screen.welcome.label.token=Token:

screen.welcome.label.netid=<span class="accesskey">U</span>sername:

screen.welcome.label.netid.accesskey=u

screen.welcome.label.password=<span class="accesskey">P</span>assword:

screen.welcome.label.password.accesskey=p

screen.welcome.label.publicstation=I am at a public workstation.

screen.welcome.label.warn=Warn me before redirecting to applications

screen.welcome.label.warn.accesskey=w

screen.welcome.label.warnremove=Do not warn me again

screen.welcome.button.login=Login

screen.welcome.button.logout=Logout

screen.welcome.button.loginwip=One moment please...

screen.welcome.button.register=Register

screen.welcome.button.deregister=Deregister

screen.welcome.button.print=Print

screen.welcome.button.clear=Clear

screen.welcome.button.clean=Clean

screen.welcome.button.confirm=Confirm

screen.welcome.button.options=Options

screen.welcome.button.search=Search

screen.welcome.label.loginwith=External Identity Providers

screen.welcome.label.navto=Navigating to external identity provider <strong>{0}</strong>. Please wait...

screen.welcome.button.loginx509=Login w/ Certificate

screen.cookies.disabled.title=Cookies Disabled

screen.cookies.disabled.message=Your browser does not support cookies. The browser's ability to store or read cookies \

  is essential for single sign-on to work. Please consult your browser settings and ensure cookie support is turned on.

screen.processing.title=Processing Request

screen.processing.text=CAS is processing request. This might take a few seconds. Please stand by and do not close your browser.

screen.browser.js.disabled.title=Unsupported Browser

screen.browser.js.disabled.text=Your browser has disabled or does not support Javascript. Without Javascript, we are unable to process your request at this time. \

  Examine your browser settings, extensions, addons, etc. and ensure the browser is able to accept and enable support for Javascript. Then, close your browser, \

  and start again.

screen.acct.button.signUp=Sign Up

screen.pm.button.submit=Submit

screen.pm.button.cancel=Cancel

screen.pm.button.close=Close

screen.pm.button.forgotpwd=<a href="{0}">Forgot your password? </a>

screen.pm.button.resetPassword=Reset your password

screen.pm.button.forgotUsername=Forgot your username?

screen.pm.reset.username=Username:

screen.pm.reset.email=Email:

screen.pm.reset.heading=Password Reset Failed

screen.pm.reset.message=We were unable to process your password reset request at this time.

screen.pm.reset.qstitle=Answer Security Questions

screen.pm.reset.qsmsg=Welcome <strong>{0}</strong>. Before you can reset your password, you must answer the following security questions.

screen.pm.reset.sentInstructions=You should shortly receive a message with follow-instructions to reset your password. Please do not take \

  long as the password reset instructions may expire.

screen.pm.reset.sent=Password Reset Instructions Sent Successfully.

screen.pm.reset.title=Reset your password

screen.pm.reset.instructions=Please provide your username. You will receive a notification with follow-up instructions on how to reset your password.

screen.pm.reset.answer=Answer {0}

screen.pm.reset.question=Question {0}

screen.pm.password.policyViolation=Password does not match the password policy requirement.

screen.pm.password.confirmMismatch=Passwords do not match.

screen.pm.password.strength=Strength:

screen.pm.password.strength.0=Worst

screen.pm.password.strength.1=Bad

screen.pm.password.strength.2=Weak

screen.pm.password.strength.3=Good

screen.pm.password.strength.4=Strong

screen.pm.password.toggle=Toggle password

screen.pm.password.generate=Generate password

screen.pm.weak.title=Weak Password

screen.pm.weak.heading=Weak Password Detected

screen.pm.weak.message=Your password does not meet our security requirements. \

  A strong password is essential to protect your account \

  from unauthorized access and potential security threats. \

  Continue here to choose a new password that meets the password policy requirements, and \

  make sure your new password is unique and not used for any other accounts.

screen.pm.reset.contact.failed=Unable to send email/SMS as no email/SMS server is defined in the CAS configuration.

screen.pm.reset.username.required=No email is provided.

screen.pm.reset.contact.invalid=Provided contact information is missing or invalid.

screen.pm.reset.email.invalid=Provided email address is invalid.

screen.pm.reset.username.failed=Failed to send the username to the given email address.

screen.pm.forgotusername.title=Forgot your username?

screen.pm.forgotusername.instructions=Please provide your email address. You will receive an email with your username.

screen.pm.forgotusername.email.failed=Unable to send email as no email server is defined in the CAS configuration.

screen.pm.forgotusername.email.invalid=No email is provided, or the given address is invalid.

screen.pm.forgotusername.contact.invalid=Provided email address or phone number is invalid.

screen.pm.forgotusername.username.missing=No username could be located for the given email address.

screen.pm.forgotusername.username.failed=Failed to send the username to the given email address.

screen.pm.forgotusername.sent=Instructions Sent Successfully.

screen.pm.forgotusername.sentInstructions=You should shortly receive a message with follow-instructions to how to retrieve your username.

screen.aup.heading=Acceptable Usage Policy

screen.aup.policyterms=<p>The purpose of this policy is to establish acceptable and unacceptable use of electronic devices \

and network resources in conjunction with the established culture of ethical and lawful behavior, openness, trust, and integrity.</p> \

<p>By using these resources, you agree to abide by the Acceptable Usage Policy.</p>

screen.aup.button.accept=ACCEPT

screen.aup.button.cancel=CANCEL

screen.saml.idp.discovery=SAML2 Identity Provider Discovery

screen.consent.confirm=Confirm

screen.consent.cancel=Cancel

screen.consent.title=Attribute Consent

screen.consent.attributes=Attributes

screen.consent.options=Options

screen.consent.attributes.header=The following attributes will be released to <strong>[{0}]</strong>:

screen.consent.attributes.attribute=Attribute

screen.consent.attributes.values=Value(s)

screen.consent.options.header=How should I be prompted for consent again?

screen.consent.options.always=<strong>Every Time</strong>

screen.consent.options.desc.always=Show the consent screen every time I attempt to log into {0}.

screen.consent.options.attributename=<strong>Attribute Name</strong>

screen.consent.options.desc.attributename=Show the consent screen, if an attribute is added or removed from the collection of attributes released to {0}.

screen.consent.options.attributevalue=<strong>Attribute Value</strong>

screen.consent.options.desc.attributevalue.intro=Show the consent screen, if:

screen.consent.options.desc.attributevalue.first=A new attribute is authorized for release to {0}.

screen.consent.options.desc.attributevalue.second=An attribute is removed from the attribute bundle previously released to {0}.

screen.consent.options.desc.attributevalue.third=The value of an attribute authorized for release to {0} has changed.

screen.consent.options.reminder.header=How often should I be reminded to consent again?

screen.consent.options.reminder.expl=Show the consent screen, as a reminder, in the event that there is no change to the collection of attributes released to {0}.

screen.consent.options.timeunit.seconds=Seconds

screen.consent.options.timeunit.minutes=Minutes

screen.consent.options.timeunit.hours=Hours

screen.consent.options.timeunit.days=Days

screen.consent.options.timeunit.weeks=Weeks

screen.consent.options.timeunit.months=Months

screen.consent.options.timeunit.years=Years

screen.consent.review.header=Review Attribute Consent

screen.consent.review.loading=Loading consent decisions...

screen.consent.review.noconsentdecisions=There are no consent decisions registered for you.

screen.consent.review.success=Consent decision was deleted successfully.

screen.consent.review.error=There was an error!

screen.consent.review.confirm=Delete consent decision for [{}]?

screen.consent.review.yes=Yes

screen.consent.review.no=No

screen.consent.review.date=Date

screen.consent.review.service=Service

screen.consent.review.delete=DELETE

screen.consent.review.createddate=Created Date:

screen.consent.review.reminder=Reminder:

screen.consent.review.option=Option:

screen.consent.review.options.attributename=Attribute Name

screen.consent.review.options.attributevalue=Attribute Value

screen.consent.review.options.always=Always

screen.consent.review.options.desc.always=Show the consent screen every time I attempt to log in.

screen.consent.review.options.desc.attributename=Show the consent screen, if an attribute is added or removed from the collection of attributes released.

screen.consent.review.options.desc.attributevalue=Show the consent screen, if 1) a new attribute is authorized for release, 2) an attribute is removed from the attribute bundle previously released, 3) the value of an attribute authorized for release has changed.

screen.consent.review.attributes=Attributes:

screen.consent.review.data.search=Search

screen.consent.review.data.zerorecords=No matching decisions found

screen.consent.review.data.info=Showing _START_ to _END_ of _TOTAL_ entries

screen.consent.review.data.infofiltered=(filtered from _MAX_ total entries)

screen.consent.review.data.infoempty=No decisions to show

screen.consent.review.logout.success=You have successfully logged out of the Consent Review page. You may completely <a href="../logout">log out</a> of the Central Authentication Service and end your single sign-on session.

screen.delegation.unauthz.error.title=Error

screen.delegation.unauthz.reason.title=Reason

screen.delegation.unauthz.code.title=Code

screen.delegation.unauthz.description.title=Description

screen.delegation.unauthz.provider.title=Provider

screen.delegation.unauthz.destination.title=Destination

screen.nonsecure.title=Non-secure Connection

screen.nonsecure.message=You are currently accessing CAS over a non-secure connection. Single Sign On WILL NOT WORK. In order to have single sign on work, you MUST log in over HTTPS.

screen.accountunlocked.heading=Your account is now unlocked.

screen.account.unlock.description=Your account has been locked and is unable to login. Please follow the instructions \

  on the screen to unlock your account and then try to log in again.

screen.account.unlock.label=Image Text

screen.account.unlock.hint=To continue, please enter the characters as you see in the image.

screen.account.unlock.fail=CAS is unable to reset and unlock your account. Contact your CAS administrator for more info.

screen.account.unlock.success=Your account status is now unlocked. Note that this change might take some time to fully take effect. \

  You should now be able to log in and proceed.

screen.defaultauthn.title=Static Authentication

screen.defaultauthn.heading=CAS is configured to accept a static list of users for primary authentication. This is <strong>ONLY</strong> useful for \

  demo purposes. It is recommended that you connect CAS to LDAP, JDBC, etc. instead.

logo.title=go to Apereo home page

copyright=Copyright © 2005–2024 Apereo, Inc.

poweredBy=Powered by

screen.capslock.on = CAPSLOCK key is turned on!

screen.button.continue=Continue

screen.post.response.message=You are being redirected to {0}.

screen.interrupt.title=Authentication Interrupt

screen.interrupt.message=The authentication flow has been interrupted for <strong>{0}</strong>.

screen.mdui.infolink.text=<a href="{0}" target="_blank">More information about this application</a>.

screen.mdui.privacylink.text=<a href="{0}" target="_blank">Privacy statement for application</a>.

screen.interrupt.btn.proceed=Proceed

screen.interrupt.btn.cancel=Cancel

# Generic Error Pages 401, 404, 500, etc

########################################

screen.error.page.heading=Error

screen.error.page.invalidrequest.title=Unknown Request

screen.error.page.invalidrequest.desc=The authentication request submitted to CAS is invalid, incorrectly constructed, \

  or contains parameters that are seen as invalid or expired. Please review the original request, consult CAS logs and try again.

screen.error.page.invalidrequest=Invalid/Unknown Request

screen.error.page.title.accessdenied=Error - 401

screen.error.page.title.permissiondenied=Error - Permission Denied

screen.error.page.title.pagenotfound=Error - Page Not Found

screen.error.page.title.requestunsupported=Error - Unsupported Request

screen.error.page.title.unprocessable=Error - Unprocessable Request

screen.error.page.accessdenied=Access Denied

screen.error.page.permissiondenied=You do not have permission to view this page.

screen.error.page.unprocessable=CAS is unable to process this request. The request is either malformed, contains \

  unrecognized parameters that are not supported by CAS, or has become stale or instructs CAS to activate a \

  particular authentication flow that is either invalid or unrecognized. It may also be that log in session has timed out \

  and you waited too long before logging in. <p>Please <strong>close extraneous browser windows, remove all browser cookies, clear your \

  browser cache and start clean again</strong> to remove traces of all previous sessions and possible invalid data.</p>

screen.error.page.requestunsupported=The request type or syntax is not supported.

screen.error.page.loginagain=Login Again

screen.error.page.notfound=Page Not Found

screen.error.page.doesnotexist=The page you are attempting to access does not exist at the moment.

screen.error.page.authdenied=Authorization Denied

screen.checkbox.decode.title=Decode

screen.checkbox.scrolllogs.title=Scroll to the end and follow logs

# Remember-Me Authentication

screen.rememberme.checkbox.title=Remember Me

# Gua

screen.gua.confirm.message=If you do not recognize this image as yours, do NOT continue.

# Blocked Errors Page

screen.error.page.title.blocked=Error - Permission Denied

screen.blocked.header=Access Denied

screen.blocked.message=You've entered the wrong password for the user too many times. You've been throttled.

AbstractAccessDecisionManager.accessDenied=You are not authorized to access this resource. Contact your CAS administrator for more info.

screen.authentication.error.title=Authentication Failure

# Confirmation Screen Messages

screen.confirmation.message=You asked to be warned before logging into applications. Please proceed.

screen.authentication.warning=Authentication Succeeded with Warnings

# Account Profile Messages

screen.account.success=You, <strong>{0}</strong>, have successfully logged into the Central Authentication Service. This page allows you to \

  review and manage your account profile and verify the collection of person attributes retrieved by CAS.

screen.account.security=When you are finished, for security reasons, please <a href="logout">log out</a> and exit your web browser.

screen.account.tooltip.logout=This operation forces a logout prior to changing the password.

screen.account.failure=Operation Failure

screen.account.securityquestions.subtitle=You can review and update your security questions here. \

  Remember that all security questions and answers <strong>MUST</strong> be unique. \

  Duplicate questions or answers are rejected by CAS.

screen.account.accesstokens.title=Access Tokens

screen.account.accesstokens.subtitle=These are the access tokens that are issued to you by CAS and are used to access various services and applications.

screen.account.mfadevices.devicepanel.title=Device Registration Details

screen.account.mfadevices.devicepanel.text=Here are the details for this record entry.

screen.account.mfadevices.register.success=Your device is now registered with CAS and may be used for multifactor authentication requests.

screen.account.mfadevices.title=Multifactor Authentication Devices

screen.account.mfadevices.subtitle=The following devices are registered under your account and may be used for multifactor authentication.

screen.account.auditlog.title=Audit Log

screen.account.auditlog.subtitle=Examine your audited authentication activity as recorded and captured by CAS.

screen.account.securityquestions.title=Manage Security Questions

screen.account.securityquestions.failure=Unable to accept and update your security questions.

screen.account.securityquestions.success=Security questions are now accepted and updated successfully.

screen.account.sessions=Review your active single sign-on sessions registered with CAS across all your devices and browsers.

screen.account.applications=There are applications registered with CAS for which CAS is authorized to allow you to access.

screen.account.attributes=These are the attributes that CAS has found and attached to your authenticated profile. \

  These attributes are included in the pool of available attributes that may be shared and released to applications.

screen.account.consent.title=Attribute Consent Decisions

screen.account.consent.subtitle=These are the attribute consent decisions that CAS has found and attached to your authenticated profile.

screen.account.consent.always=Always

screen.account.consent.attribute_name=Attribute Name Changes

screen.account.consent.attribute_value=Attribute Value Changes

screen.account.trusteddevices.title=Multifactor Authentication Trusted Devices

screen.account.trusteddevices.subtitle=Multifactor authentication trusted devices are listed here.

screen.account.trusteddevices.devicepanel.title=Device Registration Details

screen.account.trusteddevices.devicepanel.text=Here are the details for this record entry.

# Generic Success Screen Messages

screen.success.header=Log In Successful

screen.success.success=You, <strong>{0}</strong>, have successfully logged into the Central Authentication Service. However, you are seeing \

  this page because CAS does not know about your target destination and how to get you there. Examine the authentication request again and \

  make sure a target service/application that is authorized and registered with CAS is specified.

screen.success.security=When you are finished, for security reasons, please <a href="logout">log out</a> and exit your web browser.

# Logout Screen Messages

screen.logout.confirm.header=Do you, <strong>{0}</strong>, want to log out completely?

screen.logout.confirm.text=<p>An application may have redirected you to the Central Authentication Service \

  to completely log you out and destroy your single sign-on session. If you choose to log out, you will be asked again \

  to provide your credentials and login again once you attempt to access an application.</p>

screen.logout.confirm.proceed=Do you want to proceed?

screen.logout.header=Logout successful

screen.logout.success=You have successfully logged out of the Central Authentication Service. You may <a href="login">log in</a> again.

screen.logout.fc.success=You have successfully logged out of the Central Authentication Service. Given single logout is enabled with CAS, \

  the following list of applications are <strong> only notified</strong> to log you out and destroy your user session. Remember that this \

  is just a notification, not a guarantee. It is up the application itself to honor these notifications and properly take action to log you \

  out.

screen.logout.security=For security reasons, exit your web browser.

screen.logout.pending=Logout request pending…

screen.service.wildcard.message=This application does not have a dedicated registration entry in the CAS service registry. \

  It is authorized and allowed by CAS because there exists a wildcarded service definition entry in the CAS service registry \

  that allows and accepts authentication requests from unknown applications such as this one. \

  <p/>As a security best practice, it is strongly recommended to limit the service management facility to <strong>only include the list of \

  known applications</strong> that are explicitly authorized to use CAS. Leaving the management interface open for all applications \

  may create an opportunity for security attacks and will make it difficult to audit application requirements and attribute needs.

screen.service.sso.error.header=Re-Authentication Required to Access this Service

screen.service.sso.error.message=You attempted to access a service that requires authentication without re-authenticating.  Please try authenticating again</a>.

screen.service.required.message=You attempted authentication without specifying the target application. Please re-examine the request and try again.

screen.service.initial.message=Attempting to access CAS or the indicated target application is disallowed at this time. \

  The authentication policy requires that you change your starting application \

  and then move onto other applications and services.

captchaError=reCAPTCHA’s validation failed.

username.required=Username is a required field.

password.required=Password is a required field.

source.required=Authentication source is a required field.

# Password Management

confirmedPassword.required=Password must be confirmed.

pm.passwordsMustMatch=Provided passwords do not match.

pm.passwordFailedCriteria=Provided password does not satisfy the password security policy. Please try again.

pm.updateFailure=Account password could not be modified. Please try again.

# Authentication failure messages

authenticationFailure.AccountDisabledException=This account has been disabled.

authenticationFailure.AccountLockedException=This account has been locked.

authenticationFailure.AccountExpiredException=This account has expired and is forbidden to log in at this time.

authenticationFailure.CredentialExpiredException=Your password has expired.

authenticationFailure.InvalidLoginLocationException=You cannot log in from this workstation.

authenticationFailure.UniquePrincipalRequiredException=You cannot log in at this time, since you have another active single sign-on session in progress \

  and CAS is configured with an authentication policy the prevents multiple concurrent single sign-on sessions.

authenticationFailure.InvalidLoginTimeException=Your account is forbidden to log in at this time.

authenticationFailure.AccountNotFoundException=Your account is not recognized and cannot log in at this time.

authenticationFailure.FailedLoginException=Authentication attempt has failed, likely due to invalid credentials. Please verify and try again.

authenticationFailure.MultifactorAuthenticationProviderAbsentException=Unable to satisfy multifactor authentication requirements. \

  Your account is configured for a multifactor authentication strategy, yet CAS is unable to locate and execute that strategy \

  most likely due to misconfiguration of the server. Contact the service administrators for assistance.

authenticationFailure.SurrogateAuthenticationException=You are not authorized to impersonate the indicated user at this time.

authenticationFailure.AccountPasswordMustChangeException=Your account password has expired and must be changed.

authenticationFailure.UnauthorizedServiceForPrincipalException=Service access denied due to missing privileges.

authenticationFailure.MultifactorAuthenticationRequiredException=Authentication attempt for your account is denied, \

  because your account is not yet configured to go through multifactor authentication. Contact the service administrators \

  for assistance, make sure your account is enrolled and eligible for multifactor authentication and try again.

authenticationFailure.RiskyAuthenticationException=CAS is unable to proceed with the authentication flow, likely because this authentication attempt \

  is determined to be risky and suspicious with a high-enough risk score above the accepted threshold. It may be that your attempt at \

  authentication is blocked because you are using an unknown web browser, or you are logging in from an unknown location. \

  For additional information and guidance, please contact your administrator and/or help desk.

authenticationFailure.UNKNOWN=Authentication attempt has failed.

authenticationFailure.AuthenticationException=Credentials are rejected/invalid and authentication attempt has failed.

INVALID_REQUEST_PROXY=The request is incorrectly formatted. Ensure all required parameters are properly encoded and included.

INVALID_TICKET_SPEC=Ticket failed validation specification. Possible errors could include attempting to validate a Proxy Ticket via a Service Ticket validator, or not complying with the `renew=true` request.

INVALID_REQUEST=Unable to identify, authorize or complete this request, likely due to malformed or missing required parameters.

INVALID_AUTHENTICATION_CONTEXT=The validation request for [''{0}''] cannot be satisfied. The request is either unrecognized or unfulfilled.

INVALID_TICKET=Ticket ''{0}'' not recognized

INVALID_PROXY_GRANTING_TICKET=PGT already generated for this ST. Cannot grant more than one PGT for ST

INVALID_SERVICE=Ticket ''{0}'' does not match supplied service. The original service was ''{1}'' and the supplied service was ''{2}''.

INVALID_PROXY_CALLBACK=The supplied proxy callback url ''{0}'' could not be authenticated. Either ''{0}'' cannot be reached, or it is not \

  allowed to exercise proxy authentication.

UNAUTHORIZED_SERVICE_PROXY=The supplied service ''{0}'' is not authorized to use CAS proxy authentication.

UNSATISFIED_AUTHN_POLICY=Service access denied due to an unsatisfied authentication policy.

INVALID_AUTHN_REQUEST=Authentication attempt has failed, likely due to invalid credentials.

BLOCKED_AUTHN_REQUEST=Authentication attempt is blocked and cannot proceed, likely due to malformed or missing required parameters. \

  Examine the CAS server logs to locate the root cause of the error.

UNSATISFIED_SAML_REQUEST=The SAML authentication request cannot be understood, accepted or validated by CAS, \

  likely due to malformed or missing required parameters. Please examine the CAS server logs to locate the root cause of the error.

screen.service.error.header=Application Not Authorized to Use CAS

screen.service.error.redirect=You are not authorized to access this application. Please be patient as you are about \

  to be redirected to <strong>{0}</strong> to learn more about this scenario.

service.principal.resolution.error=CAS is unable to determine the correct authentication principal. \

  Either the principal could not be resolved correctly as a single unique entity or CAS has found \

  mixed/multiple candidate principals and is unable to decide which should be used. \

  This error may also be caused if the authenticated principal is not allowed to access the target application \

  due to missing privileges set by the CAS server authorization policies.

service.not.authorized.missing.attr=You are not authorized to access the application as your account \

is missing privileges required by the CAS server to authenticate into this service. Please notify your support desk.

screen.service.error.message=The application you attempted to authenticate to is not authorized to use CAS. \

  This usually indicates that the application is not registered with CAS, or its authorization policy defined in its registration record \

  prevents it from leveraging CAS functionality, or it's malformed and unrecognized by CAS. \

  Contact your CAS administrator to learn how you might register and integrate your application with CAS.

screen.service.empty.error.message=The services registry of CAS is empty and has no service definitions. \

Applications that wish to authenticate with CAS must explicitly be defined in the services’ registry.

screen.service.expired.message=The application you attempted to authenticate to is expired in the CAS Service Registry. \

  If this service should still be considered in use, please contact the service administrators to have the application renewed.

# Surrogate Account Selection

screen.surrogates.account.selection.header=Impersonation Account Selection

screen.surrogates.choose.account=Choose Account

screen.surrogates.message=<p>You are provided with a list of accounts on behalf of which you are allowed to authenticate.</p> \

<p>Select one and continue.</p>

screen.surrogates.button.cancel=Cancel

screen.surrogates.account.selection.error=You are not authorized to impersonate the indicated user at this time.

screen.surrogates.wildcard.title=Impersonation Account Selection

screen.surrogates.wildcard.description=Your account is internally recognized by CAS as one with special permissions, \

  authorized to impersonate all users and accounts. Therefore, impersonation account selection is not allowed for your \

  account. Instead, you may directly proceed to log in and impersonate any other account using its username.

# Password policy

password.expiration.warning=Your password expires in {0} day(s). Please <a href="https://pm.example.edu">change your password</a> now.

password.expiration.loginsRemaining=You have {0} login(s) remaining before you <strong>MUST</strong> change your password.

screen.accountdisabled.heading=This account has been disabled.

screen.accountdisabled.message=Please contact the system administrator to regain access.

screen.accountlocked.heading=This account has been locked.

screen.accountlocked.message=Please contact the system administrator to regain access.

screen.expiredpass.heading=Hello, {0}. Your password has expired.

screen.expiredpass.message=Please <a href="{0}">change your password</a>.

screen.mustchangepass.heading=Hello, {0}. You must change your password.

screen.mustchangepass.message=Please <a href="{0}">change your password</a>.

screen.badhours.heading=Your account is forbidden to log in at this time.

screen.badhours.message=Please try again later.

screen.authnblocked.heading=Authentication attempt is blocked.

screen.authnblocked.message=Your authentication attempt is untrusted and unauthorized from your current workstation.

screen.risk.authnconfirmed.heading=Risky Authentication attempt is confirmed.

screen.risk.authnconfirmed.message=Risky Authentication attempt cannot be verified and confirmed.

screen.risk.authnblocked.heading=Authentication attempt is blocked.

screen.risk.authnblocked.message=Your authentication attempt is untrusted and unauthorized from your current workstation.

screen.badworkstation.heading=You cannot log in from this workstation.

screen.badworkstation.message=Please contact the system administrator to regain access.

screen.button.changePassword=Change Password

screen.pm.success.header=Password Change Successful

screen.pm.success.message=Your account password is successfully updated.

screen.pm.confirmpsw=Confirm Password:

screen.pm.enterpsw=Enter Password:

screen.pac4j.authn.TechnicalException=Unable to locate or parse identity provider configuration, most likely due to misconfiguration. \

  Review logs to find the root cause of the issue.

screen.pac4j.authn.unknown=Authentication response provided to CAS by the external identity provider cannot be accepted.

screen.pac4j.unauthz.pagetitle=Unauthorized Access

screen.pac4j.unauthz.gotoapp=Go to Application

screen.pac4j.unauthz.login=Back to CAS

screen.pac4j.unauthz.heading=Unauthorized Access

screen.pac4j.unauthz.message=Either the authentication request was rejected/cancelled, or the authentication provider denied access due \

  to permissions, etc. Review logs to find the root cause of the issue.

screen.pac4j.button.retry=Try Again

screen.pac4j.discovery.intro=Please provide your username or email address so CAS can locate the correct identity provider for your account.

screen.pac4j.discovery.unknownclient=Delegated identity provider cannot be found based for this request.

screen.pac4j.button.selectprovider=Select Identity Provider

screen.pac4j.discovery.title=Delegated Authentication Dynamic Discovery

screen.pac4j.authn.SAMLException=Authentication response provided to CAS by the external identity provider cannot be accepted. \

  Please examine the CAS server logs and configuration to locate the root cause of the issue, and then try again.

screen.pac4j.authn.SAMLIssueInstantException=Authentication response provided to CAS by the external identity provider cannot be accepted \

    because the authentication issue instant, given the present CAS configuration, is either too old or set in the future.

screen.pac4j.credential-selection.title=Delegated Authentication Profile Selection

screen.pac4j.credential-selection.intro=CAS has found multiple profiles associated with your user account. Please choose the account \

  with which you wish to login and proceed.

screen.delauthn.error.header=Delegated Authentication Failure

screen.delauthn.error.message=CAS is unable to complete the delegated authentication scenario, \

or redirect to the selected identity provider. Please examine the original authentication request and try again. \

You may need to close your browser and start again.

# GAuth

screen.authentication.gauth.qrimage=QR code

screen.authentication.gauth.register=Your account is not registered.

screen.authentication.gauth.registerdesc=Use the below settings to register your device with CAS.

screen.authentication.gauth.key=Secret key to register is: <pre>{0}</pre>

screen.authentication.gauth.scratchcodes=Scratch codes:

screen.authentication.gauth.selecteddevice=Your selected device for multifactor authentication is: <code>{0}</code>.

screen.authentication.gauth.selanotherdevice=You can select another device for multifactor authentication, if <code>{0}</code> is not your current device.

screen.authentication.gauth.name=Device Name:

screen.authentication.gauth.cancel=Cancel

screen.authentication.gauth.reganotherdevice=You can also register another device to use for multifactor authentication.

screen.authentication.gauth.selectdevice=Select Device

screen.authentication.gauth.deletedevice=Delete Device

screen.authentication.gauth.invalid=Unable to accept this authentication request. The selected device or given credentials is invalid.

screen.authentication.gauth.invalidtoken=Unable to accept this token. The given token is invalid, does not belong to the device or has expired.

screen.authentication.gauth.confirm.title=Confirm Account Registration

screen.authentication.gauth.confirm.desc=Confirm your account registration by providing a token \

from the authenticator app on your device. Once the token is validated, your account registration will be finalized.

screen.welcome.button.register-residentkey=Register Device with Discoverable Credentials

screen.authentication.webauthn.confirm.title=Confirm Account Registration

screen.authentication.webauthn.confirm.desc=Start the device registration process by assigning a friendly name to your FIDO2-enabled device.

screen.authentication.webauthn.name=Device Name

screen.authentication.webauthn.login.title=Login with FIDO2-enabled Device

screen.authentication.webauthn.login.desc=Use your registered FIDO2-enabled device to login. \

  To successfully perform this action, your username and device must already be registered with CAS.

screen.authentication.webauthn.authn.fail.title=Authentication Failed

screen.authentication.webauthn.authn.fail.desc=The authentication attempt has failed. Please make sure \

  your username and chosen device are registered with CAS.

# OAuth

screen.oauth.confirm.header=Authorization

screen.oauth.confirm.message=Do you want to grant access to "{0}" ?

screen.oauth.confirm.allow=Allow

screen.oauth.confirm.deny=Deny

cas.oauth.confirm.pagetitle=Approve Access

cas.oauth.device.confirm.header=Connect Device

cas.oauth.device.confirm.message=Enter the code displayed on your device to proceed.

cas.oauth.device.confirmed.header=Code Approved

cas.oauth.device.confirmed.message=Return to your device to continue.

cas.oauth.error.pagetitle=OAuth Error

cas.oauth.error.header=OAuth Authorization Error

OAUTH_BAD_SESSION_REQUEST=The OAuth request cannot be completed, as CAS is unable to locate or determine OAuth redirect URL. \

  This is usually an indication of a stale or mismatched request where the processed request session id is different from the \

  active session and may be caused by a complete logout operation. Clear cookies and history, restart your browser and try again please.

# OIDC

screen.oidc.confirm.ciba.header=Backchannel Authentication Request

screen.oidc.confirm.ciba.confirmed=Backchannel authentication request is now confirmed. Do not refresh this window. Instead, please close this browser window and \

  check your device for further instructions.

screen.oidc.confirm.ciba.failed=Backchannel authentication request could not be confirmed. Please check server logs and contact your CAS administrator for more info.

OIDC_CIBA_BAD_REQUEST=Backchannel authentication request has failed.

screen.oidc.confirm.bindingmessage.header=Binding Message

screen.oidc.confirm.bindingmessage.description=A human-readable identifier or message intended to be displayed on both \

  the consumption device and the authentication device to interlock them together for the transaction by way of a visual \

  cue for the end-user. This interlocking message enables the end-user to ensure that the action taken on the authentication \

  device is related to the request initiated by the consumption device.

screen.oidc.confirm.usercode.header=User Code

screen.oidc.confirm.usercode.description=A secret code, such as a password or pin, that is known only to the user but verifiable by CAS. \

  The code is used to authorize sending an authentication request to the user's authentication device.

screen.oidc.confirm.infourl=Learn more about {0}.

screen.oidc.confirm.privacyurl=Learn about {0} privacy rules.

screen.oidc.confirm.scopes=Scopes

screen.oidc.confirm.claims=Claims

screen.oidc.confirm.scope.profile=This requests access to the profile claims excluding the address and email claims.

screen.oidc.confirm.scope.email=This requests access to the email claims.

screen.oidc.confirm.scope.address=This requests access to the address claims.

screen.oidc.confirm.scope.openid=This indicates an OpenID Connect authorization request.

screen.oidc.confirm.scope.phone=This requests access to the phone claims.

screen.oidc.confirm.scope.offline_access=This requests access for a refresh token used for offline access.

screen.oidc.confirm.claim.name=End-User's full name in displayable form including all name parts, possibly including titles and suffixes, ordered according to the End-User's locale and preferences.

screen.oidc.confirm.claim.given_name=Given name(s) or first name(s) of the End-User. Note that in some cultures, people can have multiple given names; all can be present, with the names being separated by space characters.

screen.oidc.confirm.claim.middle_name=Middle name(s) of the End-User. Note that in some cultures, people can have multiple middle names; all can be present, with the names being separated by space characters. Also note that in some cultures, middle names are not used.

screen.oidc.confirm.claim.family_name=Surname(s) or last name(s) of the End-User. Note that in some cultures, people can have multiple family names or no family name; all can be present, with the names being separated by space characters.

screen.oidc.confirm.claim.email=End-User's preferred e-mail address.

screen.oidc.confirm.claim.preferred_username=MAY be any valid JSON string including special characters such as @, /, or whitespace. The RP MUST NOT rely upon this value being unique.

screen.oidc.confirm.claim.profile=URL of the End-User's profile page. The contents of this Web page SHOULD be about the End-User.

screen.oidc.confirm.claim.picture=URL of the End-User's profile picture. This URL MUST refer to an image file (for example, a PNG, JPEG, or GIF image file), rather than to a Web page containing an image. Note that this URL SHOULD specifically reference a profile photo of the End-User suitable for displaying when describing the End-User, rather than an arbitrary photo taken by the End-User.

screen.oidc.confirm.claim.phone_number=End-User's preferred telephone number. It is RECOMMENDED as the format of this claim. \

   For example, <code>+1 (425) 555-1212</code> or <code>+56 (2) 687 2400</code>.

screen.oidc.confirm.asksinfo=The client is asking for the following information:

screen.oidc.confirm.dynamic=This client was dynamically registered at <code>{0}</code>.

# Unavailable

screen.unavailable.header=CAS error

screen.unavailable.heading=CAS is unable to process this request: "{0}:{1}"

screen.unavailable.message=There was an error trying to complete your request. \

<strong>Please notify your support desk or try again.</strong> \

<p><div>Apereo is a non-profit open source software governance foundation. The CAS software is an Apereo sponsored project \

and is freely downloadable and usable by anyone. However, Apereo does not operate the systems of anyone using the \

software and in most cases doesn't even know who is using it or how to contact them unless they are an active part \

of the Apereo community.<br/></br>If you are having problems logging in using CAS, \

<strong>you will need to contact the IT staff or Help Desk of your organization for assistance</strong>. \

<br/><br/>We wish we could be more directly helpful to you.</div>

screen.mfaDenied.header=MFA Denied

screen.mfaDenied.heading=MFA attempt has been denied by provider

screen.mfaDenied.message=Your MFA provider has denied your attempt at second factor \

authentication. Contact your system administrator for help in restoring your account.

screen.mfaUnavailable.header=MFA Provider Unavailable

screen.mfaUnavailable.heading=MFA Provider Unavailable

screen.mfaUnavailable.message=CAS was unable to reach your configured MFA provider at this time. \

  Due to failure policies configured for the service you are attempting to access, authentication can not \

  be granted at this time.

#####################################################################

# Login View

#####################################################################

#Resources Labels

cas.login.pagetitle=Login

cas.login.resources.header=Resources

cas.login.resources.wiki=Documentation

cas.login.resources.endpoints=Actuator Endpoints

cas.login.resources.pulls=Pull Requests

cas.login.resources.mailinglist=Mailing Lists

cas.login.resources.chat=Chatroom

cas.login.resources.blog=Blog

cas.login.resources.support=Support

cas.login.resources.contribguide=Contributor Guidelines

####

# Acceptable Usage Policy View

#

cas.acceptableusagepolicyview.pagetitle=Acceptable Usage Policy View

##

# MFA

##

cas.mfa.providerselection.pagetitle=Multifactor Provider Selection

cas.mfa.providerselection.mfa-duo=Duo Security

cas.mfa.providerselection.mfa-duo.notes=Duo's wide variety of authentication methods enable every user to \

  securely and quickly log in. Duo Push, sent by the Duo Mobile authentication app, allows users to approve \

  push notifications to verify their identity.

cas.mfa.providerselection.mfa-webauthn=FIDO2 WebAuthn

cas.mfa.providerselection.mfa-webauthn.notes=WebAuthn is an API that makes it very easy for a relying party, \

  such as a web service, to integrate strong authentication into applications using support built in to all \

  leading browsers and platforms.

cas.mfa.providerselection.mfa-gauth=Google Authenticator

cas.mfa.providerselection.mfa-gauth.notes=Google Authenticator is a software-based authenticator that \

  implements two-step verification services for authenticating users of mobile applications by Google.

cas.mfa.providerselection.mfa-simple=CAS Multifactor Authentication

cas.mfa.providerselection.mfa-simple.notes=Allow CAS to act as a multifactor authentication provider on its own, \

  issuing tokens and sending them to end-users via pre-defined communication channels such as email or text messages.

cas.mfa.providerselection.mfa-yubikey=YubiKey Multifactor Authentication

cas.mfa.providerselection.mfa-yubikey.notes=Yubico is a cloud-based service that enables strong, easy-to-use \

  and affordable two-factor authentication with one-time passwords through their flagship product, YubiKey.

cas.mfa.duologin.pagetitle=Duo Security Login

cas.mfa.simple.contact-selection.title=Select Contact Information

cas.mfa.simple.contact-selection.description=We have found multiple ways to contact you for your account. Please choose the account(s) \

    where you would like to receive the multifactor authentication token.

cas.mfa.simple.pagetitle=CAS Multifactor Authentication Login

cas.mfa.simple.label.token=Token:

cas.mfa.simple.label.resend=Resend

cas.mfa.simple.label.tokensent=A multifactor authentication token is sent to you via an email or text message. \

  Please locate the token and submit it here to continue. Note that the token will expire after a short period of time \

  and will no longer be recognized by CAS, in which case, you may ask CAS to send you a new token.

cas.mfa.simple.label.contactfailed.sms=CAS is unable to use the selected contact information to send you an SMS with the \

  multifactor authentication token. Please review your contact information and contact your CAS administrator for assistance.

cas.mfa.simple.label.contactfailed.email=CAS is unable to use the selected contact information to send you an email with the \

  multifactor authentication token. Please review your contact information and contact your CAS administrator for assistance.

cas.mfa.simple.registration.title=Account Registration

cas.mfa.simple.registration.description=Your account is not registered for multifactor authentication even though \

  it is eligible and required by the application you are trying to access. Please <a href="https://account.example.org/mfa">register your account</a> for \

  multifactor authentication and ensure CAS has access to your contact information such as email address, phone, etc.

cas.mfa.googleauth.pagetitle=Google Authenticator

cas.mfa.googleauth.label.token=Token:

cas.mfa.radius.pagetitle=Radius Authentication

screen.authentication.yubikey.reganotherdevice=You can also register another device to use for multifactor authentication.

screen.authentication.yubikey.name=Device Name:

cas.mfa.yubikey.pagetitle=YubiKey Authentication

cas.mfa.yubikey.authenticate=Use your registered YubiKey device(s) to authenticate.

cas.mfa.yubikey.register=Your device is not yet registered. Use the below form to register your device with CAS.

cas.mfa.yubikey.register.fail=Unable to register your YubiKey device for authentication. Provided token may be invalid, expired or otherwise compromised.

cas.mfa.yubikey.label.token=Token:

cas.mfa.webauthn.auth.fail=Unable to verify your device for authentication. Provided payloads may be invalid, expired or otherwise compromised.

cas.mfa.webauthn.register.helptext=Assign a friendly-name to your FIDO2-enabled device and then register it with CAS for multifactor \

  authentication. Once device registration is successfully completed, you will automatically \

  be redirected to the next step to log in with your device.

cas.mfa.webauthn.register.wait=Your FIDO2-enabled device is now registered with CAS. Please wait…

cas.mfa.webauthn.register.discoverablecredentials=You may also register your device using <i>Discoverable Credentials / Resident Keys</i>. \

  This means that the private key and associated metadata is stored in persistent \

  memory on the authenticator and not on the CAS server.

cas.mfa.registerdevice.label.title=Register Device

cas.mfa.registerdevice.label.intro=Please name the current device.

cas.mfa.registerdevice.pagetitle=Register Device

cas.mfa.registerdevice.label.name=Name

cas.mfa.registerdevice.label.duration=How long should we remember this device?

cas.mfa.registerdevice.label.expiration=Expiration

cas.mfa.registerdevice.button.register=Register

cas.mfa.registerdevice.button.skip=Skip

cas.mfa.registerdevice.options.timeunit.forever=Forever

passwordless.token.header=Provide Token

passwordless.token.description=Please provide the security token sent to you via email, phone, etc. \

  Note that the token is valid for only a brief window and upon submission, all other tokens will be invalidated and removed.

passwordless.error.failure.title=Authentication Failure

passwordless.error.failure.description=The provided token could not be verified. It may have been invalidated, removed or expired.

passwordless.error.unknown.user=Provided username cannot be recognized and located by CAS.

passwordless.error.invalid.user=Provided username does not carry enough contact information.

passwordless.getuser.header=Passwordless Authentication

passwordless.getuser.description=Please provide your username to locate your account. Once your account is verified, \

  CAS will choose the appropriate authentication strategy for you.

cas.authn.qr.fail=Unable to accept authentication request based on QR code. Make sure the QR code is correctly scanned, \

  and provided credentials are valid, issued by this CAS server and have not expired.

# Inwebo

cas.inwebo.checkresult.title=Checking Inwebo authentication

cas.inwebo.checkresult.heading=Waiting for the Inwebo notification to be approved:

cas.inwebo.checkresult.message=Please validate it on your phone/desktop…

cas.inwebo.error.title=Inwebo authentication error

cas.inwebo.error.heading=An error has occurred.

cas.inwebo.error.userrefusedortoolate=You refused the authentication or did not validate it quickly enough.

cas.inwebo.error.usernotregistered=Before any login, you must be registered at Inwebo. Check your mailbox to \

  follow the enrollment process or fill in your activation and PIN codes below to enroll in your browser…

cas.inwebo.selectauthent.title=Select authentication

cas.inwebo.selectauthent.heading=Select your authentication method:

cas.inwebo.selectauthent.browser=Browser authentication

cas.inwebo.selectauthent.push=Mobile/desktop application authentication

cas.inwebo.browserauthent.title=Browser authentication

cas.inwebo.enroll.code=Activation code

cas.inwebo.enroll.button=Enroll for browser authentication

cas.inwebo.enroll.failure=The enrollment failed

cas.inwebo.pin=PIN code

cas.inwebo.pin2=PIN code confirmation

cas.inwebo.enroll.badpinconfirmation=PIN codes don't match

cas.inwebo.browser.heading=Fill in your PIN code:

cas.inwebo.browser.button=Log in in the browser

cas.inwebo.browser.failure=OTP generation error

cas.inwebo.retry.button=Retry the Inwebo multifactor authentication

cas.screen.acct.title=Account Registration

cas.screen.acct.intro=Please complete the form below to register your new account with CAS. \

  Once the form is submitted, you will receive an email with an account activation link to \

  enable your account, set up your password and begin using CAS.

cas.screen.acct.infosent=Account activation instructions are successfully sent. \

  Please check your email, etc. and follow the instructions.

cas.screen.acct.intro.complete=Welcome back! Thank you for verifying your account. \

  Please complete the form below to register your new account with CAS.

cas.screen.acct.intro.completed=Thank you! Your account is now activated and registered with CAS.

cas.screen.acct.button.submit=Submit

cas.screen.acct.button.cancel=Cancel

cas.screen.acct.button.update=Update

cas.screen.acct.error.provision=Unable to provision the requested account.

cas.screen.acct.error.fail=Unable to register the requested account, or send the account activation link.

cas.screen.acct.error.invalid-value=The provided value is missing, invalid or does not match the required pattern for the input type.

cas.screen.acct.label.email=Email Address

cas.screen.acct.title.email=This is your primary email address to which the activation link would be sent.

cas.screen.acct.label.firstName=First Name

cas.screen.acct.title.firstName=Your first name.

cas.screen.acct.label.lastName=Last Name

cas.screen.acct.title.lastName=Your last/surname.

cas.screen.acct.label.username=Username

cas.screen.acct.title.username=The username you wish to use for login attempts.

cas.screen.acct.label.phone=Phone Number

cas.screen.acct.title.phone=This is your phone number to which the activation link would be sent.

cas.screen.acct.label.country=Country

cas.screen.acct.title.country=This is the country linked associated to your phone number.

screen.acct.label.security.question.1=Security Question 1

screen.acct.label.security.question.2=Security Question 2

screen.acct.label.security.answer=Type your answer here…

      1. messages_zh_CN.properties

cas\src\main\resources\messages_zh_CN.properties

screen.welcome.security=出于安全考虑,一旦您访问过那些需要您提供凭证信息的应用时,请操作完成之后<a href="logout">登出</a>并关闭浏览器。

screen.welcome.cas.client1=CAS客户端1登录表单

screen.welcome.cas.client2=CAS客户端2登录表单

screen.welcome.instructions=请输入您的用户名和密码

screen.welcome.forcedsso=欢迎回来,<code><strong>{0}</strong></code>。我们已为您检测到现有的单点登录会话,然而系统要求您再次重新进行身份验证,因为CAS无法成功接受您之前的单点登录参与状态, \

  该状态可能是与分配给<code><strong>{1}</strong></code>的策略相关。请输入您的用户名和密码并继续。

screen.welcome.label.source=认证来源:

screen.welcome.label.token=Token:

screen.welcome.label.netid=用户名:

screen.welcome.label.netid.accesskey=n

screen.welcome.label.password=密 码:

screen.welcome.label.password.accesskey=p

screen.welcome.label.publicstation=我在公共工作站。

screen.welcome.label.warn=转向其他站点前提示我。

screen.welcome.label.warn.accesskey=w

screen.welcome.label.warnremove=不要再警告我

screen.welcome.button.login=登录

screen.welcome.button.logout=登出

screen.welcome.button.loginwip=请稍等片刻...

screen.welcome.button.register=注册

screen.welcome.button.deregister=取消注册

screen.welcome.button.print=打印

screen.welcome.button.clear=重置

screen.welcome.button.confirm=确认

screen.welcome.label.loginwith=外部身份提供者

screen.welcome.label.navto=导航至外部身份提供者 <strong>{0}</strong>。请稍等...

screen.welcome.button.loginx509=Login w/ Certificate

screen.cookies.disabled.title=禁用Cookies

screen.cookies.disabled.message=您的浏览器不支持cookies,浏览器存储或读取cookies的能力对于单点登录的工作至关重要,请查阅您的浏览器设置并确保启用cookie支持。

screen.acct.button.signUp=注册

screen.pm.button.submit=提交

screen.pm.button.cancel=取消

screen.pm.button.forgotpwd=<a href="{0}">忘记密码? </a>

screen.pm.button.resetPassword=重置密码

screen.pm.button.forgotUsername=忘记用户名?

screen.pm.reset.username=用户名:

screen.pm.reset.email=邮箱:

screen.pm.reset.heading=重置密码失败

screen.pm.reset.message=我们此时无法处理您的密码重置请求。

screen.pm.reset.qstitle=回答安全问题

screen.pm.reset.qsmsg=欢迎<strong>{0}</strong>。在重置密码之前,您必须回答以下安全问题。

screen.pm.reset.sentInstructions=您应该很快会收到一条包含密码重置说明的信息。请不要花很长时间,因为密码重置说明可能会过期。

screen.pm.reset.sent=密码重置说明已成功发送。

screen.pm.reset.title=重置密码

screen.pm.reset.instructions=请提供您的用户名,您将收到一条包含有关如何重设密码的通知。

screen.pm.reset.answer=答案 {0}

screen.pm.reset.question=问题 {0}

screen.pm.password.policyViolation=密码与密码策略要求不匹配。

screen.pm.password.confirmMismatch=密码不匹配。

screen.pm.password.strength=强度:

screen.pm.password.strength.0=最差

screen.pm.password.strength.1=坏

screen.pm.password.strength.2=弱

screen.pm.password.strength.3=好

screen.pm.password.strength.4=强

screen.pm.reset.contact.failed=无法发送电子邮件/短信,因为CAS配置中未定义电子邮件/短信服务器。

screen.pm.reset.username.required=没有提供电子邮件。

screen.pm.reset.contact.invalid=提供的联系信息丢失或无效。

screen.pm.reset.email.invalid=提供的电子邮件地址无效。

screen.pm.reset.username.failed=无法将用户名发送到给定的电子邮件地址。

screen.pm.forgotusername.title=忘记用户名?

screen.pm.forgotusername.instructions=请提供您的电子邮件地址,您将收到一封包含您的用户名的电子邮件。

screen.pm.forgotusername.email.failed=无法发送电子邮件,因为在CAS配置中没有定义电子邮件服务器。

screen.pm.forgotusername.email.invalid=没有提供电子邮箱,或者给定的地址无效。

screen.pm.forgotusername.contact.invalid=提供的电子邮件地址或电话号码无效。

screen.pm.forgotusername.username.missing=无法找到给定电子邮件地址的用户名。

screen.pm.forgotusername.username.failed=无法将用户名发送到给定的电子邮件地址。

screen.pm.forgotusername.sent=说明已发送成功。

screen.pm.forgotusername.sentInstructions=您应该很快会收到一条包含有关如何找回用户名的通知。

screen.aup.button.accept=接受

screen.aup.button.cancel=取消

screen.saml.idp.discovery=SAML2身份提供者发现

screen.consent.confirm=确认

screen.consent.cancel=取消

screen.consent.title=属性许可

screen.consent.attributes=属性

screen.consent.options=选项

screen.consent.attributes.header=以下属性将发布到 <strong>[{0}]</strong>:

screen.consent.attributes.attribute=属性

screen.consent.attributes.values=值

screen.consent.options.header=我应该如何再次提示许可?

screen.consent.options.always=<strong>每次</strong>

screen.consent.options.desc.always=每次我尝试登录{0}时都显示许可页面。

screen.consent.options.attributename=<strong>属性名</strong>

screen.consent.options.desc.attributename=如果在发布到{0}的属性集合中添加或删除属性,则显示许可页面。

screen.consent.options.attributevalue=<strong>属性值</strong>

screen.consent.options.desc.attributevalue.intro=显示许可页面,如果:

screen.consent.options.desc.attributevalue.first=新属性已获授权发布到{0}。

screen.consent.options.desc.attributevalue.second=从先前发布到{0}的属性包中删除了一个属性。

screen.consent.options.desc.attributevalue.third=授权发布到{0}的属性值已更改。

screen.consent.options.reminder.header=我应该多久被提醒再次许可?

screen.consent.options.reminder.expl=如果发布到{0}的属性集合没有变化,则显示许可页面作为提醒。

screen.consent.options.timeunit.seconds=秒

screen.consent.options.timeunit.minutes=分

screen.consent.options.timeunit.hours=时

screen.consent.options.timeunit.days=天

screen.consent.options.timeunit.weeks=周

screen.consent.options.timeunit.months=月

screen.consent.options.timeunit.years=年

screen.nonsecure.title=非安全连接

screen.nonsecure.message=您目前正在通过非安全连接访问CAS,单点登录将不起作用,您必须通过HTTPS登录。

screen.accountunlocked.heading=您的账户现已解锁。

screen.account.unlock.description=您的账户已被锁定且无法登录,请按照说明解锁您的账户然后再次尝试登录。

screen.account.unlock.label=图片文字

screen.account.unlock.hint=要继续,请输入您在图片中看到的字符。

screen.account.unlock.fail=CAS无法重置和解锁您的账户,有关更多信息请联系您的CAS管理员。

screen.account.unlock.success=您的账户现已解锁,请注意此更改可能需要一些时间才能完全生效,您现在应该能够登录并继续。

screen.defaultauthn.title=静态认证

screen.defaultauthn.heading=CAS配置为接受静态用户列表以进行主要身份验证,<strong>这仅用于演示目的</strong>, 建议您将CAS连接到LDAP、JDBC等进行认证。

logo.title=转到Apereo网站首页

copyright=版权所有 © 2005–2024 Apereo, Inc.

screen.capslock.on=CAPSLOCK 键已打开!

screen.button.continue=继续

screen.post.response.message=您正在被重定向到{0}。

# Generic Error Pages 401, 404, 500, etc

########################################

screen.error.page.heading=错误

screen.error.page.invalidrequest.title=未知请求

screen.error.page.invalidrequest.desc=提交给CAS的认证请求无效、构造错误或包含被视为无效或过期的参数。请查看原始请求和CAS日志并重试。

screen.error.page.invalidrequest=无效/未知请求

screen.error.page.title.accessdenied=错误 - 401

screen.error.page.title.permissiondenied=错误 - 没有权限

screen.error.page.title.pagenotfound=错误 - 找不到页面

screen.error.page.title.requestunsupported=错误 - 不支持的请求

screen.error.page.accessdenied=拒绝访问

screen.error.page.permissiondenied=您没有权限查看此页面。

screen.error.page.requestunsupported=不支持请求类型或语法。

screen.error.page.loginagain=重新登录

screen.error.page.notfound=找不到页面

screen.error.page.doesnotexist=您尝试访问的页面目前不存在。

screen.error.page.authdenied=授权被拒绝

# Remember-Me Authentication

screen.rememberme.checkbox.title=记住我

# Gua

screen.gua.confirm.message=如果您不认得此图像是您的,请不要继续。

# Blocked Errors Page

screen.error.page.title.blocked=错误 - 没有权限

screen.blocked.header=拒绝访问

screen.blocked.message=输错密码次数太多,账号被锁定。

AbstractAccessDecisionManager.accessDenied=您无权访问此资源,有关更多信息请联系您的CAS管理员。

#Confirmation Screen Messages

screen.confirmation.message=您在登录应用程序之前收到警告,请继续。

screen.authentication.warning=身份验证成功但出现警告

#Account Profile Messages

screen.account.success=<strong>{0}</strong>,您已经成功登录中央认证系统。

screen.account.security=出于安全考虑,请操作完成之后<a href="logout">登出</a>并关闭浏览器。

screen.account.tooltip.logout=此操作在更改密码之前会强制注销。

screen.account.failure=操作失败

screen.account.securityquestions.subtitle=您可以在此处查看和更新您的安全问题。请记住所有安全问题和答案<strong>必须</strong>是唯一的,CAS拒绝重复的问题或答案。

screen.account.mfadevices.title=多因素身份认证设备

screen.account.mfadevices.subtitle=以下设备已在您的账户下注册,可用于多因素身份认证。

screen.account.auditlog.title=审计日志

screen.account.auditlog.subtitle=检查由CAS记录的身份验证审计日志。

screen.account.securityquestions.title=管理安全问题

screen.account.securityquestions.failure=无法更新您的安全问题。

screen.account.securityquestions.success=安全问题被成功更新。

screen.account.sessions=查看您在所有设备和浏览器上向CAS注册的活跃的单点登录会话。

screen.account.applications=在CAS注册并且授权允许您访问的应用程序。

screen.account.attributes=在CAS进行身份认证的个人属性,这些属性包含在可以共享和发布给应用程序的可用属性池中。

#Generic Success Screen Messages

screen.success.header=登录成功

screen.success.success=<strong>{0}</strong>,您已成功登录到中央身份验证系统。但是您看到此页面是因为CAS不知道您的目标地址,再次检查身份验证请求并确保指定了已在CAS中注册且授权的目标服务或应用程序。

screen.success.security=出于安全考虑,请操作完成之后<a href="logout">登出</a>并关闭浏览器。

#Logout Screen Messages

screen.logout.confirm.header=<strong>{0}</strong>,您要完全退出吗?

screen.logout.confirm.text=<p>应用程序可能已将您重定向到中央验证服务并销毁您的单点登录会话。如果您选择注销,在您尝试访问应用程序时将被再次询问以提供您的凭据并再次登录。</p>

screen.logout.confirm.proceed=你想继续吗?

screen.logout.header=注销成功

screen.logout.success=已成功退出CAS系统,您可以再次<a href="login">登录</a>。

screen.logout.security=出于安全考虑,请关闭您的浏览器。

screen.service.sso.error.header=在访问到到目标服务前,你必须进行重新认证

screen.service.sso.error.message=你正试图访问要求重新认证的服务。请尝试进行<a href="{0}">再次认证</a>。

screen.service.required.message=您在未指定目标服务的情况下尝试进行身份验证。请重新检查请求并重试。

captchaError=reCAPTCHA 验证失败。

username.required=必须录入用户名。

password.required=必须录入密码。

source.required=认证来源是必填字段。

# Password Management

confirmedPassword.required=必须确认密码。

pm.passwordsMustMatch=提供的密码不匹配。

pm.passwordFailedCriteria=提供的密码不符合密码安全策略,请重试。

pm.updateFailure=无法修改账户密码,请重试。

# Authentication failure messages

authenticationFailure.AccountDisabledException=该账户已被禁用。

authenticationFailure.AccountLockedException=该账户已被锁定。

authenticationFailure.AccountExpiredException=该账号已过期,暂时禁止登录。

authenticationFailure.CredentialExpiredException=你的密码过期了。

authenticationFailure.InvalidLoginLocationException=你不能从这个工作站登录。

authenticationFailure.UniquePrincipalRequiredException=您此时无法登录,因为您正在进行另一个活动的单点登录会话,并且CAS配置了身份验证策略以防止多个并发单点登录会话。

authenticationFailure.InvalidLoginTimeException=您的账户此时被禁止登录。

authenticationFailure.AccountNotFoundException=您的账户无法识别,目前无法登录。

authenticationFailure.FailedLoginException=身份验证失败,可能是由于凭据无效。

authenticationFailure.MultifactorAuthenticationProviderAbsentException=无法满足多因素身份验证要求。您的账户配置了多因素身份验证策略,但CAS无法定位和执行该策略很可能是由于服务器配置错误,联系服务管理员寻求帮助。

authenticationFailure.SurrogateAuthenticationException=您目前无权模拟指定用户。

authenticationFailure.AccountPasswordMustChangeException=您的密码已过期,必须更改。

authenticationFailure.UnauthorizedServiceForPrincipalException=由于缺少权限,服务访问被拒绝。

authenticationFailure.MultifactorAuthenticationRequiredException=对您的身份验证被拒绝,因为您的账户尚未配置为通过多重身份验证。请联系服务管理员寻求帮助,确保您的账户已注册并符合多重身份验证的条件。

authenticationFailure.UNKNOWN=认证信息无效。

authenticationFailure.AuthenticationException=凭据被拒绝/无效并且身份验证失败。

INVALID_REQUEST_PROXY=必须同时提供'pgt'和'targetService'参数

INVALID_TICKET_SPEC=校验票根失败。您可能采用服务票根来校验代理票根,或没有将renew设为true。

INVALID_REQUEST=必须同时提供'service'和'ticket'参数

INVALID_AUTHENTICATION_CONTEXT=无法满足 [''{0}''] 的验证请求,请求未被识别或未完成。

INVALID_TICKET=未能够识别出目标 ''{0}''票根

INVALID_PROXY_GRANTING_TICKET=已为此ST生成PGT,不能为ST生成多个PGT

INVALID_SERVICE=票根''{0}''不符合目标服务

INVALID_PROXY_CALLBACK=所提供的代理回调网址''{0}''不能提供认证。

UNAUTHORIZED_SERVICE_PROXY=所提供的服务''{0}''没有权限使用CAS代理的认证方式。

UNSATISFIED_AUTHN_POLICY=由于不满足身份验证策略,服务访问被拒绝。

INVALID_AUTHN_REQUEST=身份验证失败,可能是由于凭据无效。

BLOCKED_AUTHN_REQUEST=身份验证被阻止且无法继续,可能是由于格式错误或缺少必需的参数。检查CAS服务器日志以找到错误的根本原因。

UNSATISFIED_SAML_REQUEST=CAS无法理解、接受或验证SAML身份验证请求,可能是由于格式错误或缺少必需的参数,请检查CAS服务器日志以找到错误的根本原因。

screen.service.error.header=应用程序未被授权使用CAS

service.not.authorized.missing.attr=由于缺少CAS服务器验证此服务所需的权限,您无权以您的账户身份访问该服务。

screen.service.error.message=您尝试验证的应用程序无权使用CAS。这通常表明该应用程序未在CAS注册,或者其注册记录中定义的授权策略阻止它利用CAS功能,或者它的格式不正确且无法被CAS识别。\

  请联系您的CAS管理员,了解如何注册您的应用程序并将其与CAS集成。

screen.service.empty.error.message=CAS的服务注册记录表是空的,没有定义服务。\

  希望通过CAS进行认证的应用程序必须在服务记录中明确定义。

screen.service.expired.message=您尝试验证的应用程序已在CAS服务注册记录表中过期。如果该服务仍被认为在使用中,请联系服务管理员以更新应用程序。

# Password policy

password.expiration.warning=你的密码会在{0}天内过期。请立刻<a href="https://pm.example.edu">修改你的密码</a>。

password.expiration.loginsRemaining=在<strong>必须</strong>修改密码之前,你还剩{0}次登录。

screen.accountdisabled.heading=该账户已被禁用。

screen.accountdisabled.message=请联系系统管理员来重新获得访问权限。

screen.accountlocked.heading=该账户已被锁定。

screen.accountlocked.message=请联系系统管理员来重新获得访问权限。

screen.expiredpass.heading=您的密码已过期。

screen.expiredpass.message=请<a href="{0}">修改你的密码</a>。

screen.mustchangepass.heading=你必须修改你的密码。

screen.mustchangepass.message=请<a href="{0}">修改你的密码</a>。

screen.badhours.heading=现在你的账户被禁止登录了。

screen.badhours.message=请稍后再试。

screen.authnblocked.heading=身份验证被阻止。

screen.authnblocked.message=您当前工作站的身份验证不受信任且未经授权。

screen.risk.authnblocked.heading=身份验证被阻止。

screen.risk.authnblocked.message=您当前工作站的身份验证不受信任且未经授权。

screen.badworkstation.heading=你不能从这个工作站登录。

screen.badworkstation.message=请联系系统管理员来重新获得访问权限。

screen.button.changePassword=修改密码

screen.pm.success.header=密码修改成功

screen.pm.success.message=您的密码已被成功更新.

screen.pm.confirmpsw=确认密码:

screen.pm.enterpsw=输入密码:

screen.pac4j.authn.TechnicalException=无法定位或解析身份提供者配置,很可能是由于配置错误,查看日志以找出问题的根本原因。

screen.pac4j.authn.unknown=无法接受外部身份提供者提供给CAS的身份验证响应。

screen.pac4j.unauthz.pagetitle=未经授权的访问

screen.pac4j.unauthz.gotoapp=前往应用程序

screen.pac4j.unauthz.login=回到CAS

screen.pac4j.unauthz.heading=未经授权的访问

screen.pac4j.unauthz.message=身份验证请求被拒绝/取消,或者身份验证提供程序由于权限等原因拒绝访问,查看日志以查找问题的根本原因。

screen.pac4j.button.retry=重试

screen.pac4j.discovery.intro=请提供您的用户名或电子邮件地址,以便CAS可以为您的账户找到正确的身份提供者。

screen.pac4j.discovery.unknownclient=找不到基于此请求的委托身份提供者。

screen.pac4j.button.selectprovider=选择身份提供者

screen.pac4j.discovery.title=委托认证动态发现

screen.pac4j.authn.SAMLException=无法接受外部身份提供者提供给CAS的身份验证响应。请检查CAS服务器日志和配置以找到问题的根本原因,然后重试。

screen.pac4j.authn.SAMLIssueInstantException=无法接受外部身份提供者给CAS提供的身份验证响应,因为根据当前的CAS配置,Issue instant不合法。

screen.pac4j.credential-selection.title=委托身份验证配置选择

screen.pac4j.credential-selection.intro=CAS已找到与您的账号关联的多个配置,请选择账号配置并继续的。

screen.delauthn.error.header=委托认证失败

screen.delauthn.error.message=CAS无法完成委托身份验证方案或重定向到选定的身份提供者。请检查原始身份验证请求然后重试,您可能需要关闭浏览器并重新开始。

# GAuth

screen.authentication.gauth.qrimage=QR code

screen.authentication.gauth.register=您的账户未注册,

screen.authentication.gauth.registerdesc=使用以下设置向CAS注册您的设备。

screen.authentication.gauth.key=注册密钥是:<pre>{0}</pre>

screen.authentication.gauth.scratchcodes=预留码:

screen.authentication.gauth.selecteddevice=您选择的多因素身份验证设备是:<code>{0}</code>。

screen.authentication.gauth.selanotherdevice=如果 <code>{0}</code> 不是您当前的设备,您可以选择其他设备进行多因素身份验证。

screen.authentication.gauth.name=设备名:

screen.authentication.gauth.cancel=取消

screen.authentication.gauth.reganotherdevice=您还可以注册另一台设备以用于多因素身份验证。

screen.authentication.gauth.selectdevice=选择设备

screen.authentication.gauth.deletedevice=删除设备

screen.authentication.gauth.invalid=无法接受此身份验证请求,所选设备或给定凭据无效。

screen.authentication.gauth.invalidtoken=无法接受此令牌,给定的令牌无效、不属于设备或已过期。

screen.authentication.gauth.confirm.title=确认账户注册

screen.authentication.gauth.confirm.desc=通过从您设备上的身份验证器提供令牌来确认您的账户注册。验证令牌后,您的账户注册将完成。

# OAuth

screen.oauth.confirm.header=授权

screen.oauth.confirm.message=要授权"{0}"访问你全部个人信息吗?

screen.oauth.confirm.allow=允许

screen.oauth.confirm.deny=拒绝

cas.oauth.confirm.pagetitle=批准访问

cas.oauth.device.confirm.header=连接设备

cas.oauth.device.confirm.message=输入设备上显示的代码以继续。

cas.oauth.device.confirmed.header=Code Approved

cas.oauth.device.confirmed.message=返回您的设备以继续。

cas.oauth.error.pagetitle=OAuth错误

cas.oauth.error.header=OAuth授权错误

OAUTH_BAD_SESSION_REQUEST=OAuth请求无法完成,因为CAS无法定位或确定OAuth重定向URL。\

  这通常表示请求过时或不匹配,其中已处理的请求会话ID不同于活动会话,可能是由完整的注销操作引起的。请清除Cookie和历史记录,重新启动浏览器并重试。

# Unavailable

screen.unavailable.heading=CAS无法使用

screen.unavailable.message=在试图完成你的请求时出错。请通知你的技术支持或重试。

# OIDC

screen.oidc.confirm.infourl=了解 {0} 的更多信息.

screen.oidc.confirm.privacyurl=了解 {0} 的隐私政策.

screen.oidc.confirm.scopes=范围

screen.oidc.confirm.claims=声明

screen.oidc.confirm.scope.openid=这表示OpenID Connect授权请求

screen.oidc.confirm.asksinfo=客户端请求如下信息:

screen.oidc.confirm.dynamic=客户端在 <code>{0}</code> 动态注册。

# Unavailable

screen.unavailable.header=CAS错误

screen.unavailable.heading=CAS无法处理此请求: "{0}:{1}"

screen.unavailable.message=尝试完成您的请求时出错,<strong>请通知您的支持台或重试。</strong> \

screen.mfaDenied.header=MFA被拒绝

screen.mfaDenied.heading=MFA尝试已被提供程序拒绝

screen.mfaDenied.message=您的MFA提供程序已拒绝您尝试使用第二因素验证,请联系您的系统管理员以帮助恢复您的账户。

screen.mfaUnavailable.header=MFA提供程序不可用

screen.mfaUnavailable.heading=MFA提供程序不可用

screen.mfaUnavailable.message=CAS此时无法连接到您配置的MFA提供程序。\

  由于为您尝试访问的服务配置的失败策略,此时无法授予身份验证。

#####################################################################

# Login View

#####################################################################

#Resources Labels

cas.login.pagetitle=登录

cas.login.resources.header=资源

cas.login.resources.wiki=文档

cas.login.resources.endpoints=Actuator端点

cas.login.resources.pulls=合并请求

cas.login.resources.mailinglist=邮件列表

cas.login.resources.chat=聊天室

cas.login.resources.blog=博客

cas.login.resources.support=支持

cas.login.resources.contribguide=贡献者指南

####

# Acceptable Usage Policy View

#

cas.acceptableusagepolicyview.pagetitle=Acceptable Usage Policy View

##

# MFA

##

cas.mfa.providerselection.pagetitle=多因素提供程序选择

cas.mfa.providerselection.mfa-gauth=Google身份验证器

cas.mfa.providerselection.mfa-gauth.notes=Google身份验证器是一种基于软件的身份验证器,它实现了两步验证服务,用于通过Google对移动应用程序的用户进行身份验证

cas.mfa.providerselection.mfa-simple=CAS多因素身份认证

cas.mfa.providerselection.mfa-simple.notes=允许CAS自行充当多因素身份验证提供程序,颁发令牌并通过预定义的消息渠道(例如电子邮件或短信)将其发送给终端用户。

cas.mfa.simple.pagetitle=CAS多因素身份认证登录

cas.mfa.simple.label.token=令牌:

cas.mfa.simple.label.resend=重新发送

cas.mfa.simple.label.tokensent=多因素身份验证令牌通过电子邮件或短信发送给您。请找到令牌并在此处提交以继续。\

  请注意令牌将在短时间后过期,在这种情况下,您可以要求CAS向您发送一个新令牌。

cas.mfa.googleauth.pagetitle=Google身份验证器

cas.mfa.googleauth.label.token=令牌:

cas.mfa.radius.pagetitle=Radius身份认证

cas.mfa.registerdevice.label.title=注册设备

cas.mfa.registerdevice.label.intro=请命名当前设备。

cas.mfa.registerdevice.pagetitle=注册设备

cas.mfa.registerdevice.label.name=名称

cas.mfa.registerdevice.label.duration=我们应该记住这个设备多久?

cas.mfa.registerdevice.label.expiration=过期

cas.mfa.registerdevice.button.register=注册

cas.mfa.registerdevice.button.skip=跳过

cas.mfa.registerdevice.options.timeunit.forever=永久

passwordless.token.header=提供令牌

passwordless.token.description=请提供通过电子邮件、电话等方式发送给您的安全令牌。请注意令牌将在短时间后过期,,提交后所有其他令牌都将失效并被删除。

passwordless.error.failure.title=认证失败

passwordless.error.failure.description=无法验证提供的令牌,它可能已失效、删除或过期。

passwordless.error.unknown.user=CAS无法识别和定位提供的用户名。

passwordless.error.invalid.user=提供的用户名没有包含足够的联系信息。

cas.authn.qr.fail=无法接受基于二维码的身份验证请求。确保二维码被正确扫描,并且提供的凭据有效、由该CAS服务器颁发且未过期。

cas.screen.acct.title=账户注册

cas.screen.acct.intro=请填写下表注册您的新账户,提交表格后您将收到一封电子邮件,其中包含用于启用您的账户、设置密码并开始使用CAS的激活链接。

cas.screen.acct.infosent=账户激活说明已成功发送,请检查您的电子邮件等并按照说明进行操作。

cas.screen.acct.intro.complete=欢迎回来! 感谢您验证您的账户。请填写下表以在CAS注册您的新账户。

cas.screen.acct.intro.completed=谢谢!您的账户现已激活并在CAS注册。

cas.screen.acct.button.submit=提交

cas.screen.acct.button.cancel=取消

cas.screen.acct.button.update=更新

cas.screen.acct.error.provision=无法提供请求的帐户。

cas.screen.acct.error.fail=无法注册请求的帐户,或发送账户激活链接。

cas.screen.acct.error.invalid-value=提供的值缺失、无效或与输入类型所需的模式不匹配。

cas.screen.acct.label.email=邮件地址

cas.screen.acct.title.email=这是您的主要电子邮件地址,激活链接将被发送到该地址。

cas.screen.acct.label.firstName=名

cas.screen.acct.title.firstName=你的名字。

cas.screen.acct.label.lastName=姓

cas.screen.acct.title.lastName=你的姓氏。

cas.screen.acct.label.username=用户名

cas.screen.acct.title.username=您希望用于登录的用户名。

cas.screen.acct.label.phone=电话号码

cas.screen.acct.title.phone=这是您的电话号码,激活链接将发送到该电话号码。

cas.screen.acct.label.country=国家

cas.screen.acct.title.country=这是与您的电话号码关联的国家/地区。

screen.acct.label.security.question.1=安全问题1

screen.acct.label.security.question.2=安全问题2

screen.acct.label.security.answer=在这里输入您的答案...

      1. casclient1-1001.json

cas\src\main\resources\services\casclient1-1001.json

{

  "@class": "org.apereo.cas.services.CasRegisteredService",

  "serviceId": "^(https|http|imaps)://casclient1.*",

  "name": "casclient1",

  "theme": "casclient1",

  "id": 1001

}

      1. casclient1-1002.json

cas\src\main\resources\services\casclient2-1002.json

{

  "@class": "org.apereo.cas.services.CasRegisteredService",

  "serviceId": "^(https|http|imaps)://casclient2.*",

  "name": "casclient2",

  "theme": "casclient2",

  "id": 1002

}

      1. bootstrap.css

cas\src\main\resources\static\themes\casclient1\css\bootstrap.css

      1. bootstrap.js

cas\src\main\resources\static\themes\casclient1\js\bootstrap.js

      1. bootstrap.css

cas\src\main\resources\static\themes\casclient2\css\bootstrap.css

      1. bootstrap.js

cas\src\main\resources\static\themes\casclient2\js\bootstrap.js

      1. casLoginView.html

cas\src\main\resources\templates\casclient1\login\casLoginView.html

<!DOCTYPE html>

<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{layout}">

<head>

    <title th:text="#{cas.login.pagetitle}">CAS Login View</title>

    <link href="../../static/css/cas.css" rel="stylesheet" th:remove="tag"/>

    <link href="../../static/css/bootstrap.css" rel="stylesheet" th:remove="tag"/>

</head>

<body class="login mdc-typography text-bg-primary">

<div layout:fragment="content" class="d-flex justify-content-center">

   <div class="d-flex justify-content-center flex-md-row flex-column mdc-card mdc-card-content card flex-grow-1"

         th:with="loginFormEnabled=${#strings.defaultString(#themes.code('cas.login-form.enabled'), 'true') == 'true'},

                  loginFormViewable=${@casThymeleafTemplatesDirector.isLoginFormViewable(#vars)}">

        <section id="loginForm"

                 th:if="${loginFormViewable and loginFormEnabled}"

                 class="login-section login-form card-body">

            <div th:replace="~{fragments/loginform :: loginform}">

                <a href="fragments/loginform.html">Login Form goes here</a>

            </div>

        </section>

        <span th:if="${#bools.isFalse(delegatedAuthenticationDynamicProviderSelection) && #bools.isFalse(delegatedAuthenticationDisabled)}">

            <section id="loginProviders" class="login-section login-providers card-body"

                    th:if="${delegatedAuthenticationProviderConfigurations} OR ${wsfedUrls}">

                <div th:replace="~{fragments/loginProviders :: loginProviders}">

                    <a href="fragments/loginProviders.html">loginProviders</a>

                </div>

            </section>

        </span>

        <section id="qrlogin" class="login-section login-qr d-xs-none d-md-block card-body" th:if="${qrAuthenticationEnabled}">

            <div th:replace="~{fragments/qrAuthentication :: qrAuthentication}">

                <a href="fragments/qrAuthentication.html">qrAuthentication</a>

            </div>

        </section>

    </div>

</div>

</body>

</html>

      1. loginform.html

cas\src\main\resources\templates\casclient1\fragments\loginform.html

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>

    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>

    <title>Login Form Fragment</title>

    <link href="../../static/css/cas.css" rel="stylesheet" th:remove="tag"/>

</head>

<body>

<main class="container mt-3 mb-3">

    <div th:fragment="loginform" class="d-flex flex-column justify-content-between m-auto"

         th:with="loginFormEnabled=${#strings.defaultString(#themes.code('cas.login-form.enabled'), 'true') == 'true'},

                loginFormViewable=${@casThymeleafTemplatesDirector.isLoginFormViewable(#vars)}">

        <div th:if="${delegatedAuthenticationProviderPrimary == null}">

            <div th:if="${!#strings.isEmpty(#themes.code('cas.hero-banner.file'))}">

                <p>

                    <img id="heroimg"

                         th:title="${#strings.defaultString(#themes.code('cas.theme.name'), 'CAS')}"

                         th:src="@{${#themes.code('cas.hero-banner.file')}}"/>

                </p>

            </div>

            <div class="service-ui" th:replace="~{fragments/serviceui :: serviceUI}">

                <a href="fragments/serviceui.html">service ui fragment</a>

            </div>

        </div>

        <div class="form-wrapper">

            <form method="post" id="fm1" th:object="${credential}" action="login" οnsubmit="loginFormSubmission();">

                <div id="login-form-controls" th:unless="${loginFormViewable or loginFormEnabled}">

                    <div id="loginErrorsPanel" class="alert alert-danger banner banner-danger banner-dismissible"

                         th:if="${#fields.hasErrors('*')}">

                        <p th:each="err : ${#fields.errors('*')}" th:utext="${err + ' '}">Example error</p>

                        <!--<a href="#" class="close" data-dismiss="alert" th:aria-label="#{screen.pm.button.close}">×</a>-->

                    </div>

                </div>

                <div id="login-form-controls" th:if="${loginFormViewable and loginFormEnabled}">

                    <!-- <div th:if="${existingSingleSignOnSessionAvailable}">

                        <i class="mdi mdi-alert-decagram fas fa-exclamation-triangle" aria-hidden="true"></i> 

                        <span id="existingSsoMsg" th:if="${registeredService}" class="mdc-button__label"

                              th:utext="#{screen.welcome.forcedsso(${existingSingleSignOnSessionPrincipal?.id},${registeredService.name})}"/>

                        <span id="existingSsoMsg" th:unless="${registeredService}" class="mdc-button__label"

                              th:utext="#{screen.welcome.forcedsso(${existingSingleSignOnSessionPrincipal?.id}, 'CAS')}"/>

                    </div> -->

                    <h1 th:unless="${existingSingleSignOnSessionAvailable}" class="text-center">

                        <span th:utext="#{screen.welcome.cas.client1}">Cas Client 1 Login Form</span>

                    </h1>

                    <h3 th:unless="${existingSingleSignOnSessionAvailable}" class="text-center">

                        <i class="mdi mdi-login fas fa-shield-alt" aria-hidden="true"></i>

                        <span th:utext="#{screen.welcome.instructions}">Enter your Username and Password:</span>

                    </h3>

                    <div id="loginErrorsPanel" class="banner banner-danger alert alert-danger banner-dismissible"

                         th:if="${#fields.hasErrors('*')}" role="alert">

                        <h2 th:utext="#{screen.authentication.error.title}">Authentication Failure</h2>

                        <p th:each="err : ${#fields.errors('*')}" th:utext="${err + ' '}">Example error</p>

                        <!--<a href="#" class="close" data-dismiss="alert" th:aria-label="#{screen.pm.button.close}">×</a>-->

                    </div>

                    <section class="cas-field form-group my-3" id="usernameSection">

                        <label for="username"

                               class="mdc-text-field mdc-text-field--outlined control-label w-100">

                            <span class="mdc-notched-outline">

                                <span class="mdc-notched-outline__leading"></span>

                                <span class="mdc-notched-outline__notch">

                                    <span class="mdc-floating-label"

                                          th:utext="#{screen.welcome.label.netid}">Username</span>

                                </span>

                                <span class="mdc-notched-outline__trailing"></span>

                            </span>

                            <input class="mdc-text-field__input form-control" id="username"

                                   size="25"

                                   type="text"

                                   th:readonly="!${@casThymeleafTemplatesDirector.isLoginFormUsernameInputVisible(#vars)}"

                                   th:field="*{username}"

                                   th:accesskey="#{screen.welcome.label.netid.accesskey}"

                                   autocapitalize="none"

                                   spellcheck="false"

                                   autocomplete="username" required />

                        </label>

                        <div class="mdc-text-field-helper-line invalid-feedback">

                            <div class="mdc-text-field-helper-text mdc-text-field-helper-text--validation-msg" aria-hidden="true">

                                <span id="usernameValidationMessage" th:utext="#{username.required}"></span>

                            </div>

                        </div>

                        <script type="text/javascript" th:inline="javascript">

                            /*<![CDATA[*/

                            let username = /*[[${@casThymeleafTemplatesDirector.getLoginFormUsername(#vars)}]]*/;

                            let disabled = /*[[${@casThymeleafTemplatesDirector.isLoginFormUsernameInputDisabled(#vars)}]]*/;

                            if (username != null && username !== '') {

                                $('#username').val(username);

                                if (disabled) {

                                    $('#usernameSection').hide();

                                }

                            }

                            /*]]>*/

                        </script>

                    </section>

                    <section class="cas-field form-group my-3 mdc-input-group form-group" id="passwordSection">

                        <div class="mdc-input-group-field mdc-input-group-field-append">

                            <label for="password"

                                   class="mdc-text-field caps-check mdc-text-field--outlined control-label mdc-text-field--with-trailing-icon control-label w-100">

                                    <span class="mdc-notched-outline">

                                        <span class="mdc-notched-outline__leading"></span>

                                        <span class="mdc-notched-outline__notch">

                                            <span class="mdc-floating-label" th:utext="#{screen.welcome.label.password}">Password</span>

                                        </span>

                                        <span class="mdc-notched-outline__trailing"></span>

                                    </span>

                                <input class="mdc-text-field__input form-control pwd"

                                       type="password"

                                       id="password"

                                       size="25"

                                       required

                                       th:accesskey="#{screen.welcome.label.password.accesskey}"

                                       th:field="*{password}"

                                       autocomplete="off"/>

                                <button

                                        class="reveal-password mdc-button mdc-button--unelevated mdc-input-group-append mdc-icon-button btn btn-primary"

                                        tabindex="-1" type="button" th:title="#{screen.pm.password.toggle}">

                                    <i class="mdi mdi-eye reveal-password-icon fas fa-eye" aria-hidden="true"></i>

                                </button>

                            </label>

                            <div class="mdc-text-field-helper-line invalid-feedback">

                                <div class="mdc-text-field-helper-text mdc-text-field-helper-text--validation-msg" aria-hidden="true">

                                    <span id="passwordValidationMessage" th:utext="#{password.required}"></span>

                                </div>

                            </div>

                        </div>

                        <div class="mdc-text-field-helper-line invalid-feedback caps-warn">

                            <div class="mdc-text-field-helper-text mdc-text-field-helper-text--persistent mdc-text-field-helper-text--validation-msg text-danger">

                                <span th:utext="#{screen.capslock.on}" />

                            </div>

                        </div>

                    </section>

                    <section id="authnSourceSection" class="cas-field form-group my-3"

                             th:if="${availableAuthenticationHandlerNames != null}">

                        <div class="d-flex">

                            <div th:if="${availableAuthenticationHandlerNames.size() > 1}"

                                 class="mdc-select mdc-select--outlined mdc-select--required mdc-menu-surface--fullwidth authn-source">

                                <div class="mdc-select__anchor"

                                     role="button"

                                     aria-required="true"

                                     aria-haspopup="listbox"

                                     aria-expanded="false">

                                    <span class="mdc-line__ripple"></span>

                                    <span class="mdc-notched-outline">

                                        <span class="mdc-notched-outline__leading"></span>

                                        <span class="mdc-notched-outline__notch">

                                            <span id="outlined-select-label" class="mdc-floating-label"

                                                  th:utext="#{screen.welcome.label.source}">Source</span>

                                        </span>

                                        <span class="mdc-notched-outline__trailing"></span>

                                    </span>

                                    <span class="mdc-select__selected-text-container">

                                        <span class="mdc-select__selected-text"/>

                                    </span>

                                    <span class="mdc-select__dropdown-icon">

                                        <svg class="mdc-select__dropdown-icon-graphic" viewBox="7 10 10 5" focusable="false">

                                            <polygon class="mdc-select__dropdown-icon-inactive" stroke="none"

                                                     fill-rule="evenodd" points="7 10 12 15 17 10">

                                            </polygon>

                                            <polygon class="mdc-select__dropdown-icon-active" stroke="none"

                                                     fill-rule="evenodd" points="7 15 12 10 17 15">

                                            </polygon>

                                        </svg>

                                    </span>

                                    <span class="mdc-line-ripple"></span>

                                </div>

                                <div class="mdc-select__menu mdc-menu mdc-menu-surface mdc-menu-surface--fullwidth">

                                    <ul class="mdc-list" role="listbox">

                                        <li th:each="handler,iter : ${availableAuthenticationHandlerNames}"

                                            class="mdc-list-item " th:id="${handler + '-authnSource'}"

                                            th:classappend="${iter.index == 0 ? 'mdc-list-item--selected' : ''}"

                                            th:data-value="${handler}" role="option">

                                            <span class="mdc-list-item__ripple"></span>

                                            <span class="mdc-list-item__text" th:utext="${handler}">Option</span>

                                        </li>

                                    </ul>

                                </div>

                                <input type="hidden" id="source" th:field="*{source}" name="source"/>

                            </div>

                            <span th:if="${availableAuthenticationHandlerNames.size() == 1}">

                                <input type="hidden" id="source" name="source"

                                       th:value="${availableAuthenticationHandlerNames.get(0)}"/>

                            </span>

                        </div>

                    </section>

                    <section class="cas-field form-group my-3">

                        <div th:each="entry: ${customLoginFormFields}">

                            <label class="mdc-text-field mdc-text-field--outlined control-label">

                                <input class="mdc-text-field__input form-control"

                                       th:id="${entry.key + '-customField'}" th:name="${entry.key + '-customField'}"

                                       size="25" type="text" th:field="*{customFields[__${entry.key}__]}"

                                       autocomplete="off"/>

                                <span class="mdc-notched-outline">

                                    <span class="mdc-notched-outline__leading"></span>

                                    <span class="mdc-notched-outline__notch">

                                        <span class="mdc-floating-label"

                                              th:text="#{${entry.value.messageBundleKey}}">Label</span>

                                    </span>

                                    <span class="mdc-notched-outline__trailing"></span>

                                </span>

                            </label>

                        </div>

                    </section>

                    <section class="cas-field form-check"

                             th:if="${'true' == #strings.defaultString(#themes.code('cas.warn-on-redirect.enabled'), 'true')}">

                        <div class="mdc-form-field ">

                            <div th:replace="~{fragments/switchbutton :: switchbutton (id='warn', label='screen.welcome.label.warn')}"/>

                        </div>

                        <p/>

                    </section>

                    <section class="cas-field form-check"

                             th:if="${'true' == #strings.defaultString(#themes.code('cas.public-workstation.enabled'), 'true')}">

                        <div class="mdc-form-field ">

                            <div th:replace="~{fragments/switchbutton :: switchbutton (id='publicWorkstation', label='screen.welcome.label.publicstation')}"/>

                        </div>

                        <p/>

                    </section>

                    <section class="cas-field form-check" th:if="${rememberMeAuthenticationEnabled}">

                        <div class="mdc-form-field ">

                            <div th:replace="~{fragments/switchbutton :: switchbutton (id='rememberMe', label='screen.rememberme.checkbox.title')}"/>

                        </div>

                        <p/>

                    </section>

                    <section class="cas-field">

                        <span th:if="${recaptchaLoginEnabled}">

                            <div th:replace="~{fragments/recaptcha :: recaptchaToken}"/>

                        </span>

                        <input type="hidden" name="execution" th:value="${flowExecutionKey}"/>

                        <input type="hidden" name="_eventId" value="submit"/>

                        <input type="hidden" name="geolocation"/>

                        <input type="hidden" name="deviceFingerprint"/>

                        <p th:if="${#strings.equalsIgnoreCase(httpRequestMethod, 'POST')}">

                            <span th:each="entry : ${httpRequestInitialPostParameters}" th:remove="tag">

                                <span th:each="entryValue : ${entry.value}" th:remove="tag">

                                    <input type="hidden" th:name="${entry.key}" th:value="${entryValue}"/>

                                </span>

                            </span>

                        </p>

                        <script type="text/javascript">

                            let client = new ClientJS();

                            let fingerprint = client.getFingerprint();

                            $('[name="deviceFingerprint"]').val(fingerprint);

                        </script>

                    </section>

                    <div th:replace="~{fragments/submitbutton :: submitButton (messageKey='screen.welcome.button.login')}"/>

                </div>

            </form>

            <div id="selectIdentityProvider"

                 th:if="${#bools.isTrue(delegatedAuthenticationDynamicProviderSelection) and loginFormViewable and loginFormEnabled}">

                <p>

                <form method="post" id="providerDiscoveryForm">

                    <input type="hidden" name="execution" th:value="${flowExecutionKey}"/>

                    <input type="hidden" name="_eventId" value="discovery"/>

                    <span class="fa fa-unlock"></span>

                    <button th:id="selectProviderButton"

                            class="mdc-button mdc-button--raised"

                            οnclick="$('#providerDiscoveryForm').submit();"

                            th:value="#{screen.pac4j.button.selectprovider}">

                        <span class="mdc-button__label" th:text="#{screen.pac4j.button.selectprovider}">Select</span>

                    </button>

                </form>

            </div>

            <div id="x509Login" th:if="${x509ClientAuthLoginEndpointUrl}">

                <span th:if="${loginFormViewable and loginFormEnabled}">

                    <hr class="my-4"/>

                    <script th:inline="javascript">

                        /*<![CDATA[*/

                        function x509login() {

                            let url =  /*[[${x509ClientAuthLoginEndpointUrl}]]*/;

                            url += window.location.search;

                            window.location.assign(url)

                        }

                        /*]]>*/

                    </script>

                    <a id="x509LoginLink" class="mdc-button mdc-button--raised btn btn-primary"

                       οnclick="javascript:x509login();"

                       th:text="#{screen.welcome.button.loginx509}">X509 Login</a>

                </span>

            </div>

            <hr th:if="${loginFormViewable and loginFormEnabled}" class="my-4"/>

            <span id="webauthnLoginPanel" th:if="${webAuthnPrimaryAuthenticationEnabled}">

                <script type="text/javascript">

                    $('#webauthnLoginPanel').show();

                </script>

                <div th:replace="~{fragments/webAuthnLogin :: webAuthnLogin}"/>

                <hr class="my-4"/>

            </span>

            <div th:if="${loginFormViewable and loginFormEnabled}">

                <span th:remove="tag"

                      th:if="${'true' == #strings.defaultString(#themes.code('cas.pm-links.enabled'), 'true')}">

                    <div th:replace="~{fragments/pmlinks :: pmlinks}"/>

                </span>

            </div>

            <script type="text/javascript" th:inline="javascript">

                /*<![CDATA[*/

                var i = /*[[@{#{screen.welcome.button.loginwip}}]]*/

                var j = /*[[@{#{screen.welcome.button.login}}]]*/

                    /*]]>*/

                    $(window).on('pageshow', function () {

                        $(':submit').prop('disabled', false);

                        $(':submit').attr('value', j);

                    });

                $(document).ready(function () {

                    $("#fm1").submit(function () {

                        $(":submit").attr("disabled", true);

                        $(":submit").attr("value", i);

                        return true;

                    });

                });

            </script>

        </div>

        <div th:if="${loginFormViewable and loginFormEnabled}">

            <div th:replace="~{fragments/loginsidebar :: loginsidebar}"/>

        </div>

    </div>

</main>

</body>

</html>

      1. casLoginView.html

cas\src\main\resources\templates\casclient2\login\casLoginView.html

<!DOCTYPE html>

<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{layout}">

<head>

    <title th:text="#{cas.login.pagetitle}">CAS Login View</title>

    <link href="../../static/css/cas.css" rel="stylesheet" th:remove="tag"/>

    <link href="../../static/css/bootstrap.css" rel="stylesheet" th:remove="tag"/>

</head>

<body class="login mdc-typography text-bg-info">

<div layout:fragment="content" class="d-flex justify-content-center">

   <div class="d-flex justify-content-center flex-md-row flex-column mdc-card mdc-card-content card flex-grow-1"

         th:with="loginFormEnabled=${#strings.defaultString(#themes.code('cas.login-form.enabled'), 'true') == 'true'},

                  loginFormViewable=${@casThymeleafTemplatesDirector.isLoginFormViewable(#vars)}">

        <section id="loginForm"

                 th:if="${loginFormViewable and loginFormEnabled}"

                 class="login-section login-form card-body">

            <div th:replace="~{fragments/loginform :: loginform}">

                <a href="fragments/loginform.html">Login Form goes here</a>

            </div>

        </section>

        <span th:if="${#bools.isFalse(delegatedAuthenticationDynamicProviderSelection) && #bools.isFalse(delegatedAuthenticationDisabled)}">

            <section id="loginProviders" class="login-section login-providers card-body"

                    th:if="${delegatedAuthenticationProviderConfigurations} OR ${wsfedUrls}">

                <div th:replace="~{fragments/loginProviders :: loginProviders}">

                    <a href="fragments/loginProviders.html">loginProviders</a>

                </div>

            </section>

        </span>

        <section id="qrlogin" class="login-section login-qr d-xs-none d-md-block card-body" th:if="${qrAuthenticationEnabled}">

            <div th:replace="~{fragments/qrAuthentication :: qrAuthentication}">

                <a href="fragments/qrAuthentication.html">qrAuthentication</a>

            </div>

        </section>

    </div>

</div>

</body>

</html>

      1. loginform.html

cas\src\main\resources\templates\casclient2\fragments\loginform.html

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>

    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>

    <title>Login Form Fragment</title>

    <link href="../../static/css/cas.css" rel="stylesheet" th:remove="tag"/>

</head>

<body>

<main class="container mt-3 mb-3">

    <div th:fragment="loginform" class="d-flex flex-column justify-content-between m-auto"

         th:with="loginFormEnabled=${#strings.defaultString(#themes.code('cas.login-form.enabled'), 'true') == 'true'},

                loginFormViewable=${@casThymeleafTemplatesDirector.isLoginFormViewable(#vars)}">

        <div th:if="${delegatedAuthenticationProviderPrimary == null}">

            <div th:if="${!#strings.isEmpty(#themes.code('cas.hero-banner.file'))}">

                <p>

                    <img id="heroimg"

                         th:title="${#strings.defaultString(#themes.code('cas.theme.name'), 'CAS')}"

                         th:src="@{${#themes.code('cas.hero-banner.file')}}"/>

                </p>

            </div>

            <div class="service-ui" th:replace="~{fragments/serviceui :: serviceUI}">

                <a href="fragments/serviceui.html">service ui fragment</a>

            </div>

        </div>

        <div class="form-wrapper">

            <form method="post" id="fm1" th:object="${credential}" action="login" οnsubmit="loginFormSubmission();">

                <div id="login-form-controls" th:unless="${loginFormViewable or loginFormEnabled}">

                    <div id="loginErrorsPanel" class="alert alert-danger banner banner-danger banner-dismissible"

                         th:if="${#fields.hasErrors('*')}">

                        <p th:each="err : ${#fields.errors('*')}" th:utext="${err + ' '}">Example error</p>

                        <!--<a href="#" class="close" data-dismiss="alert" th:aria-label="#{screen.pm.button.close}">×</a>-->

                    </div>

                </div>

                <div id="login-form-controls" th:if="${loginFormViewable and loginFormEnabled}">

                    <div th:if="${existingSingleSignOnSessionAvailable}">

                        <i class="mdi mdi-alert-decagram fas fa-exclamation-triangle" aria-hidden="true"></i> 

                        <span id="existingSsoMsg" th:if="${registeredService}" class="mdc-button__label"

                              th:utext="#{screen.welcome.forcedsso(${existingSingleSignOnSessionPrincipal?.id},${registeredService.name})}"/>

                        <span id="existingSsoMsg" th:unless="${registeredService}" class="mdc-button__label"

                              th:utext="#{screen.welcome.forcedsso(${existingSingleSignOnSessionPrincipal?.id}, 'CAS')}"/>

                    </div>

                    <h1 th:unless="${existingSingleSignOnSessionAvailable}" class="text-center">

                        <span th:utext="#{screen.welcome.cas.client2}">Cas Client 2 Login Form</span>

                    </h1>

                    <h3 th:unless="${existingSingleSignOnSessionAvailable}" class="text-center">

                        <i class="mdi mdi-login fas fa-shield-alt" aria-hidden="true"></i>

                        <span th:utext="#{screen.welcome.instructions}">Enter your Username and Password:</span>

                    </h3>

                    <div id="loginErrorsPanel" class="banner banner-danger alert alert-danger banner-dismissible"

                         th:if="${#fields.hasErrors('*')}" role="alert">

                        <h2 th:utext="#{screen.authentication.error.title}">Authentication Failure</h2>

                        <p th:each="err : ${#fields.errors('*')}" th:utext="${err + ' '}">Example error</p>

                        <!--<a href="#" class="close" data-dismiss="alert" th:aria-label="#{screen.pm.button.close}">×</a>-->

                    </div>

                    <section class="cas-field form-group my-3" id="usernameSection">

                        <label for="username"

                               class="mdc-text-field mdc-text-field--outlined control-label w-100">

                            <span class="mdc-notched-outline">

                                <span class="mdc-notched-outline__leading"></span>

                                <span class="mdc-notched-outline__notch">

                                    <span class="mdc-floating-label"

                                          th:utext="#{screen.welcome.label.netid}">Username</span>

                                </span>

                                <span class="mdc-notched-outline__trailing"></span>

                            </span>

                            <input class="mdc-text-field__input form-control" id="username"

                                   size="25"

                                   type="text"

                                   th:readonly="!${@casThymeleafTemplatesDirector.isLoginFormUsernameInputVisible(#vars)}"

                                   th:field="*{username}"

                                   th:accesskey="#{screen.welcome.label.netid.accesskey}"

                                   autocapitalize="none"

                                   spellcheck="false"

                                   autocomplete="username" required />

                        </label>

                        <div class="mdc-text-field-helper-line invalid-feedback">

                            <div class="mdc-text-field-helper-text mdc-text-field-helper-text--validation-msg" aria-hidden="true">

                                <span id="usernameValidationMessage" th:utext="#{username.required}"></span>

                            </div>

                        </div>

                        <script type="text/javascript" th:inline="javascript">

                            /*<![CDATA[*/

                            let username = /*[[${@casThymeleafTemplatesDirector.getLoginFormUsername(#vars)}]]*/;

                            let disabled = /*[[${@casThymeleafTemplatesDirector.isLoginFormUsernameInputDisabled(#vars)}]]*/;

                            if (username != null && username !== '') {

                                $('#username').val(username);

                                if (disabled) {

                                    $('#usernameSection').hide();

                                }

                            }

                            /*]]>*/

                        </script>

                    </section>

                    <section class="cas-field form-group my-3 mdc-input-group form-group" id="passwordSection">

                        <div class="mdc-input-group-field mdc-input-group-field-append">

                            <label for="password"

                                   class="mdc-text-field caps-check mdc-text-field--outlined control-label mdc-text-field--with-trailing-icon control-label w-100">

                                    <span class="mdc-notched-outline">

                                        <span class="mdc-notched-outline__leading"></span>

                                        <span class="mdc-notched-outline__notch">

                                            <span class="mdc-floating-label" th:utext="#{screen.welcome.label.password}">Password</span>

                                        </span>

                                        <span class="mdc-notched-outline__trailing"></span>

                                    </span>

                                <input class="mdc-text-field__input form-control pwd"

                                       type="password"

                                       id="password"

                                       size="25"

                                       required

                                       th:accesskey="#{screen.welcome.label.password.accesskey}"

                                       th:field="*{password}"

                                       autocomplete="off"/>

                                <button

                                        class="reveal-password mdc-button mdc-button--unelevated mdc-input-group-append mdc-icon-button btn btn-primary"

                                        tabindex="-1" type="button" th:title="#{screen.pm.password.toggle}">

                                    <i class="mdi mdi-eye reveal-password-icon fas fa-eye" aria-hidden="true"></i>

                                </button>

                            </label>

                            <div class="mdc-text-field-helper-line invalid-feedback">

                                <div class="mdc-text-field-helper-text mdc-text-field-helper-text--validation-msg" aria-hidden="true">

                                    <span id="passwordValidationMessage" th:utext="#{password.required}"></span>

                                </div>

                            </div>

                        </div>

                        <div class="mdc-text-field-helper-line invalid-feedback caps-warn">

                            <div class="mdc-text-field-helper-text mdc-text-field-helper-text--persistent mdc-text-field-helper-text--validation-msg text-danger">

                                <span th:utext="#{screen.capslock.on}" />

                            </div>

                        </div>

                    </section>

                    <section id="authnSourceSection" class="cas-field form-group my-3"

                             th:if="${availableAuthenticationHandlerNames != null}">

                        <div class="d-flex">

                            <div th:if="${availableAuthenticationHandlerNames.size() > 1}"

                                 class="mdc-select mdc-select--outlined mdc-select--required mdc-menu-surface--fullwidth authn-source">

                                <div class="mdc-select__anchor"

                                     role="button"

                                     aria-required="true"

                                     aria-haspopup="listbox"

                                     aria-expanded="false">

                                    <span class="mdc-line__ripple"></span>

                                    <span class="mdc-notched-outline">

                                        <span class="mdc-notched-outline__leading"></span>

                                        <span class="mdc-notched-outline__notch">

                                            <span id="outlined-select-label" class="mdc-floating-label"

                                                  th:utext="#{screen.welcome.label.source}">Source</span>

                                        </span>

                                        <span class="mdc-notched-outline__trailing"></span>

                                    </span>

                                    <span class="mdc-select__selected-text-container">

                                        <span class="mdc-select__selected-text"/>

                                    </span>

                                    <span class="mdc-select__dropdown-icon">

                                        <svg class="mdc-select__dropdown-icon-graphic" viewBox="7 10 10 5" focusable="false">

                                            <polygon class="mdc-select__dropdown-icon-inactive" stroke="none"

                                                     fill-rule="evenodd" points="7 10 12 15 17 10">

                                            </polygon>

                                            <polygon class="mdc-select__dropdown-icon-active" stroke="none"

                                                     fill-rule="evenodd" points="7 15 12 10 17 15">

                                            </polygon>

                                        </svg>

                                    </span>

                                    <span class="mdc-line-ripple"></span>

                                </div>

                                <div class="mdc-select__menu mdc-menu mdc-menu-surface mdc-menu-surface--fullwidth">

                                    <ul class="mdc-list" role="listbox">

                                        <li th:each="handler,iter : ${availableAuthenticationHandlerNames}"

                                            class="mdc-list-item " th:id="${handler + '-authnSource'}"

                                            th:classappend="${iter.index == 0 ? 'mdc-list-item--selected' : ''}"

                                            th:data-value="${handler}" role="option">

                                            <span class="mdc-list-item__ripple"></span>

                                            <span class="mdc-list-item__text" th:utext="${handler}">Option</span>

                                        </li>

                                    </ul>

                                </div>

                                <input type="hidden" id="source" th:field="*{source}" name="source"/>

                            </div>

                            <span th:if="${availableAuthenticationHandlerNames.size() == 1}">

                                <input type="hidden" id="source" name="source"

                                       th:value="${availableAuthenticationHandlerNames.get(0)}"/>

                            </span>

                        </div>

                    </section>

                    <section class="cas-field form-group my-3">

                        <div th:each="entry: ${customLoginFormFields}">

                            <label class="mdc-text-field mdc-text-field--outlined control-label">

                                <input class="mdc-text-field__input form-control"

                                       th:id="${entry.key + '-customField'}" th:name="${entry.key + '-customField'}"

                                       size="25" type="text" th:field="*{customFields[__${entry.key}__]}"

                                       autocomplete="off"/>

                                <span class="mdc-notched-outline">

                                    <span class="mdc-notched-outline__leading"></span>

                                    <span class="mdc-notched-outline__notch">

                                        <span class="mdc-floating-label"

                                              th:text="#{${entry.value.messageBundleKey}}">Label</span>

                                    </span>

                                    <span class="mdc-notched-outline__trailing"></span>

                                </span>

                            </label>

                        </div>

                    </section>

                    <section class="cas-field form-check"

                             th:if="${'true' == #strings.defaultString(#themes.code('cas.warn-on-redirect.enabled'), 'true')}">

                        <div class="mdc-form-field ">

                            <div th:replace="~{fragments/switchbutton :: switchbutton (id='warn', label='screen.welcome.label.warn')}"/>

                        </div>

                        <p/>

                    </section>

                    <section class="cas-field form-check"

                             th:if="${'true' == #strings.defaultString(#themes.code('cas.public-workstation.enabled'), 'true')}">

                        <div class="mdc-form-field ">

                            <div th:replace="~{fragments/switchbutton :: switchbutton (id='publicWorkstation', label='screen.welcome.label.publicstation')}"/>

                        </div>

                        <p/>

                    </section>

                    <section class="cas-field form-check" th:if="${rememberMeAuthenticationEnabled}">

                        <div class="mdc-form-field ">

                            <div th:replace="~{fragments/switchbutton :: switchbutton (id='rememberMe', label='screen.rememberme.checkbox.title')}"/>

                        </div>

                        <p/>

                    </section>

                    <section class="cas-field">

                        <span th:if="${recaptchaLoginEnabled}">

                            <div th:replace="~{fragments/recaptcha :: recaptchaToken}"/>

                        </span>

                        <input type="hidden" name="execution" th:value="${flowExecutionKey}"/>

                        <input type="hidden" name="_eventId" value="submit"/>

                        <input type="hidden" name="geolocation"/>

                        <input type="hidden" name="deviceFingerprint"/>

                        <p th:if="${#strings.equalsIgnoreCase(httpRequestMethod, 'POST')}">

                            <span th:each="entry : ${httpRequestInitialPostParameters}" th:remove="tag">

                                <span th:each="entryValue : ${entry.value}" th:remove="tag">

                                    <input type="hidden" th:name="${entry.key}" th:value="${entryValue}"/>

                                </span>

                            </span>

                        </p>

                        <script type="text/javascript">

                            let client = new ClientJS();

                            let fingerprint = client.getFingerprint();

                            $('[name="deviceFingerprint"]').val(fingerprint);

                        </script>

                    </section>

                    <div th:replace="~{fragments/submitbutton :: submitButton (messageKey='screen.welcome.button.login')}"/>

                </div>

            </form>

            <div id="selectIdentityProvider"

                 th:if="${#bools.isTrue(delegatedAuthenticationDynamicProviderSelection) and loginFormViewable and loginFormEnabled}">

                <p>

                <form method="post" id="providerDiscoveryForm">

                    <input type="hidden" name="execution" th:value="${flowExecutionKey}"/>

                    <input type="hidden" name="_eventId" value="discovery"/>

                    <span class="fa fa-unlock"></span>

                    <button th:id="selectProviderButton"

                            class="mdc-button mdc-button--raised"

                            οnclick="$('#providerDiscoveryForm').submit();"

                            th:value="#{screen.pac4j.button.selectprovider}">

                        <span class="mdc-button__label" th:text="#{screen.pac4j.button.selectprovider}">Select</span>

                    </button>

                </form>

            </div>

            <div id="x509Login" th:if="${x509ClientAuthLoginEndpointUrl}">

                <span th:if="${loginFormViewable and loginFormEnabled}">

                    <hr class="my-4"/>

                    <script th:inline="javascript">

                        /*<![CDATA[*/

                        function x509login() {

                            let url =  /*[[${x509ClientAuthLoginEndpointUrl}]]*/;

                            url += window.location.search;

                            window.location.assign(url)

                        }

                        /*]]>*/

                    </script>

                    <a id="x509LoginLink" class="mdc-button mdc-button--raised btn btn-primary"

                       οnclick="javascript:x509login();"

                       th:text="#{screen.welcome.button.loginx509}">X509 Login</a>

                </span>

            </div>

            <hr th:if="${loginFormViewable and loginFormEnabled}" class="my-4"/>

            <span id="webauthnLoginPanel" th:if="${webAuthnPrimaryAuthenticationEnabled}">

                <script type="text/javascript">

                    $('#webauthnLoginPanel').show();

                </script>

                <div th:replace="~{fragments/webAuthnLogin :: webAuthnLogin}"/>

                <hr class="my-4"/>

            </span>

            <div th:if="${loginFormViewable and loginFormEnabled}">

                <span th:remove="tag"

                      th:if="${'true' == #strings.defaultString(#themes.code('cas.pm-links.enabled'), 'true')}">

                    <div th:replace="~{fragments/pmlinks :: pmlinks}"/>

                </span>

            </div>

            <script type="text/javascript" th:inline="javascript">

                /*<![CDATA[*/

                var i = /*[[@{#{screen.welcome.button.loginwip}}]]*/

                var j = /*[[@{#{screen.welcome.button.login}}]]*/

                    /*]]>*/

                    $(window).on('pageshow', function () {

                        $(':submit').prop('disabled', false);

                        $(':submit').attr('value', j);

                    });

                $(document).ready(function () {

                    $("#fm1").submit(function () {

                        $(":submit").attr("disabled", true);

                        $(":submit").attr("value", i);

                        return true;

                    });

                });

            </script>

        </div>

        <div th:if="${loginFormViewable and loginFormEnabled}">

            <div th:replace="~{fragments/loginsidebar :: loginsidebar}"/>

        </div>

    </div>

</main>

</body>

</html>

      1. application.properties

springsecurity-bootiful-cas-client-master-1\src\main\resources\application.properties

cas.server-url-prefix=${CAS_SERVER_URL_PREFIX:https://casserver.houwang.edu:8443/cas}

cas.server-login-url=${CAS_SERVER_LOGIN_URL:https://casserver.houwang.edu:8443/cas/login}

cas.client-host-url=${CAS_CLIENT_HOST_URL:http://casclient1.houwang.edu:8181}

cas.attribute-authorities=memberships

cas.use-session=true

spring.freemarker.suffix=.ftl

server.session.cookie.http-only: true

server.session.tracking-modes: COOKIE

spring.mvc.view.prefix:/WEB-INF/jsp/

spring.mvc.view.suffix:.jsp

logging.level.org.springframework.security: DEBUG

logging.level.org.jasig.cas: DEBUG

## The format used for the keystore. It could be set to JKS in case it is a JKS file

#server.ssl.key-store-type=JKS

## The path to the keystore containing the certificate

#server.ssl.key-store=classpath:keystore

## The password used to generate the certificate

#server.ssl.key-store-password=password

## The alias mapped to the certificate

#server.ssl.key-alias=tomcat

#server.error.whitelabel.enabled=false

#server.ssl.enabled=true

server.port=${MY_APP_PORT:8181}

casLogoutUrl=${CAS_LOGOUT_URL:https://casserver.houwang.edu:8443/cas/logout?service=http://casclient1.houwang.edu:8181}

      1. application.properties

springsecurity-bootiful-cas-client-master-2\src\main\resources\application.properties

cas.server-url-prefix=${CAS_SERVER_URL_PREFIX:https://casserver.houwang.edu:8443/cas}

cas.server-login-url=${CAS_SERVER_LOGIN_URL:https://casserver.houwang.edu:8443/cas/login}

cas.client-host-url=${CAS_CLIENT_HOST_URL:http://casclient2.houwang.edu:8282}

cas.attribute-authorities=memberships

cas.use-session=true

spring.freemarker.suffix=.ftl

server.session.cookie.http-only: true

server.session.tracking-modes: COOKIE

spring.mvc.view.prefix:/WEB-INF/jsp/

spring.mvc.view.suffix:.jsp

logging.level.org.springframework.security: DEBUG

logging.level.org.jasig.cas: DEBUG

## The format used for the keystore. It could be set to JKS in case it is a JKS file

#server.ssl.key-store-type=JKS

## The path to the keystore containing the certificate

#server.ssl.key-store=classpath:keystore

## The password used to generate the certificate

#server.ssl.key-store-password=password

## The alias mapped to the certificate

#server.ssl.key-alias=tomcat

#server.error.whitelabel.enabled=false

#server.ssl.enabled=true

server.port=${MY_APP_PORT:8282}

casLogoutUrl=${CAS_LOGOUT_URL:https://casserver.houwang.edu:8443/cas/logout?service=http://casclient2.houwang.edu:8282

......


http://www.kler.cn/a/547313.html

相关文章:

  • 【SLAM】在 ubuntu 18.04 arm 中以ROS环境编译与运行ORB_SLAM3
  • 网络安全防护:开源WAF雷池SafeLine本地部署与配置全流程
  • Java 基于 SpringBoot+Vue 的家政服务管理平台设计与实现
  • S32DS新建工程时不能选择芯片型号
  • 3.4 AI Agent体验设计革命:从界面美学到情感化交互的企业级设计指南
  • Spring安装和使用(Eclipse环境)
  • 前缀和(Prefix Sum)算法笔记C++
  • K8s组件
  • JavaScript 发起网络请求 axios、fetch、async / await
  • Linux基础之文件权限的八进制表示法
  • [思考.AI]AI的能力边界?通用与专用模型平衡?人机协作模式?
  • C++的constructor宜翻译为“构造器“,而不是“构造函数“
  • 如果网络中断,Promise.race 如何处理?
  • Qwen2-VL 的重大省级,Qwen 发布新旗舰视觉语言模型 Qwen2.5-VL
  • 笔试题笔记#6 模拟三道题和总结知识
  • AI全栈开发_人工智能AI大模型 Prompt提示词工程详解(全方位介绍及运用)
  • 宝塔和docker的区别
  • C++之线程池(Thread Pool)
  • [MySQL]5-MySQL扩展(分片)
  • OpenMetadata MySQL 数据库使用率提取管道实现解析