diff --git a/spring-cloud-security/1.2.2.RELEASE/css/highlight.css b/spring-cloud-security/1.2.2.RELEASE/css/highlight.css new file mode 100644 index 00000000..ffefef72 --- /dev/null +++ b/spring-cloud-security/1.2.2.RELEASE/css/highlight.css @@ -0,0 +1,35 @@ +/* + code highlight CSS resemblign the Eclipse IDE default color schema + @author Costin Leau +*/ + +.hl-keyword { + color: #7F0055; + font-weight: bold; +} + +.hl-comment { + color: #3F5F5F; + font-style: italic; +} + +.hl-multiline-comment { + color: #3F5FBF; + font-style: italic; +} + +.hl-tag { + color: #3F7F7F; +} + +.hl-attribute { + color: #7F007F; +} + +.hl-value { + color: #2A00FF; +} + +.hl-string { + color: #2A00FF; +} \ No newline at end of file diff --git a/spring-cloud-security/1.2.2.RELEASE/css/manual-multipage.css b/spring-cloud-security/1.2.2.RELEASE/css/manual-multipage.css new file mode 100644 index 00000000..0c484531 --- /dev/null +++ b/spring-cloud-security/1.2.2.RELEASE/css/manual-multipage.css @@ -0,0 +1,9 @@ +@IMPORT url("manual.css"); + +body.firstpage { + background: url("../images/background.png") no-repeat center top; +} + +div.part h1 { + border-top: none; +} diff --git a/spring-cloud-security/1.2.2.RELEASE/css/manual-singlepage.css b/spring-cloud-security/1.2.2.RELEASE/css/manual-singlepage.css new file mode 100644 index 00000000..4a7fd140 --- /dev/null +++ b/spring-cloud-security/1.2.2.RELEASE/css/manual-singlepage.css @@ -0,0 +1,6 @@ +@IMPORT url("manual.css"); + +body { + background: url("../images/background.png") no-repeat center top; +} + diff --git a/spring-cloud-security/1.2.2.RELEASE/css/manual.css b/spring-cloud-security/1.2.2.RELEASE/css/manual.css new file mode 100644 index 00000000..0ecbe2e8 --- /dev/null +++ b/spring-cloud-security/1.2.2.RELEASE/css/manual.css @@ -0,0 +1,344 @@ +@IMPORT url("highlight.css"); + +html { + padding: 0pt; + margin: 0pt; +} + +body { + color: #333333; + margin: 15px 30px; + font-family: Helvetica, Arial, Freesans, Clean, Sans-serif; + line-height: 1.6; + -webkit-font-smoothing: antialiased; +} + +code { + font-size: 16px; + font-family: Consolas, "Liberation Mono", Courier, monospace; +} + +:not(a)>code { + color: #6D180B; +} + +:not(pre)>code { + background-color: #F2F2F2; + border: 1px solid #CCCCCC; + border-radius: 4px; + padding: 1px 3px 0; + text-shadow: none; + white-space: nowrap; +} + +body>*:first-child { + margin-top: 0 !important; +} + +div { + margin: 0pt; +} + +hr { + border: 1px solid #CCCCCC; + background: #CCCCCC; +} + +h1,h2,h3,h4,h5,h6 { + color: #000000; + cursor: text; + font-weight: bold; + margin: 30px 0 10px; + padding: 0; +} + +h1,h2,h3 { + margin: 40px 0 10px; +} + +h1 { + margin: 70px 0 30px; + padding-top: 20px; +} + +div.part h1 { + border-top: 1px dotted #CCCCCC; +} + +h1,h1 code { + font-size: 32px; +} + +h2,h2 code { + font-size: 24px; +} + +h3,h3 code { + font-size: 20px; +} + +h4,h1 code,h5,h5 code,h6,h6 code { + font-size: 18px; +} + +div.book,div.chapter,div.appendix,div.part,div.preface { + min-width: 300px; + max-width: 1200px; + margin: 0 auto; +} + +p.releaseinfo { + font-weight: bold; + margin-bottom: 40px; + margin-top: 40px; +} + +div.authorgroup { + line-height: 1; +} + +p.copyright { + line-height: 1; + margin-bottom: -5px; +} + +.legalnotice p { + font-style: italic; + font-size: 14px; + line-height: 1; +} + +div.titlepage+p,div.titlepage+p { + margin-top: 0; +} + +pre { + line-height: 1.0; + color: black; +} + +a { + color: #4183C4; + text-decoration: none; +} + +p { + margin: 15px 0; + text-align: left; +} + +ul,ol { + padding-left: 30px; +} + +li p { + margin: 0; +} + +div.table { + margin: 1em; + padding: 0.5em; + text-align: center; +} + +div.table table,div.informaltable table { + display: table; + width: 100%; +} + +div.table td { + padding-left: 7px; + padding-right: 7px; +} + +.sidebar { + line-height: 1.4; + padding: 0 20px; + background-color: #F8F8F8; + border: 1px solid #CCCCCC; + border-radius: 3px 3px 3px 3px; +} + +.sidebar p.title { + color: #6D180B; +} + +pre.programlisting,pre.screen { + font-size: 15px; + padding: 6px 10px; + background-color: #F8F8F8; + border: 1px solid #CCCCCC; + border-radius: 3px 3px 3px 3px; + clear: both; + overflow: auto; + line-height: 1.4; + font-family: Consolas, "Liberation Mono", Courier, monospace; +} + +table { + border-collapse: collapse; + border-spacing: 0; + border: 1px solid #DDDDDD !important; + border-radius: 4px !important; + border-collapse: separate !important; + line-height: 1.6; +} + +table thead { + background: #F5F5F5; +} + +table tr { + border: none; + border-bottom: none; +} + +table th { + font-weight: bold; +} + +table th,table td { + border: none !important; + padding: 6px 13px; +} + +table tr:nth-child(2n) { + background-color: #F8F8F8; +} + +td p { + margin: 0 0 15px 0; +} + +div.table-contents td p { + margin: 0; +} + +div.important *,div.note *,div.tip *,div.warning *,div.navheader *,div.navfooter *,div.calloutlist * + { + border: none !important; + background: none !important; + margin: 0; +} + +div.important p,div.note p,div.tip p,div.warning p { + color: #6F6F6F; + line-height: 1.6; +} + +div.important code,div.note code,div.tip code,div.warning code { + background-color: #F2F2F2 !important; + border: 1px solid #CCCCCC !important; + border-radius: 4px !important; + padding: 1px 3px 0 !important; + text-shadow: none !important; + white-space: nowrap !important; +} + +.note th,.tip th,.warning th { + display: none; +} + +.note tr:first-child td,.tip tr:first-child td,.warning tr:first-child td + { + border-right: 1px solid #CCCCCC !important; + padding-top: 10px; +} + +div.calloutlist p,div.calloutlist td { + padding: 0; + margin: 0; +} + +div.calloutlist>table>tbody>tr>td:first-child { + padding-left: 10px; + width: 30px !important; +} + +div.important,div.note,div.tip,div.warning { + margin-left: 0px !important; + margin-right: 20px !important; + margin-top: 20px; + margin-bottom: 20px; + padding-top: 10px; + padding-bottom: 10px; +} + +div.toc { + line-height: 1.2; +} + +dl,dt { + margin-top: 1px; + margin-bottom: 0; +} + +div.toc>dl>dt { + font-size: 32px; + font-weight: bold; + margin: 30px 0 10px 0; + display: block; +} + +div.toc>dl>dd>dl>dt { + font-size: 24px; + font-weight: bold; + margin: 20px 0 10px 0; + display: block; +} + +div.toc>dl>dd>dl>dd>dl>dt { + font-weight: bold; + font-size: 20px; + margin: 10px 0 0 0; +} + +tbody.footnotes * { + border: none !important; +} + +div.footnote p { + margin: 0; + line-height: 1; +} + +div.footnote p sup { + margin-right: 6px; + vertical-align: middle; +} + +div.navheader { + border-bottom: 1px solid #CCCCCC; +} + +div.navfooter { + border-top: 1px solid #CCCCCC; +} + +.title { + margin-left: -1em; + padding-left: 1em; +} + +.title>a { + position: absolute; + visibility: hidden; + display: block; + font-size: 0.85em; + margin-top: 0.05em; + margin-left: -1em; + vertical-align: text-top; + color: black; +} + +.title>a:before { + content: "\00A7"; +} + +.title:hover>a,.title>a:hover,.title:hover>a:hover { + visibility: visible; +} + +.title:focus>a,.title>a:focus,.title:focus>a:focus { + outline: 0; +} diff --git a/spring-cloud-security/1.2.2.RELEASE/ghpages.sh b/spring-cloud-security/1.2.2.RELEASE/ghpages.sh new file mode 100644 index 00000000..57c5da3a --- /dev/null +++ b/spring-cloud-security/1.2.2.RELEASE/ghpages.sh @@ -0,0 +1,330 @@ +#!/bin/bash -x + +set -e + +# Set default props like MAVEN_PATH, ROOT_FOLDER etc. +function set_default_props() { + # The script should be executed from the root folder + ROOT_FOLDER=`pwd` + echo "Current folder is ${ROOT_FOLDER}" + + if [[ ! -e "${ROOT_FOLDER}/.git" ]]; then + echo "You're not in the root folder of the project!" + exit 1 + fi + + # Prop that will let commit the changes + COMMIT_CHANGES="no" + MAVEN_PATH=${MAVEN_PATH:-} + echo "Path to Maven is [${MAVEN_PATH}]" + REPO_NAME=${PWD##*/} + echo "Repo name is [${REPO_NAME}]" + SPRING_CLOUD_STATIC_REPO=${SPRING_CLOUD_STATIC_REPO:-git@github.com:spring-cloud/spring-cloud-static.git} + echo "Spring Cloud Static repo is [${SPRING_CLOUD_STATIC_REPO}" +} + +# Check if gh-pages exists and docs have been built +function check_if_anything_to_sync() { + git remote set-url --push origin `git config remote.origin.url | sed -e 's/^git:/https:/'` + + if ! (git remote set-branches --add origin gh-pages && git fetch -q); then + echo "No gh-pages, so not syncing" + exit 0 + fi + + if ! [ -d docs/target/generated-docs ] && ! [ "${BUILD}" == "yes" ]; then + echo "No gh-pages sources in docs/target/generated-docs, so not syncing" + exit 0 + fi +} + +function retrieve_current_branch() { + # Code getting the name of the current branch. For master we want to publish as we did until now + # http://stackoverflow.com/questions/1593051/how-to-programmatically-determine-the-current-checked-out-git-branch + # If there is a branch already passed will reuse it - otherwise will try to find it + CURRENT_BRANCH=${BRANCH} + if [[ -z "${CURRENT_BRANCH}" ]] ; then + CURRENT_BRANCH=$(git symbolic-ref -q HEAD) + CURRENT_BRANCH=${CURRENT_BRANCH##refs/heads/} + CURRENT_BRANCH=${CURRENT_BRANCH:-HEAD} + fi + echo "Current branch is [${CURRENT_BRANCH}]" + git checkout ${CURRENT_BRANCH} || echo "Failed to check the branch... continuing with the script" +} + +# Switches to the provided value of the release version. We always prefix it with `v` +function switch_to_tag() { + git checkout v${VERSION} +} + +# Build the docs if switch is on +function build_docs_if_applicable() { + if [[ "${BUILD}" == "yes" ]] ; then + ./mvnw clean install -P docs -pl docs -DskipTests + fi +} + +# Get the name of the `docs.main` property +# Get whitelisted branches - assumes that a `docs` module is available under `docs` profile +function retrieve_doc_properties() { + MAIN_ADOC_VALUE=$("${MAVEN_PATH}"mvn -q \ + -Dexec.executable="echo" \ + -Dexec.args='${docs.main}' \ + --non-recursive \ + org.codehaus.mojo:exec-maven-plugin:1.3.1:exec) + echo "Extracted 'main.adoc' from Maven build [${MAIN_ADOC_VALUE}]" + + + WHITELIST_PROPERTY=${WHITELIST_PROPERTY:-"docs.whitelisted.branches"} + WHITELISTED_BRANCHES_VALUE=$("${MAVEN_PATH}"mvn -q \ + -Dexec.executable="echo" \ + -Dexec.args="\${${WHITELIST_PROPERTY}}" \ + org.codehaus.mojo:exec-maven-plugin:1.3.1:exec \ + -P docs \ + -pl docs) + echo "Extracted '${WHITELIST_PROPERTY}' from Maven build [${WHITELISTED_BRANCHES_VALUE}]" +} + +# Stash any outstanding changes +function stash_changes() { + git diff-index --quiet HEAD && dirty=$? || (echo "Failed to check if the current repo is dirty. Assuming that it is." && dirty="1") + if [ "$dirty" != "0" ]; then git stash; fi +} + +# Switch to gh-pages branch to sync it with current branch +function add_docs_from_target() { + local DESTINATION_REPO_FOLDER + if [[ -z "${DESTINATION}" && -z "${CLONE}" ]] ; then + DESTINATION_REPO_FOLDER=${ROOT_FOLDER} + elif [[ "${CLONE}" == "yes" ]]; then + mkdir -p ${ROOT_FOLDER}/target + local clonedStatic=${ROOT_FOLDER}/target/spring-cloud-static + if [[ ! -e "${clonedStatic}/.git" ]]; then + echo "Cloning Spring Cloud Static to target" + git clone ${SPRING_CLOUD_STATIC_REPO} ${clonedStatic} && git checkout gh-pages + else + echo "Spring Cloud Static already cloned - will pull changes" + cd ${clonedStatic} && git checkout gh-pages && git pull origin gh-pages + fi + DESTINATION_REPO_FOLDER=${clonedStatic}/${REPO_NAME} + mkdir -p ${DESTINATION_REPO_FOLDER} + else + if [[ ! -e "${DESTINATION}/.git" ]]; then + echo "[${DESTINATION}] is not a git repository" + exit 1 + fi + DESTINATION_REPO_FOLDER=${DESTINATION}/${REPO_NAME} + mkdir -p ${DESTINATION_REPO_FOLDER} + echo "Destination was provided [${DESTINATION}]" + fi + cd ${DESTINATION_REPO_FOLDER} + git checkout gh-pages + git pull origin gh-pages + + # Add git branches + ################################################################### + if [[ -z "${VERSION}" ]] ; then + copy_docs_for_current_version + else + copy_docs_for_provided_version + fi + commit_changes_if_applicable +} + + +# Copies the docs by using the retrieved properties from Maven build +function copy_docs_for_current_version() { + if [[ "${CURRENT_BRANCH}" == "master" ]] ; then + echo -e "Current branch is master - will copy the current docs only to the root folder" + for f in docs/target/generated-docs/*; do + file=${f#docs/target/generated-docs/*} + if ! git ls-files -i -o --exclude-standard --directory | grep -q ^$file$; then + # Not ignored... + cp -rf $f ${ROOT_FOLDER}/ + git add -A ${ROOT_FOLDER}/$file + fi + done + COMMIT_CHANGES="yes" + else + echo -e "Current branch is [${CURRENT_BRANCH}]" + # http://stackoverflow.com/questions/29300806/a-bash-script-to-check-if-a-string-is-present-in-a-comma-separated-list-of-strin + if [[ ",${WHITELISTED_BRANCHES_VALUE}," = *",${CURRENT_BRANCH},"* ]] ; then + mkdir -p ${ROOT_FOLDER}/${CURRENT_BRANCH} + echo -e "Branch [${CURRENT_BRANCH}] is whitelisted! Will copy the current docs to the [${CURRENT_BRANCH}] folder" + for f in docs/target/generated-docs/*; do + file=${f#docs/target/generated-docs/*} + if ! git ls-files -i -o --exclude-standard --directory | grep -q ^$file$; then + # Not ignored... + # We want users to access 1.0.0.RELEASE/ instead of 1.0.0.RELEASE/spring-cloud.sleuth.html + if [[ "${file}" == "${MAIN_ADOC_VALUE}.html" ]] ; then + # We don't want to copy the spring-cloud-sleuth.html + # we want it to be converted to index.html + cp -rf $f ${ROOT_FOLDER}/${CURRENT_BRANCH}/index.html + git add -A ${ROOT_FOLDER}/${CURRENT_BRANCH}/index.html + else + cp -rf $f ${ROOT_FOLDER}/${CURRENT_BRANCH} + git add -A ${ROOT_FOLDER}/${CURRENT_BRANCH}/$file + fi + fi + done + COMMIT_CHANGES="yes" + else + echo -e "Branch [${CURRENT_BRANCH}] is not on the white list! Check out the Maven [${WHITELIST_PROPERTY}] property in + [docs] module available under [docs] profile. Won't commit any changes to gh-pages for this branch." + fi + fi +} + +# Copies the docs by using the explicitly provided version +function copy_docs_for_provided_version() { + local FOLDER=${DESTINATION_REPO_FOLDER}/${VERSION} + mkdir -p ${FOLDER} + echo -e "Current tag is [v${VERSION}] Will copy the current docs to the [${FOLDER}] folder" + for f in ${ROOT_FOLDER}/docs/target/generated-docs/*; do + file=${f#${ROOT_FOLDER}/docs/target/generated-docs/*} + copy_docs_for_branch ${file} ${FOLDER} + done + COMMIT_CHANGES="yes" + CURRENT_BRANCH="v${VERSION}" +} + +# Copies the docs from target to the provided destination +# Params: +# $1 - file from target +# $2 - destination to which copy the files +function copy_docs_for_branch() { + local file=$1 + local destination=$2 + if ! git ls-files -i -o --exclude-standard --directory | grep -q ^${file}$; then + # Not ignored... + # We want users to access 1.0.0.RELEASE/ instead of 1.0.0.RELEASE/spring-cloud.sleuth.html + if [[ ("${file}" == "${MAIN_ADOC_VALUE}.html") || ("${file}" == "${REPO_NAME}.html") ]] ; then + # We don't want to copy the spring-cloud-sleuth.html + # we want it to be converted to index.html + cp -rf $f ${destination}/index.html + git add -A ${destination}/index.html + else + cp -rf $f ${destination} + git add -A ${destination}/$file + fi + fi +} + +function commit_changes_if_applicable() { + if [[ "${COMMIT_CHANGES}" == "yes" ]] ; then + COMMIT_SUCCESSFUL="no" + git commit -a -m "Sync docs from ${CURRENT_BRANCH} to gh-pages" && COMMIT_SUCCESSFUL="yes" || echo "Failed to commit changes" + + # Uncomment the following push if you want to auto push to + # the gh-pages branch whenever you commit to master locally. + # This is a little extreme. Use with care! + ################################################################### + if [[ "${COMMIT_SUCCESSFUL}" == "yes" ]] ; then + git push origin gh-pages + fi + fi +} + +# Switch back to the previous branch and exit block +function checkout_previous_branch() { + # If -version was provided we need to come back to root project + cd ${ROOT_FOLDER} + git checkout ${CURRENT_BRANCH} || echo "Failed to check the branch... continuing with the script" + if [ "$dirty" != "0" ]; then git stash pop; fi + exit 0 +} + +# Assert if properties have been properly passed +function assert_properties() { +echo "VERSION [${VERSION}], DESTINATION [${DESTINATION}], CLONE [${CLONE}]" +if [[ "${VERSION}" != "" && (-z "${DESTINATION}" && -z "${CLONE}") ]] ; then echo "Version was set but destination / clone was not!"; exit 1;fi +if [[ ("${DESTINATION}" != "" && "${CLONE}" != "") && -z "${VERSION}" ]] ; then echo "Destination / clone was set but version was not!"; exit 1;fi +if [[ "${DESTINATION}" != "" && "${CLONE}" == "yes" ]] ; then echo "Destination and clone was set. Pick one!"; exit 1;fi +} + +# Prints the usage +function print_usage() { +cat </` +- if the destination switch is passed (-d) then the script will check if the provided dir is a git repo and then will + switch to gh-pages of that repo and copy the generated docs to `docs//` + +USAGE: + +You can use the following options: + +-v|--version - the script will apply the whole procedure for a particular library version +-d|--destination - the root of destination folder where the docs should be copied. You have to use the full path. + E.g. point to spring-cloud-static folder. Can't be used with (-c) +-b|--build - will run the standard build process after checking out the branch +-c|--clone - will automatically clone the spring-cloud-static repo instead of providing the destination. + Obviously can't be used with (-d) + +EOF +} + + +# ========================================== +# ____ ____ _____ _____ _____ _______ +# / ____|/ ____| __ \|_ _| __ \__ __| +# | (___ | | | |__) | | | | |__) | | | +# \___ \| | | _ / | | | ___/ | | +# ____) | |____| | \ \ _| |_| | | | +# |_____/ \_____|_| \_\_____|_| |_| +# +# ========================================== + +while [[ $# > 0 ]] +do +key="$1" +case ${key} in + -v|--version) + VERSION="$2" + shift # past argument + ;; + -d|--destination) + DESTINATION="$2" + shift # past argument + ;; + -b|--build) + BUILD="yes" + ;; + -c|--clone) + CLONE="yes" + ;; + -h|--help) + print_usage + exit 0 + ;; + *) + echo "Invalid option: [$1]" + print_usage + exit 1 + ;; +esac +shift # past argument or value +done + +assert_properties +set_default_props +check_if_anything_to_sync +if [[ -z "${VERSION}" ]] ; then + retrieve_current_branch +else + switch_to_tag +fi +build_docs_if_applicable +retrieve_doc_properties +stash_changes +add_docs_from_target +checkout_previous_branch \ No newline at end of file diff --git a/spring-cloud-security/1.2.2.RELEASE/images/background.png b/spring-cloud-security/1.2.2.RELEASE/images/background.png new file mode 100644 index 00000000..15dca6fb Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/images/background.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/images/caution.png b/spring-cloud-security/1.2.2.RELEASE/images/caution.png new file mode 100644 index 00000000..8a5e4fca Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/images/caution.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/images/important.png b/spring-cloud-security/1.2.2.RELEASE/images/important.png new file mode 100644 index 00000000..ec54df65 Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/images/important.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/images/logo.png b/spring-cloud-security/1.2.2.RELEASE/images/logo.png new file mode 100644 index 00000000..ade2ce6e Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/images/logo.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/images/note.png b/spring-cloud-security/1.2.2.RELEASE/images/note.png new file mode 100644 index 00000000..88d997b1 Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/images/note.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/images/sts_exception.png b/spring-cloud-security/1.2.2.RELEASE/images/sts_exception.png new file mode 100644 index 00000000..8607c38a Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/images/sts_exception.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/images/tip.png b/spring-cloud-security/1.2.2.RELEASE/images/tip.png new file mode 100644 index 00000000..6530abb4 Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/images/tip.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/images/warning.png b/spring-cloud-security/1.2.2.RELEASE/images/warning.png new file mode 100644 index 00000000..0d5b5244 Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/images/warning.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/images/web-selected.png b/spring-cloud-security/1.2.2.RELEASE/images/web-selected.png new file mode 100644 index 00000000..aa6b2da6 Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/images/web-selected.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/index.html b/spring-cloud-security/1.2.2.RELEASE/index.html new file mode 100644 index 00000000..f586369c --- /dev/null +++ b/spring-cloud-security/1.2.2.RELEASE/index.html @@ -0,0 +1,117 @@ + + + + + + + +spring-cloud-security + + + + + + + + +
+
+
+
+

1.2.2.RELEASE

+
+
+
+
+

Pick The Documentation Option

+
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/spring-cloud-security/1.2.2.RELEASE/multi/css/highlight.css b/spring-cloud-security/1.2.2.RELEASE/multi/css/highlight.css new file mode 100644 index 00000000..ffefef72 --- /dev/null +++ b/spring-cloud-security/1.2.2.RELEASE/multi/css/highlight.css @@ -0,0 +1,35 @@ +/* + code highlight CSS resemblign the Eclipse IDE default color schema + @author Costin Leau +*/ + +.hl-keyword { + color: #7F0055; + font-weight: bold; +} + +.hl-comment { + color: #3F5F5F; + font-style: italic; +} + +.hl-multiline-comment { + color: #3F5FBF; + font-style: italic; +} + +.hl-tag { + color: #3F7F7F; +} + +.hl-attribute { + color: #7F007F; +} + +.hl-value { + color: #2A00FF; +} + +.hl-string { + color: #2A00FF; +} \ No newline at end of file diff --git a/spring-cloud-security/1.2.2.RELEASE/multi/css/manual-multipage.css b/spring-cloud-security/1.2.2.RELEASE/multi/css/manual-multipage.css new file mode 100644 index 00000000..0c484531 --- /dev/null +++ b/spring-cloud-security/1.2.2.RELEASE/multi/css/manual-multipage.css @@ -0,0 +1,9 @@ +@IMPORT url("manual.css"); + +body.firstpage { + background: url("../images/background.png") no-repeat center top; +} + +div.part h1 { + border-top: none; +} diff --git a/spring-cloud-security/1.2.2.RELEASE/multi/css/manual-singlepage.css b/spring-cloud-security/1.2.2.RELEASE/multi/css/manual-singlepage.css new file mode 100644 index 00000000..4a7fd140 --- /dev/null +++ b/spring-cloud-security/1.2.2.RELEASE/multi/css/manual-singlepage.css @@ -0,0 +1,6 @@ +@IMPORT url("manual.css"); + +body { + background: url("../images/background.png") no-repeat center top; +} + diff --git a/spring-cloud-security/1.2.2.RELEASE/multi/css/manual.css b/spring-cloud-security/1.2.2.RELEASE/multi/css/manual.css new file mode 100644 index 00000000..0ecbe2e8 --- /dev/null +++ b/spring-cloud-security/1.2.2.RELEASE/multi/css/manual.css @@ -0,0 +1,344 @@ +@IMPORT url("highlight.css"); + +html { + padding: 0pt; + margin: 0pt; +} + +body { + color: #333333; + margin: 15px 30px; + font-family: Helvetica, Arial, Freesans, Clean, Sans-serif; + line-height: 1.6; + -webkit-font-smoothing: antialiased; +} + +code { + font-size: 16px; + font-family: Consolas, "Liberation Mono", Courier, monospace; +} + +:not(a)>code { + color: #6D180B; +} + +:not(pre)>code { + background-color: #F2F2F2; + border: 1px solid #CCCCCC; + border-radius: 4px; + padding: 1px 3px 0; + text-shadow: none; + white-space: nowrap; +} + +body>*:first-child { + margin-top: 0 !important; +} + +div { + margin: 0pt; +} + +hr { + border: 1px solid #CCCCCC; + background: #CCCCCC; +} + +h1,h2,h3,h4,h5,h6 { + color: #000000; + cursor: text; + font-weight: bold; + margin: 30px 0 10px; + padding: 0; +} + +h1,h2,h3 { + margin: 40px 0 10px; +} + +h1 { + margin: 70px 0 30px; + padding-top: 20px; +} + +div.part h1 { + border-top: 1px dotted #CCCCCC; +} + +h1,h1 code { + font-size: 32px; +} + +h2,h2 code { + font-size: 24px; +} + +h3,h3 code { + font-size: 20px; +} + +h4,h1 code,h5,h5 code,h6,h6 code { + font-size: 18px; +} + +div.book,div.chapter,div.appendix,div.part,div.preface { + min-width: 300px; + max-width: 1200px; + margin: 0 auto; +} + +p.releaseinfo { + font-weight: bold; + margin-bottom: 40px; + margin-top: 40px; +} + +div.authorgroup { + line-height: 1; +} + +p.copyright { + line-height: 1; + margin-bottom: -5px; +} + +.legalnotice p { + font-style: italic; + font-size: 14px; + line-height: 1; +} + +div.titlepage+p,div.titlepage+p { + margin-top: 0; +} + +pre { + line-height: 1.0; + color: black; +} + +a { + color: #4183C4; + text-decoration: none; +} + +p { + margin: 15px 0; + text-align: left; +} + +ul,ol { + padding-left: 30px; +} + +li p { + margin: 0; +} + +div.table { + margin: 1em; + padding: 0.5em; + text-align: center; +} + +div.table table,div.informaltable table { + display: table; + width: 100%; +} + +div.table td { + padding-left: 7px; + padding-right: 7px; +} + +.sidebar { + line-height: 1.4; + padding: 0 20px; + background-color: #F8F8F8; + border: 1px solid #CCCCCC; + border-radius: 3px 3px 3px 3px; +} + +.sidebar p.title { + color: #6D180B; +} + +pre.programlisting,pre.screen { + font-size: 15px; + padding: 6px 10px; + background-color: #F8F8F8; + border: 1px solid #CCCCCC; + border-radius: 3px 3px 3px 3px; + clear: both; + overflow: auto; + line-height: 1.4; + font-family: Consolas, "Liberation Mono", Courier, monospace; +} + +table { + border-collapse: collapse; + border-spacing: 0; + border: 1px solid #DDDDDD !important; + border-radius: 4px !important; + border-collapse: separate !important; + line-height: 1.6; +} + +table thead { + background: #F5F5F5; +} + +table tr { + border: none; + border-bottom: none; +} + +table th { + font-weight: bold; +} + +table th,table td { + border: none !important; + padding: 6px 13px; +} + +table tr:nth-child(2n) { + background-color: #F8F8F8; +} + +td p { + margin: 0 0 15px 0; +} + +div.table-contents td p { + margin: 0; +} + +div.important *,div.note *,div.tip *,div.warning *,div.navheader *,div.navfooter *,div.calloutlist * + { + border: none !important; + background: none !important; + margin: 0; +} + +div.important p,div.note p,div.tip p,div.warning p { + color: #6F6F6F; + line-height: 1.6; +} + +div.important code,div.note code,div.tip code,div.warning code { + background-color: #F2F2F2 !important; + border: 1px solid #CCCCCC !important; + border-radius: 4px !important; + padding: 1px 3px 0 !important; + text-shadow: none !important; + white-space: nowrap !important; +} + +.note th,.tip th,.warning th { + display: none; +} + +.note tr:first-child td,.tip tr:first-child td,.warning tr:first-child td + { + border-right: 1px solid #CCCCCC !important; + padding-top: 10px; +} + +div.calloutlist p,div.calloutlist td { + padding: 0; + margin: 0; +} + +div.calloutlist>table>tbody>tr>td:first-child { + padding-left: 10px; + width: 30px !important; +} + +div.important,div.note,div.tip,div.warning { + margin-left: 0px !important; + margin-right: 20px !important; + margin-top: 20px; + margin-bottom: 20px; + padding-top: 10px; + padding-bottom: 10px; +} + +div.toc { + line-height: 1.2; +} + +dl,dt { + margin-top: 1px; + margin-bottom: 0; +} + +div.toc>dl>dt { + font-size: 32px; + font-weight: bold; + margin: 30px 0 10px 0; + display: block; +} + +div.toc>dl>dd>dl>dt { + font-size: 24px; + font-weight: bold; + margin: 20px 0 10px 0; + display: block; +} + +div.toc>dl>dd>dl>dd>dl>dt { + font-weight: bold; + font-size: 20px; + margin: 10px 0 0 0; +} + +tbody.footnotes * { + border: none !important; +} + +div.footnote p { + margin: 0; + line-height: 1; +} + +div.footnote p sup { + margin-right: 6px; + vertical-align: middle; +} + +div.navheader { + border-bottom: 1px solid #CCCCCC; +} + +div.navfooter { + border-top: 1px solid #CCCCCC; +} + +.title { + margin-left: -1em; + padding-left: 1em; +} + +.title>a { + position: absolute; + visibility: hidden; + display: block; + font-size: 0.85em; + margin-top: 0.05em; + margin-left: -1em; + vertical-align: text-top; + color: black; +} + +.title>a:before { + content: "\00A7"; +} + +.title:hover>a,.title>a:hover,.title:hover>a:hover { + visibility: visible; +} + +.title:focus>a,.title>a:focus,.title:focus>a:focus { + outline: 0; +} diff --git a/spring-cloud-security/1.2.2.RELEASE/multi/images/background.png b/spring-cloud-security/1.2.2.RELEASE/multi/images/background.png new file mode 100644 index 00000000..15dca6fb Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/multi/images/background.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/multi/images/caution.png b/spring-cloud-security/1.2.2.RELEASE/multi/images/caution.png new file mode 100644 index 00000000..8a5e4fca Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/multi/images/caution.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/multi/images/important.png b/spring-cloud-security/1.2.2.RELEASE/multi/images/important.png new file mode 100644 index 00000000..ec54df65 Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/multi/images/important.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/multi/images/logo.png b/spring-cloud-security/1.2.2.RELEASE/multi/images/logo.png new file mode 100644 index 00000000..ade2ce6e Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/multi/images/logo.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/multi/images/note.png b/spring-cloud-security/1.2.2.RELEASE/multi/images/note.png new file mode 100644 index 00000000..88d997b1 Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/multi/images/note.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/multi/images/sts_exception.png b/spring-cloud-security/1.2.2.RELEASE/multi/images/sts_exception.png new file mode 100644 index 00000000..8607c38a Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/multi/images/sts_exception.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/multi/images/tip.png b/spring-cloud-security/1.2.2.RELEASE/multi/images/tip.png new file mode 100644 index 00000000..6530abb4 Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/multi/images/tip.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/multi/images/warning.png b/spring-cloud-security/1.2.2.RELEASE/multi/images/warning.png new file mode 100644 index 00000000..0d5b5244 Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/multi/images/warning.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/multi/images/web-selected.png b/spring-cloud-security/1.2.2.RELEASE/multi/images/web-selected.png new file mode 100644 index 00000000..aa6b2da6 Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/multi/images/web-selected.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/multi/multi__configuring_authentication_downstream_of_a_zuul_proxy.html b/spring-cloud-security/1.2.2.RELEASE/multi/multi__configuring_authentication_downstream_of_a_zuul_proxy.html new file mode 100644 index 00000000..9cf2512a --- /dev/null +++ b/spring-cloud-security/1.2.2.RELEASE/multi/multi__configuring_authentication_downstream_of_a_zuul_proxy.html @@ -0,0 +1,17 @@ + + + 3. Configuring Authentication Downstream of a Zuul Proxy

3. Configuring Authentication Downstream of a Zuul Proxy

You can control the authorization behaviour downstream of an +@EnableZuulProxy through the proxy.auth.* settings. Example:

application.yml.  +

proxy:
+  auth:
+    routes:
+      customers: oauth2
+      stores: passthru
+      recommendations: none

+

In this example the "customers" service gets an OAuth2 token relay, +the "stores" service gets a passthrough (the authorization header is +just passed downstream), and the "recommendations" service has its +authorization header removed. The default behaviour is to do a token +relay if there is a token available, and passthru otherwise.

See + +ProxyAuthenticationProperties for full details.

\ No newline at end of file diff --git a/spring-cloud-security/1.2.2.RELEASE/multi/multi__more_detail.html b/spring-cloud-security/1.2.2.RELEASE/multi/multi__more_detail.html new file mode 100644 index 00000000..ca9f32c2 --- /dev/null +++ b/spring-cloud-security/1.2.2.RELEASE/multi/multi__more_detail.html @@ -0,0 +1,84 @@ + + + 2. More Detail

2. More Detail

2.1 Single Sign On

[Note]Note

All of the OAuth2 SSO and resource server features moved to Spring Boot +in version 1.3. You can find documentation in the +Spring Boot user guide.

2.2 Token Relay

A Token Relay is where an OAuth2 consumer acts as a Client and +forwards the incoming token to outgoing resource requests. The +consumer can be a pure Client (like an SSO application) or a Resource +Server.

2.2.1 Client Token Relay

If your app is a user facing OAuth2 client (i.e. has declared +@EnableOAuth2Sso or @EnableOAuth2Client) then it has an +OAuth2ClientContext in request scope from Spring Boot. You can +create your own OAuth2RestTemplate from this context and an +autowired OAuth2ProtectedResourceDetails, and then the context will +always forward the access token downstream, also refreshing the access +token automatically if it expires. (These are features of Spring +Security and Spring Boot.)

[Note]Note

Spring Boot (1.4.1) does not create an +OAuth2ProtectedResourceDetails automatically if you are using +client_credentials tokens. In that case you need to create your own +ClientCredentialsResourceDetails and configure it with +@ConfigurationProperties("security.oauth2.client").

2.2.2 Client Token Relay in Zuul Proxy

If your app also has a +Spring +Cloud Zuul embedded reverse proxy (using @EnableZuulProxy) then you +can ask it to forward OAuth2 access tokens downstream to the services +it is proxying. Thus the SSO app above can be enhanced simply like +this:

app.groovy.  +

@Controller
+@EnableOAuth2Sso
+@EnableZuulProxy
+class Application {
+
+}

+

and it will (in addition to logging the user in and grabbing a token) +pass the authentication token downstream to the /proxy/* +services. If those services are implemented with +@EnableResourceServer then they will get a valid token in the +correct header.

How does it work? The @EnableOAuth2Sso annotation pulls in +spring-cloud-starter-security (which you could do manually in a +traditional app), and that in turn triggers some autoconfiguration for +a ZuulFilter, which itself is activated because Zuul is on the +classpath (via @EnableZuulProxy). The +filter +just extracts an access token from the currently authenticated user, +and puts it in a request header for the downstream requests.

2.2.3 Resource Server Token Relay

If your app has @EnableResourceServer you might want to relay the +incoming token downstream to other services. If you use a +RestTemplate to contact the downstream services then this is just a +matter of how to create the template with the right context.

If your service uses UserInfoTokenServices to authenticate incoming +tokens (i.e. it is using the security.oauth2.user-info-uri +configuration), then you can simply create an OAuth2RestTemplate +using an autowired OAuth2ClientContext (it will be populated by the +authentication process before it hits the backend code). Equivalently +(with Spring Boot 1.4), you could inject a +UserInfoRestTemplateFactory and grab its OAuth2RestTemplate in +your configuration. For example:

MyConfiguration.java.  +

@Bean
+public OAuth2RestTemplate restTemplate(UserInfoRestTemplateFactory factory) {
+    return factory.getUserInfoRestTemplate();
+}

+

This rest template will then have the same OAuth2ClientContext +(request-scoped) that is used by the authentication filter, so you can +use it to send requests with the same access token.

If your app is not using UserInfoTokenServices but is still a client +(i.e. it declares @EnableOAuth2Client or @EnableOAuth2Sso), then +with Spring Security Cloud any OAuth2RestOperations that the user +creates from an @Autowired @OAuth2Context will also forward +tokens. This feature is implemented by default as an MVC handler +interceptor, so it only works in Spring MVC. If you are not using MVC +you could use a custom filter or AOP interceptor wrapping an +AccessTokenContextRelay to provide the same feature.

Here’s a basic +example showing the use of an autowired rest template created +elsewhere ("foo.com" is a Resource Server accepting the same tokens as +the surrounding app):

MyController.java.  +

@Autowired
+private OAuth2RestOperations restTemplate;
+
+@RequestMapping("/relay")
+public String relay() {
+    ResponseEntity<String> response =
+      restTemplate.getForEntity("https://foo.com/bar", String.class);
+    return "Success! (" + response.getBody() + ")";
+}

+

If you don’t want to forward tokens (and that is a valid +choice, since you might want to act as yourself, rather than the +client that sent you the token), then you only need to create your own +OAuth2Context instead of autowiring the default one.

Feign clients will also pick up an interceptor that uses the +OAuth2ClientContext if it is available, so they should also do a +token relay anywhere where a RestTemplate would.

\ No newline at end of file diff --git a/spring-cloud-security/1.2.2.RELEASE/multi/multi__quickstart.html b/spring-cloud-security/1.2.2.RELEASE/multi/multi__quickstart.html new file mode 100644 index 00000000..e3a60b59 --- /dev/null +++ b/spring-cloud-security/1.2.2.RELEASE/multi/multi__quickstart.html @@ -0,0 +1,72 @@ + + + 1. Quickstart

1. Quickstart

1.1 OAuth2 Single Sign On

Here’s a Spring Cloud "Hello World" app with HTTP Basic +authentication and a single user account:

app.groovy.  +

@Grab('spring-boot-starter-security')
+@Controller
+class Application {
+
+  @RequestMapping('/')
+  String home() {
+    'Hello World'
+  }
+
+}

+

You can run it with spring run app.groovy and watch the logs for the password (username is "user"). So far this is just the default for a Spring Boot app.

Here’s a Spring Cloud app with OAuth2 SSO:

app.groovy.  +

@Controller
+@EnableOAuth2Sso
+class Application {
+
+  @RequestMapping('/')
+  String home() {
+    'Hello World'
+  }
+
+}

+

Spot the difference? This app will actually behave exactly the same as +the previous one, because it doesn’t know it’s OAuth2 credentals +yet.

You can register an app in github quite easily, so try that if you +want a production app on your own domain. If you are happy to test on +localhost:8080, then set up these properties in your application +configuration:

application.yml.  +

security:
+  oauth2:
+    client:
+      clientId: bd1c0a783ccdd1c9b9e4
+      clientSecret: 1a9030fbca47a5b2c28e92f19050bb77824b5ad1
+      accessTokenUri: https://github.com/login/oauth/access_token
+      userAuthorizationUri: https://github.com/login/oauth/authorize
+      clientAuthenticationScheme: form
+    resource:
+      userInfoUri: https://api.github.com/user
+      preferTokenInfo: false

+

run the app above and it will redirect to github for authorization. If +you are already signed into github you won’t even notice that it has +authenticated. These credentials will only work if your app is +running on port 8080.

To limit the scope that the client asks for when it obtains an access token +you can set security.oauth2.client.scope (comma separated or an array in YAML). By +default the scope is empty and it is up to to Authorization Server to +decide what the defaults should be, usually depending on the settings in +the client registration that it holds.

[Note]Note

The examples above are all Groovy scripts. If you want to write the +same code in Java (or Groovy) you need to add Spring Security OAuth2 +to the classpath (e.g. see the +sample here).

1.2 OAuth2 Protected Resource

You want to protect an API resource with an OAuth2 token? Here’s a +simple example (paired with the client above):

app.groovy.  +

@Grab('spring-cloud-starter-security')
+@RestController
+@EnableResourceServer
+class Application {
+
+  @RequestMapping('/')
+  def home() {
+    [message: 'Hello World']
+  }
+
+}

+

and

application.yml.  +

security:
+  oauth2:
+    resource:
+      userInfoUri: https://api.github.com/user
+      preferTokenInfo: false

+

\ No newline at end of file diff --git a/spring-cloud-security/1.2.2.RELEASE/multi/multi_pr01.html b/spring-cloud-security/1.2.2.RELEASE/multi/multi_pr01.html new file mode 100644 index 00000000..868ebaeb --- /dev/null +++ b/spring-cloud-security/1.2.2.RELEASE/multi/multi_pr01.html @@ -0,0 +1,11 @@ + + +

Spring Cloud Security offers a set of primitives for building secure +applications and services with minimum fuss. A declarative model which +can be heavily configured externally (or centrally) lends itself to +the implementation of large systems of co-operating, remote components, +usually with a central indentity management service. It is also extremely +easy to use in a service platform like Cloud Foundry. Building on +Spring Boot and Spring Security OAuth2 we can quickly create systems that +implement common patterns like single sign on, token relay and token +exchange.

[Note]Note

Spring Cloud is released under the non-restrictive Apache 2.0 license. If you would like to contribute to this section of the documentation or if you find an error, please find the source code and issue trackers in the project at github.

\ No newline at end of file diff --git a/spring-cloud-security/1.2.2.RELEASE/multi/multi_spring-cloud-security.html b/spring-cloud-security/1.2.2.RELEASE/multi/multi_spring-cloud-security.html new file mode 100644 index 00000000..25b549e9 --- /dev/null +++ b/spring-cloud-security/1.2.2.RELEASE/multi/multi_spring-cloud-security.html @@ -0,0 +1,3 @@ + + + Spring Cloud Security \ No newline at end of file diff --git a/spring-cloud-security/1.2.2.RELEASE/single/css/highlight.css b/spring-cloud-security/1.2.2.RELEASE/single/css/highlight.css new file mode 100644 index 00000000..ffefef72 --- /dev/null +++ b/spring-cloud-security/1.2.2.RELEASE/single/css/highlight.css @@ -0,0 +1,35 @@ +/* + code highlight CSS resemblign the Eclipse IDE default color schema + @author Costin Leau +*/ + +.hl-keyword { + color: #7F0055; + font-weight: bold; +} + +.hl-comment { + color: #3F5F5F; + font-style: italic; +} + +.hl-multiline-comment { + color: #3F5FBF; + font-style: italic; +} + +.hl-tag { + color: #3F7F7F; +} + +.hl-attribute { + color: #7F007F; +} + +.hl-value { + color: #2A00FF; +} + +.hl-string { + color: #2A00FF; +} \ No newline at end of file diff --git a/spring-cloud-security/1.2.2.RELEASE/single/css/manual-multipage.css b/spring-cloud-security/1.2.2.RELEASE/single/css/manual-multipage.css new file mode 100644 index 00000000..0c484531 --- /dev/null +++ b/spring-cloud-security/1.2.2.RELEASE/single/css/manual-multipage.css @@ -0,0 +1,9 @@ +@IMPORT url("manual.css"); + +body.firstpage { + background: url("../images/background.png") no-repeat center top; +} + +div.part h1 { + border-top: none; +} diff --git a/spring-cloud-security/1.2.2.RELEASE/single/css/manual-singlepage.css b/spring-cloud-security/1.2.2.RELEASE/single/css/manual-singlepage.css new file mode 100644 index 00000000..4a7fd140 --- /dev/null +++ b/spring-cloud-security/1.2.2.RELEASE/single/css/manual-singlepage.css @@ -0,0 +1,6 @@ +@IMPORT url("manual.css"); + +body { + background: url("../images/background.png") no-repeat center top; +} + diff --git a/spring-cloud-security/1.2.2.RELEASE/single/css/manual.css b/spring-cloud-security/1.2.2.RELEASE/single/css/manual.css new file mode 100644 index 00000000..0ecbe2e8 --- /dev/null +++ b/spring-cloud-security/1.2.2.RELEASE/single/css/manual.css @@ -0,0 +1,344 @@ +@IMPORT url("highlight.css"); + +html { + padding: 0pt; + margin: 0pt; +} + +body { + color: #333333; + margin: 15px 30px; + font-family: Helvetica, Arial, Freesans, Clean, Sans-serif; + line-height: 1.6; + -webkit-font-smoothing: antialiased; +} + +code { + font-size: 16px; + font-family: Consolas, "Liberation Mono", Courier, monospace; +} + +:not(a)>code { + color: #6D180B; +} + +:not(pre)>code { + background-color: #F2F2F2; + border: 1px solid #CCCCCC; + border-radius: 4px; + padding: 1px 3px 0; + text-shadow: none; + white-space: nowrap; +} + +body>*:first-child { + margin-top: 0 !important; +} + +div { + margin: 0pt; +} + +hr { + border: 1px solid #CCCCCC; + background: #CCCCCC; +} + +h1,h2,h3,h4,h5,h6 { + color: #000000; + cursor: text; + font-weight: bold; + margin: 30px 0 10px; + padding: 0; +} + +h1,h2,h3 { + margin: 40px 0 10px; +} + +h1 { + margin: 70px 0 30px; + padding-top: 20px; +} + +div.part h1 { + border-top: 1px dotted #CCCCCC; +} + +h1,h1 code { + font-size: 32px; +} + +h2,h2 code { + font-size: 24px; +} + +h3,h3 code { + font-size: 20px; +} + +h4,h1 code,h5,h5 code,h6,h6 code { + font-size: 18px; +} + +div.book,div.chapter,div.appendix,div.part,div.preface { + min-width: 300px; + max-width: 1200px; + margin: 0 auto; +} + +p.releaseinfo { + font-weight: bold; + margin-bottom: 40px; + margin-top: 40px; +} + +div.authorgroup { + line-height: 1; +} + +p.copyright { + line-height: 1; + margin-bottom: -5px; +} + +.legalnotice p { + font-style: italic; + font-size: 14px; + line-height: 1; +} + +div.titlepage+p,div.titlepage+p { + margin-top: 0; +} + +pre { + line-height: 1.0; + color: black; +} + +a { + color: #4183C4; + text-decoration: none; +} + +p { + margin: 15px 0; + text-align: left; +} + +ul,ol { + padding-left: 30px; +} + +li p { + margin: 0; +} + +div.table { + margin: 1em; + padding: 0.5em; + text-align: center; +} + +div.table table,div.informaltable table { + display: table; + width: 100%; +} + +div.table td { + padding-left: 7px; + padding-right: 7px; +} + +.sidebar { + line-height: 1.4; + padding: 0 20px; + background-color: #F8F8F8; + border: 1px solid #CCCCCC; + border-radius: 3px 3px 3px 3px; +} + +.sidebar p.title { + color: #6D180B; +} + +pre.programlisting,pre.screen { + font-size: 15px; + padding: 6px 10px; + background-color: #F8F8F8; + border: 1px solid #CCCCCC; + border-radius: 3px 3px 3px 3px; + clear: both; + overflow: auto; + line-height: 1.4; + font-family: Consolas, "Liberation Mono", Courier, monospace; +} + +table { + border-collapse: collapse; + border-spacing: 0; + border: 1px solid #DDDDDD !important; + border-radius: 4px !important; + border-collapse: separate !important; + line-height: 1.6; +} + +table thead { + background: #F5F5F5; +} + +table tr { + border: none; + border-bottom: none; +} + +table th { + font-weight: bold; +} + +table th,table td { + border: none !important; + padding: 6px 13px; +} + +table tr:nth-child(2n) { + background-color: #F8F8F8; +} + +td p { + margin: 0 0 15px 0; +} + +div.table-contents td p { + margin: 0; +} + +div.important *,div.note *,div.tip *,div.warning *,div.navheader *,div.navfooter *,div.calloutlist * + { + border: none !important; + background: none !important; + margin: 0; +} + +div.important p,div.note p,div.tip p,div.warning p { + color: #6F6F6F; + line-height: 1.6; +} + +div.important code,div.note code,div.tip code,div.warning code { + background-color: #F2F2F2 !important; + border: 1px solid #CCCCCC !important; + border-radius: 4px !important; + padding: 1px 3px 0 !important; + text-shadow: none !important; + white-space: nowrap !important; +} + +.note th,.tip th,.warning th { + display: none; +} + +.note tr:first-child td,.tip tr:first-child td,.warning tr:first-child td + { + border-right: 1px solid #CCCCCC !important; + padding-top: 10px; +} + +div.calloutlist p,div.calloutlist td { + padding: 0; + margin: 0; +} + +div.calloutlist>table>tbody>tr>td:first-child { + padding-left: 10px; + width: 30px !important; +} + +div.important,div.note,div.tip,div.warning { + margin-left: 0px !important; + margin-right: 20px !important; + margin-top: 20px; + margin-bottom: 20px; + padding-top: 10px; + padding-bottom: 10px; +} + +div.toc { + line-height: 1.2; +} + +dl,dt { + margin-top: 1px; + margin-bottom: 0; +} + +div.toc>dl>dt { + font-size: 32px; + font-weight: bold; + margin: 30px 0 10px 0; + display: block; +} + +div.toc>dl>dd>dl>dt { + font-size: 24px; + font-weight: bold; + margin: 20px 0 10px 0; + display: block; +} + +div.toc>dl>dd>dl>dd>dl>dt { + font-weight: bold; + font-size: 20px; + margin: 10px 0 0 0; +} + +tbody.footnotes * { + border: none !important; +} + +div.footnote p { + margin: 0; + line-height: 1; +} + +div.footnote p sup { + margin-right: 6px; + vertical-align: middle; +} + +div.navheader { + border-bottom: 1px solid #CCCCCC; +} + +div.navfooter { + border-top: 1px solid #CCCCCC; +} + +.title { + margin-left: -1em; + padding-left: 1em; +} + +.title>a { + position: absolute; + visibility: hidden; + display: block; + font-size: 0.85em; + margin-top: 0.05em; + margin-left: -1em; + vertical-align: text-top; + color: black; +} + +.title>a:before { + content: "\00A7"; +} + +.title:hover>a,.title>a:hover,.title:hover>a:hover { + visibility: visible; +} + +.title:focus>a,.title>a:focus,.title:focus>a:focus { + outline: 0; +} diff --git a/spring-cloud-security/1.2.2.RELEASE/single/images/background.png b/spring-cloud-security/1.2.2.RELEASE/single/images/background.png new file mode 100644 index 00000000..15dca6fb Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/single/images/background.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/single/images/caution.png b/spring-cloud-security/1.2.2.RELEASE/single/images/caution.png new file mode 100644 index 00000000..8a5e4fca Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/single/images/caution.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/single/images/important.png b/spring-cloud-security/1.2.2.RELEASE/single/images/important.png new file mode 100644 index 00000000..ec54df65 Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/single/images/important.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/single/images/logo.png b/spring-cloud-security/1.2.2.RELEASE/single/images/logo.png new file mode 100644 index 00000000..ade2ce6e Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/single/images/logo.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/single/images/note.png b/spring-cloud-security/1.2.2.RELEASE/single/images/note.png new file mode 100644 index 00000000..88d997b1 Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/single/images/note.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/single/images/sts_exception.png b/spring-cloud-security/1.2.2.RELEASE/single/images/sts_exception.png new file mode 100644 index 00000000..8607c38a Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/single/images/sts_exception.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/single/images/tip.png b/spring-cloud-security/1.2.2.RELEASE/single/images/tip.png new file mode 100644 index 00000000..6530abb4 Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/single/images/tip.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/single/images/warning.png b/spring-cloud-security/1.2.2.RELEASE/single/images/warning.png new file mode 100644 index 00000000..0d5b5244 Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/single/images/warning.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/single/images/web-selected.png b/spring-cloud-security/1.2.2.RELEASE/single/images/web-selected.png new file mode 100644 index 00000000..aa6b2da6 Binary files /dev/null and b/spring-cloud-security/1.2.2.RELEASE/single/images/web-selected.png differ diff --git a/spring-cloud-security/1.2.2.RELEASE/single/spring-cloud-security.html b/spring-cloud-security/1.2.2.RELEASE/single/spring-cloud-security.html new file mode 100644 index 00000000..0362a6bf --- /dev/null +++ b/spring-cloud-security/1.2.2.RELEASE/single/spring-cloud-security.html @@ -0,0 +1,175 @@ + + + Spring Cloud Security

Spring Cloud Security


Spring Cloud Security offers a set of primitives for building secure +applications and services with minimum fuss. A declarative model which +can be heavily configured externally (or centrally) lends itself to +the implementation of large systems of co-operating, remote components, +usually with a central indentity management service. It is also extremely +easy to use in a service platform like Cloud Foundry. Building on +Spring Boot and Spring Security OAuth2 we can quickly create systems that +implement common patterns like single sign on, token relay and token +exchange.

[Note]Note

Spring Cloud is released under the non-restrictive Apache 2.0 license. If you would like to contribute to this section of the documentation or if you find an error, please find the source code and issue trackers in the project at github.

1. Quickstart

1.1 OAuth2 Single Sign On

Here’s a Spring Cloud "Hello World" app with HTTP Basic +authentication and a single user account:

app.groovy.  +

@Grab('spring-boot-starter-security')
+@Controller
+class Application {
+
+  @RequestMapping('/')
+  String home() {
+    'Hello World'
+  }
+
+}

+

You can run it with spring run app.groovy and watch the logs for the password (username is "user"). So far this is just the default for a Spring Boot app.

Here’s a Spring Cloud app with OAuth2 SSO:

app.groovy.  +

@Controller
+@EnableOAuth2Sso
+class Application {
+
+  @RequestMapping('/')
+  String home() {
+    'Hello World'
+  }
+
+}

+

Spot the difference? This app will actually behave exactly the same as +the previous one, because it doesn’t know it’s OAuth2 credentals +yet.

You can register an app in github quite easily, so try that if you +want a production app on your own domain. If you are happy to test on +localhost:8080, then set up these properties in your application +configuration:

application.yml.  +

security:
+  oauth2:
+    client:
+      clientId: bd1c0a783ccdd1c9b9e4
+      clientSecret: 1a9030fbca47a5b2c28e92f19050bb77824b5ad1
+      accessTokenUri: https://github.com/login/oauth/access_token
+      userAuthorizationUri: https://github.com/login/oauth/authorize
+      clientAuthenticationScheme: form
+    resource:
+      userInfoUri: https://api.github.com/user
+      preferTokenInfo: false

+

run the app above and it will redirect to github for authorization. If +you are already signed into github you won’t even notice that it has +authenticated. These credentials will only work if your app is +running on port 8080.

To limit the scope that the client asks for when it obtains an access token +you can set security.oauth2.client.scope (comma separated or an array in YAML). By +default the scope is empty and it is up to to Authorization Server to +decide what the defaults should be, usually depending on the settings in +the client registration that it holds.

[Note]Note

The examples above are all Groovy scripts. If you want to write the +same code in Java (or Groovy) you need to add Spring Security OAuth2 +to the classpath (e.g. see the +sample here).

1.2 OAuth2 Protected Resource

You want to protect an API resource with an OAuth2 token? Here’s a +simple example (paired with the client above):

app.groovy.  +

@Grab('spring-cloud-starter-security')
+@RestController
+@EnableResourceServer
+class Application {
+
+  @RequestMapping('/')
+  def home() {
+    [message: 'Hello World']
+  }
+
+}

+

and

application.yml.  +

security:
+  oauth2:
+    resource:
+      userInfoUri: https://api.github.com/user
+      preferTokenInfo: false

+

2. More Detail

2.1 Single Sign On

[Note]Note

All of the OAuth2 SSO and resource server features moved to Spring Boot +in version 1.3. You can find documentation in the +Spring Boot user guide.

2.2 Token Relay

A Token Relay is where an OAuth2 consumer acts as a Client and +forwards the incoming token to outgoing resource requests. The +consumer can be a pure Client (like an SSO application) or a Resource +Server.

2.2.1 Client Token Relay

If your app is a user facing OAuth2 client (i.e. has declared +@EnableOAuth2Sso or @EnableOAuth2Client) then it has an +OAuth2ClientContext in request scope from Spring Boot. You can +create your own OAuth2RestTemplate from this context and an +autowired OAuth2ProtectedResourceDetails, and then the context will +always forward the access token downstream, also refreshing the access +token automatically if it expires. (These are features of Spring +Security and Spring Boot.)

[Note]Note

Spring Boot (1.4.1) does not create an +OAuth2ProtectedResourceDetails automatically if you are using +client_credentials tokens. In that case you need to create your own +ClientCredentialsResourceDetails and configure it with +@ConfigurationProperties("security.oauth2.client").

2.2.2 Client Token Relay in Zuul Proxy

If your app also has a +Spring +Cloud Zuul embedded reverse proxy (using @EnableZuulProxy) then you +can ask it to forward OAuth2 access tokens downstream to the services +it is proxying. Thus the SSO app above can be enhanced simply like +this:

app.groovy.  +

@Controller
+@EnableOAuth2Sso
+@EnableZuulProxy
+class Application {
+
+}

+

and it will (in addition to logging the user in and grabbing a token) +pass the authentication token downstream to the /proxy/* +services. If those services are implemented with +@EnableResourceServer then they will get a valid token in the +correct header.

How does it work? The @EnableOAuth2Sso annotation pulls in +spring-cloud-starter-security (which you could do manually in a +traditional app), and that in turn triggers some autoconfiguration for +a ZuulFilter, which itself is activated because Zuul is on the +classpath (via @EnableZuulProxy). The +filter +just extracts an access token from the currently authenticated user, +and puts it in a request header for the downstream requests.

2.2.3 Resource Server Token Relay

If your app has @EnableResourceServer you might want to relay the +incoming token downstream to other services. If you use a +RestTemplate to contact the downstream services then this is just a +matter of how to create the template with the right context.

If your service uses UserInfoTokenServices to authenticate incoming +tokens (i.e. it is using the security.oauth2.user-info-uri +configuration), then you can simply create an OAuth2RestTemplate +using an autowired OAuth2ClientContext (it will be populated by the +authentication process before it hits the backend code). Equivalently +(with Spring Boot 1.4), you could inject a +UserInfoRestTemplateFactory and grab its OAuth2RestTemplate in +your configuration. For example:

MyConfiguration.java.  +

@Bean
+public OAuth2RestTemplate restTemplate(UserInfoRestTemplateFactory factory) {
+    return factory.getUserInfoRestTemplate();
+}

+

This rest template will then have the same OAuth2ClientContext +(request-scoped) that is used by the authentication filter, so you can +use it to send requests with the same access token.

If your app is not using UserInfoTokenServices but is still a client +(i.e. it declares @EnableOAuth2Client or @EnableOAuth2Sso), then +with Spring Security Cloud any OAuth2RestOperations that the user +creates from an @Autowired @OAuth2Context will also forward +tokens. This feature is implemented by default as an MVC handler +interceptor, so it only works in Spring MVC. If you are not using MVC +you could use a custom filter or AOP interceptor wrapping an +AccessTokenContextRelay to provide the same feature.

Here’s a basic +example showing the use of an autowired rest template created +elsewhere ("foo.com" is a Resource Server accepting the same tokens as +the surrounding app):

MyController.java.  +

@Autowired
+private OAuth2RestOperations restTemplate;
+
+@RequestMapping("/relay")
+public String relay() {
+    ResponseEntity<String> response =
+      restTemplate.getForEntity("https://foo.com/bar", String.class);
+    return "Success! (" + response.getBody() + ")";
+}

+

If you don’t want to forward tokens (and that is a valid +choice, since you might want to act as yourself, rather than the +client that sent you the token), then you only need to create your own +OAuth2Context instead of autowiring the default one.

Feign clients will also pick up an interceptor that uses the +OAuth2ClientContext if it is available, so they should also do a +token relay anywhere where a RestTemplate would.

3. Configuring Authentication Downstream of a Zuul Proxy

You can control the authorization behaviour downstream of an +@EnableZuulProxy through the proxy.auth.* settings. Example:

application.yml.  +

proxy:
+  auth:
+    routes:
+      customers: oauth2
+      stores: passthru
+      recommendations: none

+

In this example the "customers" service gets an OAuth2 token relay, +the "stores" service gets a passthrough (the authorization header is +just passed downstream), and the "recommendations" service has its +authorization header removed. The default behaviour is to do a token +relay if there is a token available, and passthru otherwise.

See + +ProxyAuthenticationProperties for full details.

\ No newline at end of file diff --git a/spring-cloud-security/1.2.2.RELEASE/spring-cloud-security.xml b/spring-cloud-security/1.2.2.RELEASE/spring-cloud-security.xml new file mode 100644 index 00000000..639f7151 --- /dev/null +++ b/spring-cloud-security/1.2.2.RELEASE/spring-cloud-security.xml @@ -0,0 +1,287 @@ + + + + + +Spring Cloud Security +2018-01-16 + + + +Spring Cloud Security offers a set of primitives for building secure +applications and services with minimum fuss. A declarative model which +can be heavily configured externally (or centrally) lends itself to +the implementation of large systems of co-operating, remote components, +usually with a central indentity management service. It is also extremely +easy to use in a service platform like Cloud Foundry. Building on +Spring Boot and Spring Security OAuth2 we can quickly create systems that +implement common patterns like single sign on, token relay and token +exchange. + +Spring Cloud is released under the non-restrictive Apache 2.0 license. If you would like to contribute to this section of the documentation or if you find an error, please find the source code and issue trackers in the project at github. + + + +Quickstart +
+OAuth2 Single Sign On +Here’s a Spring Cloud "Hello World" app with HTTP Basic +authentication and a single user account: + +app.groovy + +@Grab('spring-boot-starter-security') +@Controller +class Application { + + @RequestMapping('/') + String home() { + 'Hello World' + } + +} + + +You can run it with spring run app.groovy and watch the logs for the password (username is "user"). So far this is just the default for a Spring Boot app. +Here’s a Spring Cloud app with OAuth2 SSO: + +app.groovy + +@Controller +@EnableOAuth2Sso +class Application { + + @RequestMapping('/') + String home() { + 'Hello World' + } + +} + + +Spot the difference? This app will actually behave exactly the same as +the previous one, because it doesn’t know it’s OAuth2 credentals +yet. +You can register an app in github quite easily, so try that if you +want a production app on your own domain. If you are happy to test on +localhost:8080, then set up these properties in your application +configuration: + +application.yml + +security: + oauth2: + client: + clientId: bd1c0a783ccdd1c9b9e4 + clientSecret: 1a9030fbca47a5b2c28e92f19050bb77824b5ad1 + accessTokenUri: https://github.com/login/oauth/access_token + userAuthorizationUri: https://github.com/login/oauth/authorize + clientAuthenticationScheme: form + resource: + userInfoUri: https://api.github.com/user + preferTokenInfo: false + + +run the app above and it will redirect to github for authorization. If +you are already signed into github you won’t even notice that it has +authenticated. These credentials will only work if your app is +running on port 8080. +To limit the scope that the client asks for when it obtains an access token +you can set security.oauth2.client.scope (comma separated or an array in YAML). By +default the scope is empty and it is up to to Authorization Server to +decide what the defaults should be, usually depending on the settings in +the client registration that it holds. + +The examples above are all Groovy scripts. If you want to write the +same code in Java (or Groovy) you need to add Spring Security OAuth2 +to the classpath (e.g. see the +sample here). + +
+
+OAuth2 Protected Resource +You want to protect an API resource with an OAuth2 token? Here’s a +simple example (paired with the client above): + +app.groovy + +@Grab('spring-cloud-starter-security') +@RestController +@EnableResourceServer +class Application { + + @RequestMapping('/') + def home() { + [message: 'Hello World'] + } + +} + + +and + +application.yml + +security: + oauth2: + resource: + userInfoUri: https://api.github.com/user + preferTokenInfo: false + + +
+
+ +More Detail +
+Single Sign On + +All of the OAuth2 SSO and resource server features moved to Spring Boot +in version 1.3. You can find documentation in the +Spring Boot user guide. + +
+
+Token Relay +A Token Relay is where an OAuth2 consumer acts as a Client and +forwards the incoming token to outgoing resource requests. The +consumer can be a pure Client (like an SSO application) or a Resource +Server. +
+Client Token Relay +If your app is a user facing OAuth2 client (i.e. has declared +@EnableOAuth2Sso or @EnableOAuth2Client) then it has an +OAuth2ClientContext in request scope from Spring Boot. You can +create your own OAuth2RestTemplate from this context and an +autowired OAuth2ProtectedResourceDetails, and then the context will +always forward the access token downstream, also refreshing the access +token automatically if it expires. (These are features of Spring +Security and Spring Boot.) + +Spring Boot (1.4.1) does not create an +OAuth2ProtectedResourceDetails automatically if you are using +client_credentials tokens. In that case you need to create your own +ClientCredentialsResourceDetails and configure it with +@ConfigurationProperties("security.oauth2.client"). + +
+
+Client Token Relay in Zuul Proxy +If your app also has a +Spring +Cloud Zuul embedded reverse proxy (using @EnableZuulProxy) then you +can ask it to forward OAuth2 access tokens downstream to the services +it is proxying. Thus the SSO app above can be enhanced simply like +this: + +app.groovy + +@Controller +@EnableOAuth2Sso +@EnableZuulProxy +class Application { + +} + + +and it will (in addition to logging the user in and grabbing a token) +pass the authentication token downstream to the /proxy/* +services. If those services are implemented with +@EnableResourceServer then they will get a valid token in the +correct header. +How does it work? The @EnableOAuth2Sso annotation pulls in +spring-cloud-starter-security (which you could do manually in a +traditional app), and that in turn triggers some autoconfiguration for +a ZuulFilter, which itself is activated because Zuul is on the +classpath (via @EnableZuulProxy). The +filter +just extracts an access token from the currently authenticated user, +and puts it in a request header for the downstream requests. +
+
+Resource Server Token Relay +If your app has @EnableResourceServer you might want to relay the +incoming token downstream to other services. If you use a +RestTemplate to contact the downstream services then this is just a +matter of how to create the template with the right context. +If your service uses UserInfoTokenServices to authenticate incoming +tokens (i.e. it is using the security.oauth2.user-info-uri +configuration), then you can simply create an OAuth2RestTemplate +using an autowired OAuth2ClientContext (it will be populated by the +authentication process before it hits the backend code). Equivalently +(with Spring Boot 1.4), you could inject a +UserInfoRestTemplateFactory and grab its OAuth2RestTemplate in +your configuration. For example: + +MyConfiguration.java + +@Bean +public OAuth2RestTemplate restTemplate(UserInfoRestTemplateFactory factory) { + return factory.getUserInfoRestTemplate(); +} + + +This rest template will then have the same OAuth2ClientContext +(request-scoped) that is used by the authentication filter, so you can +use it to send requests with the same access token. +If your app is not using UserInfoTokenServices but is still a client +(i.e. it declares @EnableOAuth2Client or @EnableOAuth2Sso), then +with Spring Security Cloud any OAuth2RestOperations that the user +creates from an @Autowired @OAuth2Context will also forward +tokens. This feature is implemented by default as an MVC handler +interceptor, so it only works in Spring MVC. If you are not using MVC +you could use a custom filter or AOP interceptor wrapping an +AccessTokenContextRelay to provide the same feature. +Here’s a basic +example showing the use of an autowired rest template created +elsewhere ("foo.com" is a Resource Server accepting the same tokens as +the surrounding app): + +MyController.java + +@Autowired +private OAuth2RestOperations restTemplate; + +@RequestMapping("/relay") +public String relay() { + ResponseEntity<String> response = + restTemplate.getForEntity("https://foo.com/bar", String.class); + return "Success! (" + response.getBody() + ")"; +} + + +If you don’t want to forward tokens (and that is a valid +choice, since you might want to act as yourself, rather than the +client that sent you the token), then you only need to create your own +OAuth2Context instead of autowiring the default one. +Feign clients will also pick up an interceptor that uses the +OAuth2ClientContext if it is available, so they should also do a +token relay anywhere where a RestTemplate would. +
+
+
+ +Configuring Authentication Downstream of a Zuul Proxy +You can control the authorization behaviour downstream of an +@EnableZuulProxy through the proxy.auth.* settings. Example: + +application.yml + +proxy: + auth: + routes: + customers: oauth2 + stores: passthru + recommendations: none + + +In this example the "customers" service gets an OAuth2 token relay, +the "stores" service gets a passthrough (the authorization header is +just passed downstream), and the "recommendations" service has its +authorization header removed. The default behaviour is to do a token +relay if there is a token available, and passthru otherwise. +See + +ProxyAuthenticationProperties for full details. + +
\ No newline at end of file