提交 bf9cfe5b 编写于 作者: N Nicky 提交者: u014427391

提交单点登录工程

上级 40a91ef8
# Compiled class file
# ---> Java
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
# ---> Eclipse
*.pydevproject
.metadata
.gradle
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
# Eclipse Core
.project
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# JDT-specific (Eclipse Java Development Tools)
.classpath
# Java annotation processor (APT)
.factorypath
# PDT-specific
.buildpath
# sbteclipse plugin
.target
# TeXlipse plugin
.texlipse
# ---> Maven
target/
out/
overlays/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# ---> TortoiseGit
# Project-level settings
/.tgitconfig
# ---> SVN
.svn/
# IDEA
*.iml
.idea/
/*.iml
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
# sso
单点登录系统
CAS Overlay Template
============================
Generic CAS maven war overlay to exercise the latest versions of CAS. This overlay could be freely used as a starting template for local CAS maven war overlays. The CAS services management overlay is available [here](https://github.com/Jasig/cas-services-management-overlay).
# Versions
```xml
<cas.version>4.2.x</cas.version>
```
# Requirements
* JDK 1.7+
# Configuration
The `etc` directory contains the configuration files that need to be copied to `/etc/cas`.
Current files are:
* `cas.properties`
* `log4j2.xml`
# Build
```bash
mvnw clean package
```
or
```bash
mvnw.bat clean package
```
# Deployment
## Embedded Jetty
* Create a Java keystore at `/etc/cas/jetty/thekeystore` with the password `changeit`.
* Import your CAS server certificate inside this keystore.
```bash
mvnw jetty:run-forked
```
CAS will be available at:
* `http://cas.server.name:8080/cas`
* `https://cas.server.name:8443/cas`
## External
Deploy resultant `target/cas.war` to a Servlet container of choice.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd ">
<modelVersion>4.0.0</modelVersion>
<groupId>com.muses</groupId>
<artifactId>cas</artifactId>
<packaging>war</packaging>
<version>1.0</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<cas.version>4.2.7</cas.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<log4j2.version>2.8.2</log4j2.version>
<fastjson.version>1.2.24</fastjson.version>
<kaptcha.version>2.3.2</kaptcha.version>
<junit.version>4.12</junit.version>
<pac4j-cas.version>2.0.0-RC1</pac4j-cas.version>
<disruptor.version>3.3.6</disruptor.version>
<cas.integration.redis.version>1.1.1-RELEASE</cas.integration.redis.version>
<mysql-connector-java.version>5.1.26</mysql-connector-java.version>
<sqljdbc4.version>3.0</sqljdbc4.version>
<druid.version>1.0.26</druid.version>
</properties>
<dependencies>
<!--<dependency>
<groupId>org.jasig.cas</groupId>
<artifactId>cas-server-webapp</artifactId>
<version>${cas.version}</version>
<type>war</type>
<scope>runtime</scope>
</dependency>-->
<dependency>
<groupId>org.jasig.cas</groupId>
<artifactId>cas-server-core</artifactId>
<version>${cas.version}</version>
</dependency>
<dependency>
<groupId>org.jasig.cas</groupId>
<artifactId>cas-server-webapp-actions</artifactId>
<version>${cas.version}</version>
</dependency>
<dependency>
<groupId>org.jasig.cas</groupId>
<artifactId>cas-server-support-rest-services</artifactId>
<version>${cas.version}</version>
</dependency>
<dependency>
<groupId>org.jasig.cas</groupId>
<artifactId>cas-server-core-logout</artifactId>
<version>${cas.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>${disruptor.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!--<dependency>
<groupId>ren.boot</groupId>
<artifactId>cas-server-integration-redis</artifactId>
<version>${cas.integration.redis.version}</version>
</dependency>-->
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version>
</dependency>
<!--pac4j test start-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.pac4j</groupId>
<artifactId>pac4j-cas</artifactId>
<version>${pac4j-cas.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.pac4j</groupId>
<artifactId>pac4j-core</artifactId>
<version>${pac4j-cas.version}</version>
<scope>test</scope>
</dependency>
<!--pac4j test end-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector-java.version}</version>
</dependency>
<!--<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>${sqljdbc4.version}</version>
</dependency>-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
</dependencies>
<build>
<finalName>cas</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warName>cas</warName>
<overlays>
<overlay>
<groupId>org.jasig.cas</groupId>
<artifactId>cas-server-webapp</artifactId>
<excludes>
<exclude>WEB-INF/cas.properties</exclude>
<exclude>WEB-INF/classes/log4j2.xml</exclude>
<exclude>WEB-INF/classes/message*.properties</exclude>
<exclude>WEB-INF/classes/services</exclude>
</excludes>
</overlay>
</overlays>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
cas-server-core-authentication\src\main\java\org\jasig\cas\authentication\UsernamePasswordCredential.java
cas-server-support-rest\src\main\java\org\jasig\cas\support\rest\TicketsResource.java
cas-server-core-authentication\src\main\java\org\jasig\cas\web\flow\AuthenticationExceptionHandler.java
cas-server-webapp-actions\src\main\java\org\jasig\cas\web\flow\AuthenticationViaFormAction.java
cas-server-core\src\main\java\org\jasig\cas\CentralAuthenticationServiceImpl.java
\ No newline at end of file
package com.muses.taoshop.sso.authentication;
import org.jasig.cas.authentication.HandlerResult;
import org.jasig.cas.authentication.PreventedException;
import org.jasig.cas.authentication.UsernamePasswordCredential;
import org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler;
import java.security.GeneralSecurityException;
/**
* <pre>
* Cas单点登录用户名密码校验
* </pre>
*
* @author nicky
* @version 1.00.00
* <pre>
* 修改记录
* 修改后版本: 修改人: 修改日期: 2018.08.19 22:16 修改内容:
* </pre>
*/
public class UsernamePasswordAuthenticationHandler extends AbstractUsernamePasswordAuthenticationHandler{
@Override
protected HandlerResult authenticateUsernamePasswordInternal(UsernamePasswordCredential usernamePasswordCredential) throws GeneralSecurityException, PreventedException {
return null;
}
protected void doTest(){
try{
System.out.println();
}catch (Exception e){
e.printStackTrace();
}
}
}
package org.jasig.cas.adaptors.jdbc;
import org.apache.commons.lang3.StringUtils;
import org.jasig.cas.authentication.HandlerResult;
import org.jasig.cas.authentication.PreventedException;
import org.jasig.cas.authentication.UsernamePasswordCredential;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.stereotype.Component;
import javax.security.auth.login.AccountNotFoundException;
import javax.security.auth.login.FailedLoginException;
import javax.sql.DataSource;
import javax.validation.constraints.NotNull;
import java.security.GeneralSecurityException;
/**
* Class that if provided a query that returns a password (parameter of query
* must be username) will compare that password to a translated version of the
* password provided by the user. If they match, then authentication succeeds.
* Default password translator is plaintext translator.
*
* @author Scott Battaglia
* @author Dmitriy Kopylenko
* @author Marvin S. Addison
*
* @since 3.0.0
*/
@Component("queryDatabaseAuthenticationHandler")
public class QueryDatabaseAuthenticationHandler extends AbstractJdbcUsernamePasswordAuthenticationHandler {
@NotNull
private String sql;
@Override
protected final HandlerResult authenticateUsernamePasswordInternal(final UsernamePasswordCredential credential)
throws GeneralSecurityException, PreventedException {
if (StringUtils.isBlank(this.sql) || getJdbcTemplate() == null) {
throw new GeneralSecurityException("Authentication handler is not configured correctly");
}
final String username = credential.getUsername();
final String encryptedPassword = this.getPasswordEncoder().encode(credential.getPassword());
try {
final String dbPassword = getJdbcTemplate().queryForObject(this.sql, String.class, username);
if (!dbPassword.equals(encryptedPassword)) {
throw new FailedLoginException("Password does not match value on record.");
}
} catch (final IncorrectResultSizeDataAccessException e) {
if (e.getActualSize() == 0) {
throw new AccountNotFoundException(username + " not found with SQL query");
} else {
throw new FailedLoginException("Multiple records found for " + username);
}
} catch (final DataAccessException e) {
throw new PreventedException("SQL exception while executing query for " + username, e);
}
return createHandlerResult(credential, this.principalFactory.createPrincipal(username), null);
}
/**
* @param sql The sql to set.
*/
@Autowired
public void setSql(@Value("${cas.jdbc.authn.query.sql:}") final String sql) {
this.sql = sql;
}
@Override
@Autowired(required = false)
public void setDataSource(@Qualifier("queryDatabaseDataSource") final DataSource dataSource) {
super.setDataSource(dataSource);
}
}
package org.jasig.cas.authentication;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
/**
* Credential for authenticating with a username and password.
*
* @author Scott Battaglia
* @author Marvin S. Addison
* @since 3.0.0
*/
public class UsernamePasswordCredential implements Credential, Serializable {
/** Authentication attribute name for password. **/
public static final String AUTHENTICATION_ATTRIBUTE_PASSWORD = "credential";
private static final long serialVersionUID = -700605081472810939L;
@NotNull
@Size(min=1, message = "required.username")
private String username;
@NotNull
@Size(min=1, message = "required.password")
private String password;
/** Default constructor. */
public UsernamePasswordCredential() {}
/**
* Creates a new instance with the given username and password.
*
* @param userName Non-null user name.
* @param password Non-null password.
*/
public UsernamePasswordCredential(final String userName, final String password) {
this.username = userName;
this.password = password;
}
public final String getPassword() {
return this.password;
}
public final void setPassword(final String password) {
this.password = password;
}
public final String getUsername() {
return this.username;
}
public final void setUsername(final String userName) {
this.username = userName;
}
@Override
public String getId() {
return this.username;
}
@Override
public String toString() {
return this.username;
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final UsernamePasswordCredential that = (UsernamePasswordCredential) o;
if (password != null ? !password.equals(that.password) : that.password != null) {
return false;
}
if (username != null ? !username.equals(that.username) : that.username != null) {
return false;
}
return true;
}
@Override
public int hashCode() {
return new HashCodeBuilder()
.append(username)
.append(password)
.toHashCode();
}
}
package org.jasig.cas.support.rest;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.jasig.cas.CasProtocolConstants;
import org.jasig.cas.CentralAuthenticationService;
import org.jasig.cas.authentication.AuthenticationContext;
import org.jasig.cas.authentication.AuthenticationContextBuilder;
import org.jasig.cas.authentication.AuthenticationSystemSupport;
import org.jasig.cas.authentication.AuthenticationException;
import org.jasig.cas.authentication.AuthenticationTransaction;
import org.jasig.cas.authentication.Credential;
import org.jasig.cas.authentication.DefaultAuthenticationContextBuilder;
import org.jasig.cas.authentication.DefaultAuthenticationSystemSupport;
import org.jasig.cas.authentication.UsernamePasswordCredential;
import org.jasig.cas.authentication.principal.Service;
import org.jasig.cas.authentication.principal.ServiceFactory;
import org.jasig.cas.ticket.InvalidTicketException;
import org.jasig.cas.ticket.ServiceTicket;
import org.jasig.cas.ticket.TicketGrantingTicket;
import org.jasig.cas.ticket.registry.DefaultTicketRegistrySupport;
import org.jasig.cas.ticket.registry.TicketRegistrySupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import java.net.URI;
import java.util.Formatter;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* {@link RestController} implementation of CAS' REST API.
*
* This class implements main CAS RESTful resource for vending/deleting TGTs and vending STs:
*
* <ul>
* <li>{@code POST /v1/tickets}</li>
* <li>{@code POST /v1/tickets/{TGT-id}}</li>
* <li>{@code DELETE /v1/tickets/{TGT-id}}</li>
* </ul>
*
* @author Dmitriy Kopylenko
* @since 4.1.0
*/
@RestController("ticketResourceRestController")
public class TicketsResource {
private static final Logger LOGGER = LoggerFactory.getLogger(TicketsResource.class);
@Autowired
@Qualifier("centralAuthenticationService")
private CentralAuthenticationService centralAuthenticationService;
@NotNull
@Autowired(required=false)
@Qualifier("defaultAuthenticationSystemSupport")
private AuthenticationSystemSupport authenticationSystemSupport = new DefaultAuthenticationSystemSupport();
@Autowired(required = false)
private final CredentialFactory credentialFactory = new DefaultCredentialFactory();
@Autowired
@Qualifier("webApplicationServiceFactory")
private ServiceFactory webApplicationServiceFactory;
@Autowired
@Qualifier("defaultTicketRegistrySupport")
private TicketRegistrySupport ticketRegistrySupport = new DefaultTicketRegistrySupport();
private final ObjectMapper jacksonObjectMapper = new ObjectMapper();
/**
* Create new ticket granting ticket.
*
* @param requestBody username and password application/x-www-form-urlencoded values
* @param request raw HttpServletRequest used to call this method
* @return ResponseEntity representing RESTful response
* @throws JsonProcessingException in case of JSON parsing failure
*/
@RequestMapping(value = "/v1/tickets", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public final ResponseEntity<String> createTicketGrantingTicket(@RequestBody final MultiValueMap<String, String> requestBody,
final HttpServletRequest request) throws JsonProcessingException {
try (Formatter fmt = new Formatter()) {
final Credential credential = this.credentialFactory.fromRequestBody(requestBody);
final AuthenticationContextBuilder builder = new DefaultAuthenticationContextBuilder(
this.authenticationSystemSupport.getPrincipalElectionStrategy());
final AuthenticationTransaction transaction =
AuthenticationTransaction.wrap(credential);
this.authenticationSystemSupport.getAuthenticationTransactionManager().handle(transaction, builder);
final AuthenticationContext authenticationContext = builder.build();
final TicketGrantingTicket tgtId = this.centralAuthenticationService.createTicketGrantingTicket(authenticationContext);
final URI ticketReference = new URI(request.getRequestURL().toString() + '/' + tgtId.getId());
final HttpHeaders headers = new HttpHeaders();
headers.setLocation(ticketReference);
headers.setContentType(MediaType.TEXT_HTML);
fmt.format("<!DOCTYPE HTML PUBLIC \\\"-//IETF//DTD HTML 2.0//EN\\\"><html><head><title>");
fmt.format("%s %s", HttpStatus.CREATED, HttpStatus.CREATED.getReasonPhrase())
.format("</title></head><body><h1>TGT Created</h1><form action=\"%s", ticketReference.toString())
.format("\" method=\"POST\">Service:<input type=\"text\" name=\"service\" value=\"\">")
.format("<br><input type=\"submit\" value=\"Submit\"></form></body></html>");
return new ResponseEntity<>(fmt.toString(), headers, HttpStatus.CREATED);
}
catch(final AuthenticationException e) {
final List<String> authnExceptions = new LinkedList<>();
for (final Map.Entry<String, Class<? extends Exception>> handlerErrorEntry: e.getHandlerErrors().entrySet()) {
authnExceptions.add(handlerErrorEntry.getValue().getSimpleName());
}
final Map<String, List<String>> errorsMap = new HashMap<>();
errorsMap.put("authentication_exceptions", authnExceptions);
LOGGER.error(e.getMessage(), e);
LOGGER.error(String.format("Caused by: %s", authnExceptions));
return new ResponseEntity<>(this.jacksonObjectMapper
.writer()
.withDefaultPrettyPrinter()
.writeValueAsString(errorsMap), HttpStatus.UNAUTHORIZED);
} catch (final BadRequestException e) {
LOGGER.error(e.getMessage(), e);
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
} catch (final Throwable e) {
LOGGER.error(e.getMessage(), e);
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
/**
* Create new service ticket.
*
* @param requestBody service application/x-www-form-urlencoded value
* @param tgtId ticket granting ticket id URI path param
* @return {@link ResponseEntity} representing RESTful response
*/
@RequestMapping(value = "/v1/tickets/{tgtId:.+}", method = RequestMethod.POST, consumes = MediaType
.APPLICATION_FORM_URLENCODED_VALUE)
public final ResponseEntity<String> createServiceTicket(@RequestBody final MultiValueMap<String, String> requestBody,
@PathVariable("tgtId") final String tgtId) {
try {
final String serviceId = requestBody.getFirst(CasProtocolConstants.PARAMETER_SERVICE);
final AuthenticationContextBuilder builder = new DefaultAuthenticationContextBuilder(
this.authenticationSystemSupport.getPrincipalElectionStrategy());
final Service service = this.webApplicationServiceFactory.createService(serviceId);
final AuthenticationContext authenticationContext =
builder.collect(this.ticketRegistrySupport.getAuthenticationFrom(tgtId)).build(service);
final ServiceTicket serviceTicketId = this.centralAuthenticationService.grantServiceTicket(tgtId,
service, authenticationContext);
return new ResponseEntity<>(serviceTicketId.getId(), HttpStatus.OK);
} catch (final InvalidTicketException e) {
return new ResponseEntity<>("TicketGrantingTicket could not be found", HttpStatus.NOT_FOUND);
} catch (final Exception e) {
LOGGER.error(e.getMessage(), e);
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
/**
* Destroy ticket granting ticket.
*
* @param tgtId ticket granting ticket id URI path param
* @return {@link ResponseEntity} representing RESTful response. Signals
* {@link HttpStatus#OK} when successful.
*/
@RequestMapping(value = "/v1/tickets/{tgtId:.+}", method = RequestMethod.DELETE)
public final ResponseEntity<String> deleteTicketGrantingTicket(@PathVariable("tgtId") final String tgtId) {
this.centralAuthenticationService.destroyTicketGrantingTicket(tgtId);
return new ResponseEntity<>(tgtId, HttpStatus.OK);
}
public void setAuthenticationSystemSupport(final AuthenticationSystemSupport authenticationSystemSupport) {
this.authenticationSystemSupport = authenticationSystemSupport;
}
public void setWebApplicationServiceFactory(final ServiceFactory webApplicationServiceFactory) {
this.webApplicationServiceFactory = webApplicationServiceFactory;
}
public void setTicketRegistrySupport(final TicketRegistrySupport ticketRegistrySupport) {
this.ticketRegistrySupport = ticketRegistrySupport;
}
public void setCentralAuthenticationService(final CentralAuthenticationService centralAuthenticationService) {
this.centralAuthenticationService = centralAuthenticationService;
}
public CentralAuthenticationService getCentralAuthenticationService() {
return centralAuthenticationService;
}
public AuthenticationSystemSupport getAuthenticationSystemSupport() {
return authenticationSystemSupport;
}
public CredentialFactory getCredentialFactory() {
return credentialFactory;
}
public ServiceFactory getWebApplicationServiceFactory() {
return webApplicationServiceFactory;
}
public TicketRegistrySupport getTicketRegistrySupport() {
return ticketRegistrySupport;
}
/**
* Default implementation of CredentialFactory.
*/
private static class DefaultCredentialFactory implements CredentialFactory {
@Override
public Credential fromRequestBody(@NotNull final MultiValueMap<String, String> requestBody) {
final String username = requestBody.getFirst("username");
final String password = requestBody.getFirst("password");
if(username == null || password == null) {
throw new BadRequestException("Invalid payload. 'username' and 'password' form fields are required.");
}
return new UsernamePasswordCredential(requestBody.getFirst("username"), requestBody.getFirst("password"));
}
}
/**
* Exception to indicate bad payload.
*/
private static class BadRequestException extends IllegalArgumentException {
private static final long serialVersionUID = 6852720596988243487L;
/**
* Ctor.
* @param msg error message
*/
BadRequestException(final String msg) {
super(msg);
}
}
}
package org.jasig.cas.web.flow;
import org.jasig.cas.authentication.AuthenticationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.binding.message.MessageBuilder;
import org.springframework.binding.message.MessageContext;
import org.springframework.stereotype.Component;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Performs two important error handling functions on an {@link AuthenticationException} raised from the authentication
* layer:
*
* <ol>
* <li>Maps handler errors onto message bundle strings for display to user.</li>
* <li>Determines the next webflow state by comparing handler errors against {@link #errors}
* in list order. The first entry that matches determines the outcome state, which
* is the simple class name of the exception.</li>
* </ol>
*
* @author Marvin S. Addison
* @since 4.0.0
*/
@Component("authenticationExceptionHandler")
public class AuthenticationExceptionHandler {
/** State name when no matching exception is found. */
public static final String UNKNOWN = "UNKNOWN";
/** Default message bundle prefix. */
private static final String DEFAULT_MESSAGE_BUNDLE_PREFIX = "authenticationFailure.";
/** Default list of errors this class knows how to handle. */
private static final List<Class<? extends Exception>> DEFAULT_ERROR_LIST =
new ArrayList<>();
private final transient Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* Order is important here; We want the account policy exceptions to be handled
* first before moving onto more generic errors. In the event that multiple handlers
* are defined, where one failed due to account policy restriction and one fails
* due to a bad password, we want the error associated with the account policy
* to be processed first, rather than presenting a more generic error associated
* with latter handlers.
*/
static {
DEFAULT_ERROR_LIST.add(javax.security.auth.login.AccountLockedException.class);
DEFAULT_ERROR_LIST.add(javax.security.auth.login.CredentialExpiredException.class);
DEFAULT_ERROR_LIST.add(org.jasig.cas.authentication.AccountDisabledException.class);
DEFAULT_ERROR_LIST.add(org.jasig.cas.authentication.InvalidLoginLocationException.class);
DEFAULT_ERROR_LIST.add(org.jasig.cas.authentication.AccountPasswordMustChangeException.class);
DEFAULT_ERROR_LIST.add(org.jasig.cas.authentication.InvalidLoginTimeException.class);
DEFAULT_ERROR_LIST.add(javax.security.auth.login.AccountNotFoundException.class);
DEFAULT_ERROR_LIST.add(javax.security.auth.login.FailedLoginException.class);
}
/** Ordered list of error classes that this class knows how to handle. */
@NotNull
private List<Class<? extends Exception>> errors = DEFAULT_ERROR_LIST;
/** String appended to exception class name to create a message bundle key for that particular error. */
private String messageBundlePrefix = DEFAULT_MESSAGE_BUNDLE_PREFIX;
/**
* Sets the list of errors that this class knows how to handle.
*
* @param errors List of errors in order of descending precedence.
*/
public void setErrors(final List<Class<? extends Exception>> errors) {
this.errors = errors;
}
public final List<Class<? extends Exception>> getErrors() {
return Collections.unmodifiableList(this.errors);
}
/**
* Sets the message bundle prefix appended to exception class names to create a message bundle key for that
* particular error.
*
* @param prefix Prefix appended to exception names.
*/
public void setMessageBundlePrefix(final String prefix) {
this.messageBundlePrefix = prefix;
}
/**
* Maps an authentication exception onto a state name equal to the simple class name of the.
*
* @param e Authentication error to handle.
* @param messageContext the spring message context
* @return Name of next flow state to transition to or {@value #UNKNOWN}
* {@link AuthenticationException#getHandlerErrors()} with highest precedence.
* Also sets an ERROR severity message in the message context of the form
* {@code [messageBundlePrefix][exceptionClassSimpleName]} for each handler error that is
* configured. If not match is found, {@value #UNKNOWN} is returned.
*/
public String handle(final AuthenticationException e, final MessageContext messageContext) {
if (e != null) {
final MessageBuilder builder = new MessageBuilder();
for (final Class<? extends Exception> kind : this.errors) {
for (final Class<? extends Exception> handlerError : e.getHandlerErrors().values()) {
if (handlerError != null && handlerError.equals(kind)) {
final String handlerErrorName = handlerError.getSimpleName();
final String messageCode = this.messageBundlePrefix + handlerErrorName;
messageContext.addMessage(builder.error().code(messageCode).build());
return handlerErrorName;
}
}
}
}
final String messageCode = this.messageBundlePrefix + UNKNOWN;
logger.trace("Unable to translate handler errors of the authentication exception {}. Returning {} by default...", e, messageCode);
messageContext.addMessage(new MessageBuilder().error().code(messageCode).build());
return UNKNOWN;
}
}
package org.jasig.cas.web.flow;
import org.apache.commons.lang3.StringUtils;
import org.jasig.cas.CasProtocolConstants;
import org.jasig.cas.CentralAuthenticationService;
import org.jasig.cas.authentication.AuthenticationContext;
import org.jasig.cas.authentication.AuthenticationContextBuilder;
import org.jasig.cas.authentication.AuthenticationException;
import org.jasig.cas.authentication.AuthenticationSystemSupport;
import org.jasig.cas.authentication.AuthenticationTransaction;
import org.jasig.cas.authentication.Credential;
import org.jasig.cas.authentication.DefaultAuthenticationContextBuilder;
import org.jasig.cas.authentication.DefaultAuthenticationSystemSupport;
import org.jasig.cas.authentication.HandlerResult;
import org.jasig.cas.authentication.MessageDescriptor;
import org.jasig.cas.authentication.principal.Service;
import org.jasig.cas.ticket.AbstractTicketException;
import org.jasig.cas.ticket.ServiceTicket;
import org.jasig.cas.ticket.TicketCreationException;
import org.jasig.cas.ticket.TicketGrantingTicket;
import org.jasig.cas.web.support.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.binding.message.MessageBuilder;
import org.springframework.binding.message.MessageContext;
import org.springframework.stereotype.Component;
import org.springframework.web.util.CookieGenerator;
import org.springframework.webflow.core.collection.LocalAttributeMap;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;
import javax.validation.constraints.NotNull;
import java.util.Map;
/**
* Action to authenticate credential and retrieve a TicketGrantingTicket for
* those credential. If there is a request for renew, then it also generates
* the Service Ticket required.
*
* @author Scott Battaglia
* @since 3.0.0
*/
@Component("authenticationViaFormAction")
public class AuthenticationViaFormAction {
/** Authentication succeeded with warnings from authn subsystem that should be displayed to user. */
public static final String SUCCESS_WITH_WARNINGS = "successWithWarnings";
/** Authentication failure result. */
public static final String AUTHENTICATION_FAILURE = "authenticationFailure";
/** Flow scope attribute that determines if authn is happening at a public workstation. */
public static final String PUBLIC_WORKSTATION_ATTRIBUTE = "publicWorkstation";
/** Logger instance. **/
protected final transient Logger logger = LoggerFactory.getLogger(getClass());
/** Core we delegate to for handling all ticket related tasks. */
@NotNull
@Autowired
@Qualifier("centralAuthenticationService")
private CentralAuthenticationService centralAuthenticationService;
@NotNull
@Autowired
@Qualifier("warnCookieGenerator")
private CookieGenerator warnCookieGenerator;
@NotNull
@Autowired(required=false)
@Qualifier("defaultAuthenticationSystemSupport")
private AuthenticationSystemSupport authenticationSystemSupport = new DefaultAuthenticationSystemSupport();
/**
* Handle the submission of credentials from the post.
*
* @param context the context
* @param credential the credential
* @param messageContext the message context
* @return the event
* @since 4.1.0
*/
public final Event submit(final RequestContext context, final Credential credential,
final MessageContext messageContext) {
if (isRequestAskingForServiceTicket(context)) {
return grantServiceTicket(context, credential);
}
return createTicketGrantingTicket(context, credential, messageContext);
}
/**
* Is request asking for service ticket?
*
* @param context the context
* @return true, if both service and tgt are found, and the request is not asking to renew.
* @since 4.1.0
*/
protected boolean isRequestAskingForServiceTicket(final RequestContext context) {
final String ticketGrantingTicketId = WebUtils.getTicketGrantingTicketId(context);
final Service service = WebUtils.getService(context);
return (StringUtils.isNotBlank(context.getRequestParameters().get(CasProtocolConstants.PARAMETER_RENEW))
&& ticketGrantingTicketId != null
&& service != null);
}
/**
* Grant service ticket for the given credential based on the service and tgt
* that are found in the request context.
*
* @param context the context
* @param credential the credential
* @return the resulting event. Warning, authentication failure or error.
* @since 4.1.0
*/
protected Event grantServiceTicket(final RequestContext context, final Credential credential) {
final String ticketGrantingTicketId = WebUtils.getTicketGrantingTicketId(context);
try {
final Service service = WebUtils.getService(context);
final AuthenticationContextBuilder builder = new DefaultAuthenticationContextBuilder(
this.authenticationSystemSupport.getPrincipalElectionStrategy());
final AuthenticationTransaction transaction =
AuthenticationTransaction.wrap(credential);
this.authenticationSystemSupport.getAuthenticationTransactionManager().handle(transaction, builder);
final AuthenticationContext authenticationContext = builder.build(service);
final ServiceTicket serviceTicketId = this.centralAuthenticationService.grantServiceTicket(
ticketGrantingTicketId, service, authenticationContext);
WebUtils.putServiceTicketInRequestScope(context, serviceTicketId);
WebUtils.putWarnCookieIfRequestParameterPresent(this.warnCookieGenerator, context);
return newEvent(AbstractCasWebflowConfigurer.TRANSITION_ID_WARN);
} catch (final AuthenticationException e) {
return newEvent(AUTHENTICATION_FAILURE, e);
} catch (final TicketCreationException e) {
logger.warn("Invalid attempt to access service using renew=true with different credential. Ending SSO session.");
this.centralAuthenticationService.destroyTicketGrantingTicket(ticketGrantingTicketId);
} catch (final AbstractTicketException e) {
return newEvent(AbstractCasWebflowConfigurer.TRANSITION_ID_ERROR, e);
}
return newEvent(AbstractCasWebflowConfigurer.TRANSITION_ID_ERROR);
}
/**
* Create ticket granting ticket for the given credentials.
* Adds all warnings into the message context.
*
* @param context the context
* @param credential the credential
* @param messageContext the message context
* @return the resulting event.
* @since 4.1.0
*/
protected Event createTicketGrantingTicket(final RequestContext context, final Credential credential,
final MessageContext messageContext) {
try {
final Service service = WebUtils.getService(context);
final AuthenticationContextBuilder builder = new DefaultAuthenticationContextBuilder(
this.authenticationSystemSupport.getPrincipalElectionStrategy());
final AuthenticationTransaction transaction =
AuthenticationTransaction.wrap(credential);
this.authenticationSystemSupport.getAuthenticationTransactionManager().handle(transaction, builder);
final AuthenticationContext authenticationContext = builder.build(service);
final TicketGrantingTicket tgt = this.centralAuthenticationService.createTicketGrantingTicket(authenticationContext);
WebUtils.putTicketGrantingTicketInScopes(context, tgt);
WebUtils.putWarnCookieIfRequestParameterPresent(this.warnCookieGenerator, context);
putPublicWorkstationToFlowIfRequestParameterPresent(context);
if (addWarningMessagesToMessageContextIfNeeded(tgt, messageContext)) {
return newEvent(SUCCESS_WITH_WARNINGS);
}
return newEvent(AbstractCasWebflowConfigurer.TRANSITION_ID_SUCCESS);
} catch (final AuthenticationException e) {
logger.debug(e.getMessage(), e);
return newEvent(AUTHENTICATION_FAILURE, e);
} catch (final Exception e) {
logger.debug(e.getMessage(), e);
return newEvent(AbstractCasWebflowConfigurer.TRANSITION_ID_ERROR, e);
}
}
/**
* Add warning messages to message context if needed.
*
* @param tgtId the tgt id
* @param messageContext the message context
* @return true if warnings were found and added, false otherwise.
* @since 4.1.0
*/
protected boolean addWarningMessagesToMessageContextIfNeeded(final TicketGrantingTicket tgtId, final MessageContext messageContext) {
boolean foundAndAddedWarnings = false;
for (final Map.Entry<String, HandlerResult> entry : tgtId.getAuthentication().getSuccesses().entrySet()) {
for (final MessageDescriptor message : entry.getValue().getWarnings()) {
addWarningToContext(messageContext, message);
foundAndAddedWarnings = true;
}
}
return foundAndAddedWarnings;
}
/**
* Put public workstation into the flow if request parameter present.
*
* @param context the context
*/
private static void putPublicWorkstationToFlowIfRequestParameterPresent(final RequestContext context) {
if (StringUtils.isNotBlank(context.getExternalContext()
.getRequestParameterMap().get(PUBLIC_WORKSTATION_ATTRIBUTE))) {
context.getFlowScope().put(PUBLIC_WORKSTATION_ATTRIBUTE, Boolean.TRUE);
}
}
/**
* New event based on the given id.
*
* @param id the id
* @return the event
*/
private Event newEvent(final String id) {
return new Event(this, id);
}
/**
* New event based on the id, which contains an error attribute referring to the exception occurred.
*
* @param id the id
* @param error the error
* @return the event
*/
private Event newEvent(final String id, final Exception error) {
return new Event(this, id, new LocalAttributeMap("error", error));
}
/**
* Adds a warning message to the message context.
*
* @param context Message context.
* @param warning Warning message.
*/
private static void addWarningToContext(final MessageContext context, final MessageDescriptor warning) {
final MessageBuilder builder = new MessageBuilder()
.warning()
.code(warning.getCode())
.defaultText(warning.getDefaultMessage())
.args(warning.getParams());
context.addMessage(builder.build());
}
public void setCentralAuthenticationService(final CentralAuthenticationService centralAuthenticationService) {
this.centralAuthenticationService = centralAuthenticationService;
}
public void setWarnCookieGenerator(final CookieGenerator warnCookieGenerator) {
this.warnCookieGenerator = warnCookieGenerator;
}
public void setAuthenticationSystemSupport(final AuthenticationSystemSupport authenticationSystemSupport) {
this.authenticationSystemSupport = authenticationSystemSupport;
}
}
#CAS督昢華硊
cas.server.host.url=http://localhost:8082/
#CAS督昢腎翹華硊
cas.server.host.login_url=${cas.server.host.url}/login
#CAS督昢腎堤華硊
cas.server.host.logout_url=${cas.server.host.url}/logout?service=${app.server.host.url}
#茼蚚溼恀華硊
app.server.host.url=http://localhost:8080
#茼蚚腎翹華硊
app.login.url=/login
#茼蚚腎堤華硊
app.logout.url=/logout
\ No newline at end of file
server:
port: 8082
spring:
datasource:
# 主数据源
shop:
url: jdbc:mysql://127.0.0.1:3306/taoshop?autoReconnect=true&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&useSSL=false
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
# 连接池设置
druid:
initial-size: 5
min-idle: 5
max-active: 20
# 配置获取连接等待超时的时间
max-wait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 300000
# Oracle请使用select 1 from dual
validation-query: SELECT 'x'
test-while-idle: true
test-on-borrow: false
test-on-return: false
# 打开PSCache,并且指定每个连接上PSCache的大小
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall,slf4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
# 合并多个DruidDataSource的监控数据
use-global-data-source-stat: true
# jpa:
# database: mysql
# hibernate:
# show_sql: true
# format_sql: true
# ddl-auto: none
# naming:
# physical-strategy: org.hibernate.boot.entity.naming.PhysicalNamingStrategyStandardImpl
# mvc:
# view:
# prefix: /WEB-INF/jsp/
# suffix: .jsp
#添加Thymeleaf配置
thymeleaf:
cache: false
prefix: classpath:/templates/
suffix: .html
mode: HTML5
encoding: UTF-8
content-type: text/html
#Jedis配置
# jedis :
# pool :
# host : 127.0.0.1
# port : 6379
# password : redispassword
# timeout : 0
# config :
# maxTotal : 100
# maxIdle : 10
# maxWaitMillis : 100000
{
"@class" : "org.jasig.cas.services.RegexRegisteredService",
"serviceId" : "^https://www.apereo.org",
"name" : "Apereo",
"theme" : "apereo",
"id" : 10000002,
"description" : "Apereo foundation sample service",
"proxyPolicy" : {
"@class" : "org.jasig.cas.services.RefuseRegisteredServiceProxyPolicy"
},
"evaluationOrder" : 1,
"usernameAttributeProvider" : {
"@class" : "org.jasig.cas.services.DefaultRegisteredServiceUsernameProvider"
},
"logoutType" : "BACK_CHANNEL",
"attributeReleasePolicy" : {
"@class" : "org.jasig.cas.services.ReturnAllowedAttributeReleasePolicy",
"principalAttributesRepository" : {
"@class" : "org.jasig.cas.authentication.principal.DefaultPrincipalAttributesRepository"
},
"authorizedToReleaseCredentialPassword" : false,
"authorizedToReleaseProxyGrantingTicket" : false
},
"accessStrategy" : {
"@class" : "org.jasig.cas.services.DefaultRegisteredServiceAccessStrategy",
"enabled" : true,
"ssoEnabled" : true
}
}
\ No newline at end of file
{
"@class" : "org.jasig.cas.services.RegexRegisteredService",
"serviceId" : "^(https|imaps|http)://.*",
"name" : "HTTPS and IMAPS",
"id" : 10000001,
"description" : "This service definition authorized all application urls that support HTTPS and IMAPS protocols.",
"proxyPolicy" : {
"@class" : "org.jasig.cas.services.RefuseRegisteredServiceProxyPolicy"
},
"evaluationOrder" : 10000,
"usernameAttributeProvider" : {
"@class" : "org.jasig.cas.services.DefaultRegisteredServiceUsernameProvider"
},
"logoutType" : "BACK_CHANNEL",
"attributeReleasePolicy" : {
"@class" : "org.jasig.cas.services.ReturnAllowedAttributeReleasePolicy",
"principalAttributesRepository" : {
"@class" : "org.jasig.cas.authentication.principal.DefaultPrincipalAttributesRepository"
},
"authorizedToReleaseCredentialPassword" : false,
"authorizedToReleaseProxyGrantingTicket" : false
},
"accessStrategy" : {
"@class" : "org.jasig.cas.services.DefaultRegisteredServiceAccessStrategy",
"enabled" : true,
"ssoEnabled" : true
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:webflow="http://www.springframework.org/schema/webflow-config"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.3.xsd">
<import resource="spring-configuration/propertyFileConfigurer.xml"/>
<bean id="themeChangeInterceptor"
class="org.springframework.web.servlet.theme.ThemeChangeInterceptor"
p:paramName="${cas.themeResolver.param.name:theme}"/>
<bean id="beanNameViewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver"
p:order="1"/>
<!--
<bean id="xmlViewResolver" class="org.springframework.web.servlet.view.XmlViewResolver"
p:order="1000"
p:location="${cas.viewResolver.xmlFile:classpath:/META-INF/spring/views.xml}" />
-->
<bean id="urlBasedViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver"
p:viewClass="org.springframework.web.servlet.view.InternalResourceView"
p:prefix="${cas.themeResolver.pathprefix:/WEB-INF/view/jsp}/"
p:suffix=".jsp"
p:order="2000"/>
<!-- Locale Resolver -->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"
p:defaultLocale="${locale.default:en}"/>
<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"
p:paramName="${locale.param.name:locale}"/>
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!-- login webflow configuration -->
<bean id="loginFlowHandlerMapping" class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping"
p:flowRegistry-ref="loginFlowRegistry" p:order="2">
<property name="interceptors">
<array value-type="org.springframework.web.servlet.HandlerInterceptor">
<ref bean="localeChangeInterceptor"/>
<ref bean="authenticationThrottle"/>
</array>
</property>
</bean>
<bean id="loginHandlerAdapter" class="org.jasig.cas.web.flow.SelectiveFlowHandlerAdapter"
p:supportedFlowId="login" p:flowExecutor-ref="loginFlowExecutor" p:flowUrlHandler-ref="loginFlowUrlHandler"/>
<bean id="loginFlowUrlHandler" class="org.jasig.cas.web.flow.CasDefaultFlowUrlHandler"/>
<bean name="loginFlowExecutor" class="org.springframework.webflow.executor.FlowExecutorImpl"
c:definitionLocator-ref="loginFlowRegistry"
c:executionFactory-ref="loginFlowExecutionFactory"
c:executionRepository-ref="loginFlowExecutionRepository"/>
<bean name="loginFlowExecutionFactory" class="org.springframework.webflow.engine.impl.FlowExecutionImplFactory"
p:executionKeyFactory-ref="loginFlowExecutionRepository"/>
<bean id="loginFlowExecutionRepository" class=" org.jasig.spring.webflow.plugin.ClientFlowExecutionRepository"
c:flowExecutionFactory-ref="loginFlowExecutionFactory"
c:flowDefinitionLocator-ref="loginFlowRegistry"
c:transcoder-ref="loginFlowStateTranscoder"/>
<bean id="loginFlowStateTranscoder" class="org.jasig.spring.webflow.plugin.EncryptedTranscoder"
c:cipherBean-ref="loginFlowCipherBean" />
<!-- logout webflow configuration -->
<bean id="logoutFlowHandlerMapping" class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping"
p:flowRegistry-ref="logoutFlowRegistry" p:order="3">
<property name="interceptors">
<array value-type="org.springframework.web.servlet.HandlerInterceptor">
<ref bean="localeChangeInterceptor"/>
</array>
</property>
</bean>
<bean id="logoutHandlerAdapter" class="org.jasig.cas.web.flow.SelectiveFlowHandlerAdapter"
p:supportedFlowId="logout" p:flowExecutor-ref="logoutFlowExecutor"
p:flowUrlHandler-ref="logoutFlowUrlHandler"/>
<bean id="logoutFlowUrlHandler" class="org.jasig.cas.web.flow.CasDefaultFlowUrlHandler"
p:flowExecutionKeyParameter="RelayState"/>
<bean id="credentialsValidator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"
p:messageInterpolator-ref="messageInterpolator"/>
</beans>
此差异已折叠。
此差异已折叠。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<bean id="dataSourceOA" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="url" value="${portal.jdbc.jdbcUrl}"/>
<property name="username" value="${portal.jdbc.user}"/>
<property name="password" value="${portal.jdbc.password}"/>
<property name="initialSize" value="${portal.jdbc.initialSize}"/>
<property name="minIdle" value="${portal.jdbc.minIdle}"/>
<property name="maxActive" value="${portal.jdbc.maxActive}"/>
<property name="maxWait" value="60000"/>
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000"/>
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000"/>
<property name="validationQuery" value="SELECT 1"/>
<property name="testWhileIdle" value="true"/>
<property name="testOnBorrow" value="false"/>
<property name="testOnReturn" value="false"/>
<!-- 打开removeAbandoned功能 -->
<property name="removeAbandoned" value="true"/>
<property name="removeAbandonedTimeout" value="1800"/>
<!-- 1800秒,也就是30分钟 -->
<property name="logAbandoned" value="true"/>
<!-- 打开PSCache,并且指定每个连接上PSCache的大小,mysql 不使用 -->
<property name="poolPreparedStatements" value="false"/>
<property name="filters" value="config" />
<property name="connectionProperties" value="config.decrypt=true;config.decrypt.key=${portal.jdbc.publickey};druid.stat.slowSqlMillis=200;druid.stat.logSlowSql=true"/>
</bean>
<util:map id="authenticationHandlersResolvers">
<entry key-ref="proxyAuthenticationHandler" value-ref="proxyPrincipalResolver" />
<!--<entry key-ref="primaryAuthenticationHandler" value-ref="primaryPrincipalResolver" />-->
<entry key-ref="usernamePasswordAuthenticationHandler" value-ref="primaryPrincipalResolver" />
</util:map>
<util:list id="authenticationMetadataPopulators">
<ref bean="successfulHandlerMetaDataPopulator" />
<ref bean="rememberMeAuthenticationMetaDataPopulator" />
</util:list>
<bean id="attributeRepository" class="org.jasig.services.persondir.support.NamedStubPersonAttributeDao"
p:backingMap-ref="attrRepoBackingMap" />
<alias name="acceptUsersAuthenticationHandler" alias="primaryAuthenticationHandler" />
<alias name="personDirectoryPrincipalResolver" alias="primaryPrincipalResolver" />
<util:map id="attrRepoBackingMap">
<entry key="uid" value="uid" />
<entry key="eduPersonAffiliation" value="eduPersonAffiliation" />
<entry key="groupMembership" value="groupMembership" />
<entry>
<key><value>memberOf</value></key>
<list>
<value>faculty</value>
<value>staff</value>
<value>org</value>
</list>
</entry>
</util:map>
<alias name="serviceThemeResolver" alias="themeResolver" />
<alias name="jsonServiceRegistryDao" alias="serviceRegistryDao" />
<!--<alias name="defaultTicketRegistry" alias="ticketRegistry" />-->
<!-- redis来保存Server Ticket,并设置TGC有效期,PS:这里设置的失效期是指Redis的,并非指ST的有效期-->
<!--<alias name="redisTicketRegistry" alias="ticketRegistry" />
<bean id="redisTicketRegistry" class="ren.boot.cas.ticket.registry.RedisTicketRegistry"
p:client-ref="ticketRedisTemplate"
p:tgtTimeout="${tgt.maxTimeToLiveInSeconds}"
p:stTimeout="${st.timeToKillInSeconds}"/>
&lt;!&ndash; redis连接池 &ndash;&gt;
<bean id="jedisConnFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:hostName="${redis.hostName}"
p:database="${redis.database}"
p:password="${redis.password}"
p:port="${redis.port}"
p:usePool="true"/>
<bean id="ticketRedisTemplate" class="ren.boot.cas.ticket.registry.TicketRedisTemplate"
p:connectionFactory-ref="jedisConnFactory"/>-->
<alias name="ticketGrantingTicketExpirationPolicy" alias="grantingTicketExpirationPolicy" />
<alias name="multiTimeUseOrTimeoutExpirationPolicy" alias="serviceTicketExpirationPolicy" />
<alias name="anyAuthenticationPolicy" alias="authenticationPolicy" />
<alias name="acceptAnyAuthenticationPolicyFactory" alias="authenticationPolicyFactory" />
<bean id="auditTrailManager"
class="org.jasig.inspektr.audit.support.Slf4jLoggingAuditTrailManager"
p:entrySeparator="${cas.audit.singleline.separator:|}"
p:useSingleLine="${cas.audit.singleline:false}"/>
<alias name="neverThrottle" alias="authenticationThrottle" />
<util:list id="monitorsList">
<ref bean="memoryMonitor" />
<ref bean="sessionMonitor" />
</util:list>
<alias name="defaultPrincipalFactory" alias="principalFactory" />
<alias name="defaultAuthenticationTransactionManager" alias="authenticationTransactionManager" />
<alias name="defaultPrincipalElectionStrategy" alias="principalElectionStrategy" />
<alias name="tgcCipherExecutor" alias="defaultCookieCipherExecutor" />
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<description>
This file lets CAS know where you've stored the cas.properties file which details some of the configuration
options
that are specific to your environment. You can specify the location of the file here. You may wish to place the
file outside
of the Servlet context if you have options that are specific to a tier (i.e. test vs. production) so that the
WAR file
can be moved between tiers without modification.
</description>
<util:properties id="casProperties" location="cas_${config_env}.properties"/>
<context:property-placeholder properties-ref="casProperties"/>
</beans>
<jsp:directive.include file="/WEB-INF/view/jsp/default/ui/includes/top.jsp" />
<%@ page isErrorPage="true" %>
<%@ page import="org.jasig.cas.web.support.WebUtils"%>
<div id="msg" class="errors">
<h2>${pageContext.errorData.statusCode} - <spring:message code="screen.blocked.header" /></h2>
<%
Object casAcessDeniedKey = request.getAttribute(WebUtils.CAS_ACCESS_DENIED_REASON);
request.setAttribute("casAcessDeniedKey", casAcessDeniedKey);
%>
<c:choose>
<c:when test="${not empty casAcessDeniedKey}">
<p><spring:message code="${casAcessDeniedKey}" /></p>
</c:when>
</c:choose>
<p><%=request.getAttribute("javax.servlet.error.message")%></p>
<p><spring:message code="AbstractAccessDecisionManager.accessDenied"/></p>
</div>
<jsp:directive.include file="/WEB-INF/view/jsp/default/ui/includes/bottom.jsp" />
<jsp:directive.include file="includes/top.jsp" />
<div id="login" style="width: 100%;">
<form:form method="post" id="fm1" htmlEscape="true">
<h2>Acceptable Usage Policy</h2>
<div>
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>
By using these resources, you agree to abide by the Acceptable Usage Policy.
</p>
<p>Click '<spring:message code="screen.aup.button.accept" />' to continue. Otherwise, click '<spring:message code="screen.aup.button.cancel" />'.</p>
</div>
<section class="row btn-row">
<input type="hidden" name="execution" value="${flowExecutionKey}" />
<input type="hidden" name="_eventId" value="submit" />
<input class="btn-submit" name="submit" accesskey="s" value="<spring:message code="screen.aup.button.accept" />" type="submit" />
<input class="btn-reset" name="cancel" accesskey="c"
value="<spring:message code="screen.aup.button.cancel" />" type="button"
onclick="location.href = location.href;" />
</section>
</form:form>
</div>
<jsp:directive.include file="includes/bottom.jsp" />
<jsp:directive.include file="includes/top.jsp" />
<div id="msg" class="errors">
<h2><spring:message code="screen.accountdisabled.heading" /></h2>
<p><spring:message code="screen.accountdisabled.message" /></p>
</div>
<jsp:directive.include file="includes/bottom.jsp" />
<jsp:directive.include file="includes/top.jsp" />
<div id="msg" class="errors">
<h2><spring:message code="screen.accountlocked.heading" /></h2>
<p><spring:message code="screen.accountlocked.message" /></p>
</div>
<jsp:directive.include file="includes/bottom.jsp" />
<jsp:directive.include file="includes/top.jsp" />
<div id="msg" class="errors">
<h2><spring:message code="screen.badhours.heading" /></h2>
<p><spring:message code="screen.badhours.message" /></p>
</div>
<jsp:directive.include file="includes/bottom.jsp" />
<jsp:directive.include file="includes/top.jsp" />
<div id="msg" class="errors">
<h2><spring:message code="screen.badworkstation.heading" /></h2>
<p><spring:message code="screen.badworkstation.message" /></p>
</div>
<jsp:directive.include file="includes/bottom.jsp" />
<jsp:directive.include file="includes/top.jsp" />
<div id="msg" class="info">
<p><spring:message code="screen.confirmation.message" arguments="${fn:escapeXml(param.service)}${fn:indexOf(param.service, '?') eq -1 ? '?' : '&'}ticket=${serviceTicketId}" /></p>
</div>
<jsp:directive.include file="includes/bottom.jsp" />
\ No newline at end of file
<jsp:directive.include file="includes/top.jsp" />
<div id="msg" class="errors">
<h2><spring:message code="screen.expiredpass.heading" /></h2>
<p><spring:message code="screen.expiredpass.message" arguments="${passwordPolicyUrl}" /></p>
</div>
<jsp:directive.include file="includes/bottom.jsp" />
<jsp:directive.include file="includes/top.jsp" />
<div id="msg" class="success">
<h2><spring:message code="screen.success.header" /></h2>
<p><spring:message code="screen.success.success" arguments="${principal.id}"/></p>
<p><spring:message code="screen.success.security" /></p>
</div>
<jsp:directive.include file="includes/bottom.jsp" />
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<jsp:directive.include file="includes/top.jsp" />
<div id="msg" class="warn">
<h2>Authentication Succeeded with Warnings</h2>
<c:forEach items="${messages}" var="message">
<p class="message">${message.text}</p>
</c:forEach>
</div>
<c:url value="login" var="url">
<c:param name="execution" value="${flowExecutionKey}" />
<c:param name="_eventId" value="proceed" />
</c:url>
<div id="big-buttons">
<a class="button" href="${url}">Continue</a>
</div>
<jsp:directive.include file="includes/bottom.jsp" />
<jsp:directive.include file="includes/top.jsp" />
<%-- 登录页面屏蔽CAS安全提示
<c:if test="${not pageContext.request.secure}">
<div id="msg" class="errors">
<h2><spring:message code="screen.nonsecure.title" /></h2>
<p><spring:message code="screen.nonsecure.message" /></p>
</div>
</c:if>--%>
<div id="cookiesDisabled" class="errors" style="display:none;">
<h2><spring:message code="screen.cookies.disabled.title" /></h2>
<p><spring:message code="screen.cookies.disabled.message" /></p>
</div>
<c:if test="${not empty registeredService}">
<c:set var="registeredServiceLogo" value="images/webapp.png"/>
<c:set var="registeredServiceName" value="${registeredService.name}"/>
<c:set var="registeredServiceDescription" value="${registeredService.description}"/>
<c:choose>
<c:when test="${not empty mduiContext}">
<c:if test="${not empty mduiContext.logoUrl}">
<c:set var="registeredServiceLogo" value="${mduiContext.logoUrl}"/>
</c:if>
<c:set var="registeredServiceName" value="${mduiContext.displayName}"/>
<c:set var="registeredServiceDescription" value="${mduiContext.description}"/>
</c:when>
<c:when test="${not empty registeredService.logo}">
<c:set var="registeredServiceLogo" value="${registeredService.logo}"/>
</c:when>
</c:choose>
<div id="serviceui" class="serviceinfo">
<table>
<tr>
<td><img src="${registeredServiceLogo}"></td>
<td id="servicedesc">
<h1>${fn:escapeXml(registeredServiceName)}</h1>
<p>${fn:escapeXml(registeredServiceDescription)}</p>
</td>
</tr>
</table>
</div>
<p/>
</c:if>
<div class="box" id="login">
<form:form method="post" id="fm1" commandName="${commandName}" htmlEscape="true">
<form:errors path="*" id="msg" cssClass="errors" element="div" htmlEscape="false" />
<h2><spring:message code="screen.welcome.instructions" /></h2>
<section class="row">
<label for="username"><spring:message code="screen.welcome.label.netid" /></label>
<c:choose>
<c:when test="${not empty sessionScope.openIdLocalId}">
<strong><c:out value="${sessionScope.openIdLocalId}" /></strong>
<input type="hidden" id="username" name="username" value="<c:out value="${sessionScope.openIdLocalId}" />" />
</c:when>
<c:otherwise>
<spring:message code="screen.welcome.label.netid.accesskey" var="userNameAccessKey" />
<form:input cssClass="required" cssErrorClass="error" id="username" size="25" tabindex="1" accesskey="${userNameAccessKey}" path="username" autocomplete="off" htmlEscape="true" />
</c:otherwise>
</c:choose>
</section>
<section class="row">
<label for="password"><spring:message code="screen.welcome.label.password" /></label>
<%--
NOTE: Certain browsers will offer the option of caching passwords for a user. There is a non-standard attribute,
"autocomplete" that when set to "off" will tell certain browsers not to prompt to cache credentials. For more
information, see the following web page:
http://www.technofundo.com/tech/web/ie_autocomplete.html
--%>
<spring:message code="screen.welcome.label.password.accesskey" var="passwordAccessKey" />
<form:password cssClass="required" cssErrorClass="error" id="password" size="25" tabindex="2" path="password" accesskey="${passwordAccessKey}" htmlEscape="true" autocomplete="off" />
<span id="capslock-on" style="display:none;"><p><img src="images/warning.png" valign="top"> <spring:message code="screen.capslock.on" /></p></span>
</section>
<!--
<section class="row check">
<p>
<input id="warn" name="warn" value="true" tabindex="3" accesskey="<spring:message code="screen.welcome.label.warn.accesskey" />" type="checkbox" />
<label for="warn"><spring:message code="screen.welcome.label.warn" /></label>
<br/>
<input id="publicWorkstation" name="publicWorkstation" value="false" tabindex="4" type="checkbox" />
<label for="publicWorkstation"><spring:message code="screen.welcome.label.publicstation" /></label>
<br/>
<input type="checkbox" name="rememberMe" id="rememberMe" value="true" tabindex="5" />
<label for="rememberMe"><spring:message code="screen.rememberme.checkbox.title" /></label>
</p>
</section>
-->
<section class="row btn-row">
<input type="hidden" name="execution" value="${flowExecutionKey}" />
<input type="hidden" name="_eventId" value="submit" />
<input class="btn-submit" name="submit" accesskey="l" value="<spring:message code="screen.welcome.button.login" />" tabindex="6" type="submit" />
<input class="btn-reset" name="reset" accesskey="c" value="<spring:message code="screen.welcome.button.clear" />" tabindex="7" type="reset" />
</section>
</form:form>
</div>
<div id="sidebar">
<div class="sidebar-content">
<p><spring:message code="screen.welcome.security" /></p>
<c:if test="${!empty pac4jUrls}">
<div id="list-providers">
<h3><spring:message code="screen.welcome.label.loginwith" /></h3>
<form>
<ul>
<c:forEach var="entry" items="${pac4jUrls}">
<li><a href="${entry.value}">${entry.key}</a></li>
</c:forEach>
</ul>
</form>
</div>
</c:if>
<div id="list-languages">
<%final String queryString = request.getQueryString() == null ? "" : request.getQueryString().replaceAll("&locale=([A-Za-z][A-Za-z]_)?[A-Za-z][A-Za-z]|^locale=([A-Za-z][A-Za-z]_)?[A-Za-z][A-Za-z]", "");%>
<c:set var='query' value='<%=queryString%>' />
<c:set var="xquery" value="${fn:escapeXml(query)}" />
<h3>Languages:</h3>
<c:choose>
<c:when test="${not empty requestScope['isMobile'] and not empty mobileCss}">
<form method="get" action="login?${xquery}">
<select name="locale">
<option value="en">English</option>
<option value="es">Spanish</option>
<option value="fr">French</option>
<option value="ru">Russian</option>
<option value="nl">Nederlands</option>
<option value="sv">Svenska</option>
<option value="it">Italiano</option>
<option value="ur">Urdu</option>
<option value="zh_CN">Chinese (Simplified)</option>
<option value="zh_TW">Chinese (Traditional)</option>
<option value="de">Deutsch</option>
<option value="ja">Japanese</option>
<option value="hr">Croatian</option>
<option value="uk">Ukranian</option>
<option value="cs">Czech</option>
<option value="sk">Slovak</option>
<option value="sl">Slovenian</option>
<option value="pl">Polish</option>
<option value="ca">Catalan</option>
<option value="mk">Macedonian</option>
<option value="fa">Farsi</option>
<option value="ar">Arabic</option>
<option value="pt_PT">Portuguese</option>
<option value="pt_BR">Portuguese (Brazil)</option>
</select>
<input type="submit" value="Switch">
</form>
</c:when>
<c:otherwise>
<c:set var="loginUrl" value="login?${xquery}${not empty xquery ? '&' : ''}locale=" />
<ul>
<li class="first"><a href="${loginUrl}en">English</a></li>
<li><a href="${loginUrl}es">Spanish</a></li>
<li><a href="${loginUrl}fr">French</a></li>
<li><a href="${loginUrl}ru">Russian</a></li>
<li><a href="${loginUrl}nl">Nederlands</a></li>
<li><a href="${loginUrl}sv">Svenska</a></li>
<li><a href="${loginUrl}it">Italiano</a></li>
<li><a href="${loginUrl}ur">Urdu</a></li>
<li><a href="${loginUrl}zh_CN">Chinese (Simplified)</a></li>
<li><a href="${loginUrl}zh_TW">Chinese (Traditional)</a></li>
<li><a href="${loginUrl}de">Deutsch</a></li>
<li><a href="${loginUrl}ja">Japanese</a></li>
<li><a href="${loginUrl}hr">Croatian</a></li>
<li><a href="${loginUrl}uk">Ukranian</a></li>
<li><a href="${loginUrl}cs">Czech</a></li>
<li><a href="${loginUrl}sk">Slovak</a></li>
<li><a href="${loginUrl}sl">Slovenian</a></li>
<li><a href="${loginUrl}ca">Catalan</a></li>
<li><a href="${loginUrl}mk">Macedonian</a></li>
<li><a href="${loginUrl}fa">Farsi</a></li>
<li><a href="${loginUrl}ar">Arabic</a></li>
<li><a href="${loginUrl}pt_PT">Portuguese</a></li>
<li><a href="${loginUrl}pt_BR">Portuguese (Brazil)</a></li>
<li class="last"><a href="${loginUrl}pl">Polish</a></li>
</ul>
</c:otherwise>
</c:choose>
</div>
</div>
</div>
<jsp:directive.include file="includes/bottom.jsp" />
<jsp:directive.include file="includes/top.jsp" />
<div id="msg" class="success">
<h2><spring:message code="screen.logout.header" /></h2>
<p><spring:message code="screen.logout.success" /></p>
<p><spring:message code="screen.logout.security" /></p>
</div>
<jsp:directive.include file="includes/bottom.jsp" />
\ No newline at end of file
<jsp:directive.include file="includes/top.jsp" />
<div id="msg" class="errors">
<h2><spring:message code="screen.mustchangepass.heading" /></h2>
<p><spring:message code="screen.mustchangepass.message" arguments="${passwordPolicyUrl}" /></p>
</div>
<jsp:directive.include file="includes/bottom.jsp" />
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
</div> <!-- END #content -->
<footer>
<div id="copyright" class="container">
<p><spring:message code="copyright" /></p>
<p>Powered by <a href="http://www.apereo.org/cas">
Apereo Central Authentication Service <%=org.jasig.cas.CasVersion.getVersion()%></a>
<%=org.jasig.cas.CasVersion.getDateTime()%></p>
</div>
</footer>
</div> <!-- END #container -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/headjs/1.0.3/head.min.js"></script>
<spring:theme code="cas.javascript.file" var="casJavascriptFile" text="" />
<script type="text/javascript" src="<c:url value="${casJavascriptFile}" />"></script>
</body>
</html>
<!DOCTYPE html>
<%@ page pageEncoding="UTF-8" %>
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>CAS &#8211; Central Authentication Service</title>
<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>
<spring:theme code="standard.custom.css.file" var="customCssFile" />
<link rel="stylesheet" href="<c:url value="${customCssFile}" />" />
<link rel="icon" href="<c:url value="/favicon.ico" />" type="image/x-icon" />
</head>
<body id="cas">
<div id="container">
<header>
<a id="logo" href="http://www.apereo.org" title="<spring:message code="logo.title" />">Apereo</a>
<h1>Central Authentication Service (CAS)</h1>
</header>
<div id="content">
<jsp:directive.include file="includes/top.jsp" />
<c:url var="url" value="/login">
<c:param name="service" value="${param.service}" />
<c:param name="renew" value="true" />
</c:url>
<div id="msg" class="errors">
<h2><spring:message code="screen.service.sso.error.header" /></h2>
<p><spring:message code="screen.service.sso.error.message" arguments="${fn:escapeXml(url)}" /></p>
</div>
<jsp:directive.include file="includes/bottom.jsp" />
<jsp:directive.include file="includes/top.jsp" />
<div id="msg" class="errors">
<h2><spring:message code="screen.service.error.header" /></h2>
<p><spring:message code="${rootCauseException.code}" /></p>
</div>
<jsp:directive.include file="includes/bottom.jsp" />
<jsp:directive.include file="default/ui/includes/top.jsp" />
<div id="msg" class="errors">
<h2><spring:message code="screen.unavailable.heading" /></h2>
<p><spring:message code="screen.unavailable.message" /></p>
</div>
<jsp:directive.include file="default/ui/includes/bottom.jsp" />
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>Central Authentication System (CAS)</display-name>
<!--<context-param>-->
<!--<param-name>isLog4jAutoInitializationDisabled</param-name>-->
<!--<param-value>true</param-value>-->
<!--</context-param>-->
<!--<listener>-->
<!--<listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>-->
<!--</listener>-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-configuration/*.xml
/WEB-INF/deployerConfigContext.xml
<!-- this enables extensions and addons to contribute to overall CAS' application context
by loading spring context files from classpath i.e. found in classpath jars, etc. -->
classpath*:/META-INF/spring/*.xml
</param-value>
</context-param>
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<async-supported>true</async-supported>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>CAS Client Info Logging Filter</filter-name>
<filter-class>org.jasig.inspektr.common.web.ClientInfoThreadLocalFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter-mapping>
<filter-name>CAS Client Info Logging Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>requestParameterSecurityFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<async-supported>true</async-supported>
</filter>
<filter-mapping>
<filter-name>requestParameterSecurityFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>responseHeadersSecurityFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<async-supported>true</async-supported>
</filter>
<filter-mapping>
<filter-name>responseHeadersSecurityFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
- Loads the CAS ApplicationContext.
-->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.jasig.cas.CasEnvironmentContextListener
</listener-class>
</listener>
<!--
- This is the Spring dispatcher servlet which delegates all requests to the
- Spring WebMVC controllers as configured in cas-servlet.xml.
- This configuration also provides a plugin mechanism which enables un-intrusive contributions to the DispatcherServlet
- child application context (via local Maven or Gradle war overlays for example)
- and thus an ability to override beans defined in cas-servlet.xml by means of including additional
- Spring XML config files with a naming convention pattern of /WEB-INF/cas-servlet-*.xml
-->
<servlet>
<servlet-name>cas</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- Load the child application context. Start with the default, then modules, then overlays. -->
<param-value>/WEB-INF/cas-servlet.xml,classpath*:/META-INF/cas-servlet-*.xml,/WEB-INF/cas-servlet-*.xml</param-value>
</init-param>
<init-param>
<param-name>publishContext</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/logout</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/validate</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/serviceValidate</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/p3/serviceValidate</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/proxy</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/proxyValidate</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/p3/proxyValidate</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/CentralAuthenticationService</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/status</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/statistics</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/statistics/ping</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/statistics/metrics</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/statistics/threads</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/statistics/healthcheck</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/statistics/ssosessions/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/statistics/ssosessions</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/status/config/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/status/config</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/authorizationFailure.html</url-pattern>
</servlet-mapping>
<!-- REST support if cas-server-support-rest is included -->
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/v1/tickets/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/v1/services/*</url-pattern>
</servlet-mapping>
<session-config>
<!-- Default to 5 minute session timeouts -->
<session-timeout>5</session-timeout>
<tracking-mode>COOKIE</tracking-mode>
<cookie-config>
<http-only>true</http-only>
</cookie-config>
</session-config>
<error-page>
<error-code>401</error-code>
<location>/authorizationFailure.html</location>
</error-page>
<error-page>
<error-code>403</error-code>
<location>/authorizationFailure.html</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/WEB-INF/view/jsp/errors.jsp</location>
</error-page>
<error-page>
<error-code>501</error-code>
<location>/WEB-INF/view/jsp/errors.jsp</location>
</error-page>
<error-page>
<error-code>503</error-code>
<location>/WEB-INF/view/jsp/errors.jsp</location>
</error-page>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/webflow"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow.xsd">
<var name="credential" class="org.jasig.cas.authentication.UsernamePasswordCredential"/>
<!--
<var name="credential" class="org.jasig.cas.authentication.RememberMeUsernamePasswordCredential" />
-->
<on-start>
<evaluate expression="initialFlowSetupAction"/>
</on-start>
<action-state id="ticketGrantingTicketCheck">
<evaluate expression="ticketGrantingTicketCheckAction"/>
<transition on="notExists" to="gatewayRequestCheck"/>
<transition on="invalid" to="terminateSession"/>
<transition on="valid" to="hasServiceCheck"/>
</action-state>
<action-state id="terminateSession">
<evaluate expression="terminateSessionAction.terminate(flowRequestContext)"/>
<transition to="gatewayRequestCheck"/>
</action-state>
<decision-state id="gatewayRequestCheck">
<if test="requestParameters.gateway != '' and requestParameters.gateway != null and flowScope.service != null"
then="gatewayServicesManagementCheck" else="serviceAuthorizationCheck"/>
</decision-state>
<decision-state id="hasServiceCheck">
<if test="flowScope.service != null" then="renewRequestCheck" else="viewGenericLoginSuccess"/>
</decision-state>
<decision-state id="renewRequestCheck">
<if test="requestParameters.renew != '' and requestParameters.renew != null" then="serviceAuthorizationCheck"
else="generateServiceTicket"/>
</decision-state>
<!-- Do a service authorization check early without the need to login first -->
<action-state id="serviceAuthorizationCheck">
<evaluate expression="serviceAuthorizationCheck"/>
<transition to="initializeLogin"/>
</action-state>
<!--
The "warn" action makes the determination of whether to redirect directly to the requested
service or display the "confirmation" page to go back to the server.
-->
<decision-state id="warn">
<if test="flowScope.warnCookieValue" then="showWarningView" else="redirect"/>
</decision-state>
<action-state id="initializeLogin">
<evaluate expression="'success'"/>
<transition on="success" to="viewLoginForm"/>
</action-state>
<view-state id="viewLoginForm" view="casLoginView" model="credential">
<binder>
<binding property="username" required="true"/>
<binding property="password" required="true"/>
<!--
<binding property="rememberMe" />
-->
</binder>
<on-entry>
<set name="viewScope.commandName" value="'credential'"/>
<!--
<evaluate expression="samlMetadataUIParserAction" />
-->
</on-entry>
<transition on="submit" bind="true" validate="true" to="realSubmit"/>
</view-state>
<action-state id="realSubmit">
<evaluate
expression="authenticationViaFormAction.submit(flowRequestContext, flowScope.credential, messageContext)"/>
<transition on="warn" to="warn"/>
<!--
To enable AUP workflows, replace the 'success' transition with the following:
<transition on="success" to="acceptableUsagePolicyCheck" />
-->
<transition on="success" to="sendTicketGrantingTicket"/>
<transition on="successWithWarnings" to="showMessages"/>
<transition on="authenticationFailure" to="handleAuthenticationFailure"/>
<transition on="error" to="initializeLogin"/>
</action-state>
<view-state id="showMessages" view="casLoginMessageView">
<on-entry>
<evaluate expression="sendTicketGrantingTicketAction"/>
<set name="requestScope.messages" value="messageContext.allMessages"/>
</on-entry>
<transition on="proceed" to="serviceCheck"/>
</view-state>
<action-state id="handleAuthenticationFailure">
<evaluate expression="authenticationExceptionHandler.handle(currentEvent.attributes.error, messageContext)"/>
<transition on="AccountDisabledException" to="casAccountDisabledView"/>
<transition on="AccountLockedException" to="casAccountLockedView"/>
<transition on="AccountPasswordMustChangeException" to="casMustChangePassView"/>
<transition on="CredentialExpiredException" to="casExpiredPassView"/>
<transition on="InvalidLoginLocationException" to="casBadWorkstationView"/>
<transition on="InvalidLoginTimeException" to="casBadHoursView"/>
<transition on="FailedLoginException" to="initializeLogin"/>
<transition on="AccountNotFoundException" to="initializeLogin"/>
<transition on="UNKNOWN" to="initializeLogin"/>
</action-state>
<action-state id="sendTicketGrantingTicket">
<evaluate expression="sendTicketGrantingTicketAction"/>
<transition to="serviceCheck"/>
</action-state>
<decision-state id="serviceCheck">
<if test="flowScope.service != null" then="generateServiceTicket" else="viewGenericLoginSuccess"/>
</decision-state>
<action-state id="generateServiceTicket">
<evaluate expression="generateServiceTicketAction"/>
<transition on="success" to="warn"/>
<transition on="authenticationFailure" to="handleAuthenticationFailure"/>
<transition on="error" to="initializeLogin"/>
<transition on="gateway" to="gatewayServicesManagementCheck"/>
</action-state>
<action-state id="gatewayServicesManagementCheck">
<evaluate expression="gatewayServicesManagementCheck"/>
<transition on="success" to="redirect"/>
</action-state>
<action-state id="redirect">
<evaluate expression="flowScope.service.getResponse(requestScope.serviceTicketId)"
result-type="org.jasig.cas.authentication.principal.Response" result="requestScope.response"/>
<transition to="postRedirectDecision"/>
</action-state>
<decision-state id="postRedirectDecision">
<if test="requestScope.response.responseType.name() == 'POST'" then="postView" else="redirectView"/>
</decision-state>
<!--
the "viewGenericLoginSuccess" is the end state for when a user attempts to login without coming directly from a service.
They have only initialized their single-sign on session.
-->
<end-state id="viewGenericLoginSuccess" view="casGenericSuccessView">
<on-entry>
<evaluate expression="genericSuccessViewAction.getAuthenticationPrincipal(flowScope.ticketGrantingTicketId)"
result="requestScope.principal"
result-type="org.jasig.cas.authentication.principal.Principal"/>
</on-entry>
</end-state>
<!--
The "showWarningView" end state is the end state for when the user has requested privacy settings (to be "warned")
to be turned on. It delegates to a view defines in default_views.properties that display the
"Please click here to go to the service." message.
-->
<end-state id="showWarningView" view="casConfirmView"/>
<!-- Password policy failure states -->
<end-state id="abstactPasswordChangeView">
<on-entry>
<set name="flowScope.passwordPolicyUrl" value="passwordPolicyConfiguration.passwordPolicyUrl"/>
</on-entry>
</end-state>
<end-state id="casExpiredPassView" view="casExpiredPassView" parent="#abstactPasswordChangeView"/>
<end-state id="casMustChangePassView" view="casMustChangePassView" parent="#abstactPasswordChangeView"/>
<end-state id="casAccountDisabledView" view="casAccountDisabledView"/>
<end-state id="casAccountLockedView" view="casAccountLockedView"/>
<end-state id="casBadHoursView" view="casBadHoursView"/>
<end-state id="casBadWorkstationView" view="casBadWorkstationView"/>
<end-state id="postView" view="postResponseView">
<on-entry>
<set name="requestScope.parameters" value="requestScope.response.attributes"/>
<set name="requestScope.originalUrl" value="flowScope.service.id"/>
</on-entry>
</end-state>
<!--
The "redirect" end state allows CAS to properly end the workflow while still redirecting
the user back to the service required.
-->
<end-state id="redirectView" view="externalRedirect:#{requestScope.response.url}"/>
<end-state id="viewServiceErrorView" view="serviceErrorView"/>
<decision-state id="serviceUnauthorizedCheck">
<if test="flowScope.unauthorizedRedirectUrl != null"
then="viewRedirectToUnauthorizedUrlView"
else="viewServiceErrorView"/>
</decision-state>
<end-state id="viewRedirectToUnauthorizedUrlView" view="externalRedirect:#{flowScope.unauthorizedRedirectUrl}"/>
<end-state id="viewServiceSsoErrorView" view="serviceErrorSsoView" />
<global-transitions>
<transition to="viewLoginForm" on-exception="org.jasig.cas.services.UnauthorizedSsoServiceException"/>
<transition to="viewServiceErrorView"
on-exception="org.springframework.webflow.execution.repository.NoSuchFlowExecutionException"/>
<transition to="serviceUnauthorizedCheck" on-exception="org.jasig.cas.services.UnauthorizedServiceException"/>
<transition to="serviceUnauthorizedCheck" on-exception="org.jasig.cas.services.UnauthorizedServiceForPrincipalException" />
</global-transitions>
</flow>
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow.xsd">
<action-state id="terminateSession">
<evaluate expression="terminateSessionAction.terminate(flowRequestContext)" />
<transition to="doLogout" />
</action-state>
<action-state id="doLogout">
<evaluate expression="logoutAction" />
<transition on="finish" to="finishLogout" />
<transition on="front" to="frontLogout" />
</action-state>
<action-state id="frontLogout">
<evaluate expression="frontChannelLogoutAction" />
<transition on="finish" to="finishLogout" />
<transition on="redirectApp" to="redirectToFrontApp" />
</action-state>
<view-state id="redirectToFrontApp" view="externalRedirect:#{currentEvent.attributes.logoutUrl}&amp;RelayState=#{flowExecutionContext.key}">
<transition on="next" to="frontLogout" />
</view-state>
<decision-state id="finishLogout">
<if test="flowScope.logoutRedirectUrl != null" then="redirectView" else="logoutView" />
</decision-state>
<end-state id="redirectView" view="externalRedirect:#{flowScope.logoutRedirectUrl}" />
<end-state id="logoutView" view="casLogoutView" />
</flow>
此差异已折叠。
<html>
<body>
<h2>Hello World!</h2>
</body>
</html>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册