{"id":13735014,"url":"https://github.com/SAML-Toolkits/java-saml","last_synced_at":"2025-05-08T11:31:52.762Z","repository":{"id":38983556,"uuid":"1513115","full_name":"SAML-Toolkits/java-saml","owner":"SAML-Toolkits","description":"Java SAML toolkit","archived":false,"fork":false,"pushed_at":"2024-06-20T09:17:32.000Z","size":2093,"stargazers_count":633,"open_issues_count":73,"forks_count":395,"subscribers_count":73,"default_branch":"master","last_synced_at":"2024-11-03T07:43:02.337Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SAML-Toolkits.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2011-03-22T20:26:02.000Z","updated_at":"2024-10-03T06:29:30.000Z","dependencies_parsed_at":"2023-07-27T12:06:54.968Z","dependency_job_id":"3686fb51-21fc-457c-83ea-aa56c036ba8c","html_url":"https://github.com/SAML-Toolkits/java-saml","commit_stats":null,"previous_names":["onelogin/java-saml"],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SAML-Toolkits%2Fjava-saml","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SAML-Toolkits%2Fjava-saml/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SAML-Toolkits%2Fjava-saml/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SAML-Toolkits%2Fjava-saml/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SAML-Toolkits","download_url":"https://codeload.github.com/SAML-Toolkits/java-saml/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224727173,"owners_count":17359532,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T03:01:02.117Z","updated_at":"2024-11-15T03:31:21.899Z","avatar_url":"https://github.com/SAML-Toolkits.png","language":"Java","funding_links":[],"categories":["Programming Language Libraries","安全","others"],"sub_categories":["Java"],"readme":"# SAML Java Toolkit \u003c!-- omit in toc --\u003e\n\n[![Build Status](https://travis-ci.org/onelogin/java-saml.svg?branch=master)](https://travis-ci.org/onelogin/java-saml) [![Coverage Status](https://coveralls.io/repos/github/onelogin/java-saml/badge.svg?branch=master)](https://coveralls.io/github/onelogin/java-saml?branch=master)\n\nAdd SAML support to your Java applications using this library.\n\n2.8.0 uses xmlsec 2.2.3 which fixes [CVE-2021-40690](https://snyk.io/vuln/SNYK-JAVA-ORGAPACHESANTUARIO-1655558)\n\nVersion \u003e= 2.5.0 compatible with java8 / java9. Not compatible with java7\n\n2.5.0 sets the 'strict' setting parameter to true.\n\n2.5.0 uses xmlsec 2.1.4 which fixes [CVE-2019-12400](https://snyk.io/vuln/SNYK-JAVA-ORGAPACHESANTUARIO-460281)\n\nVersion 2.0.0 - 2.4.0, compatible with java7 / java8.\n\nWe [introduced some incompatibilities](https://github.com/onelogin/java-saml/issues/90), that could be fixed and make it compatible with java6.\n\nVersion 1.1.2 is considered to be deprecated. If you have used it, we strongly recommend that you migrate to the new version.\nWe rebuilt the toolkit on 2.0.0, so code/settings that you had been using in the previous version will no longer be compatible.\n\n- [Why add SAML support to my software?](#why-add-saml-support-to-my-software)\n- [General description](#general-description)\n- [Security warning](#security-warning)\n- [Installation](#installation)\n  - [Hosting](#hosting)\n    - [Github](#github)\n    - [Maven](#maven)\n  - [Dependencies](#dependencies)\n- [Working with the github repository code and Eclipse.](#working-with-the-github-repository-code-and-eclipse)\n  - [Get the toolkit.](#get-the-toolkit)\n  - [Adding java-saml toolkit components as a project](#adding-java-saml-toolkit-components-as-a-project)\n  - [Adding the java-saml-tookit-jspsample as a project](#adding-the-java-saml-tookit-jspsample-as-a-project)\n  - [Deploy the java-saml-tookit-jspsample](#deploy-the-java-saml-tookit-jspsample)\n- [Getting started](#getting-started)\n  - [Learning the toolkit](#learning-the-toolkit)\n    - [core (com.onelogin:java-saml-core)](#core-comoneloginjava-saml-core)\n    - [toolkit (com.onelogin:java-saml)](#toolkit-comoneloginjava-saml)\n    - [samples (com.onelogin:java-saml-tookit-samples)](#samples-comoneloginjava-saml-tookit-samples)\n  - [How it works](#how-it-works)\n    - [Javadocs](#javadocs)\n    - [Settings](#settings)\n      - [Properties File](#properties-file)\n      - [KeyStores](#keystores)\n      - [Dynamic Settings](#dynamic-settings)\n    - [The HttpRequest](#the-httprequest)\n    - [Initiate SSO](#initiate-sso)\n    - [The SP Endpoints](#the-sp-endpoints)\n      - [SP Metadata](#sp-metadata)\n      - [Attribute Consumer Service(ACS)](#attribute-consumer-serviceacs)\n      - [Single Logout Service (SLS)](#single-logout-service-sls)\n    - [Initiate SLO](#initiate-slo)\n  - [Extending the provided implementation](#extending-the-provided-implementation)\n  - [Working behind load balancer](#working-behind-load-balancer)\n  - [IdP with multiple certificates](#idp-with-multiple-certificates)\n  - [Replay attacks](#replay-attacks)\n- [Demo included in the toolkit](#demo-included-in-the-toolkit)\n    - [SP setup](#sp-setup)\n    - [IdP setup](#idp-setup)\n    - [How it works](#how-it-works-1)\n\n## Why add SAML support to my software?\n\nSAML is an XML-based standard for web browser single sign-on and is defined by\nthe OASIS Security Services Technical Committee. The standard has been around\nsince 2002, but lately it has become popular due to its advantages as follows:\n\n * **Usability** - One-click access from portals or intranets, deep linking,\n   password elimination and automatically renewing sessions make life\n   easier for the user.\n * **Security** - Based on strong digital signatures for authentication and\n   integrity, SAML is a secure single sign-on protocol that the largest\n   and most security conscious enterprises in the world rely on.\n * **Speed** - SAML is fast. One browser redirect is all it takes to securely\n   sign a user into an application.\n * **Phishing Prevention** - If you don’t have a password for an app, you\n   can’t be tricked into entering it on a fake login page.\n * **IT Friendly** - SAML simplifies life for IT because it centralizes\n   authentication, provides greater visibility and makes directory\n   integration easier.\n * **Opportunity** - B2B cloud vendor should support SAML to facilitate the\n   integration of their product.\n\n\n## General description\n\nSAML Java toolkit lets you turn a Java application into a SP\n(Service Provider) that can be connected to an IdP (Identity Provider).\n\nSupports:\n\n * SSO and SLO (SP-Initiated and IdP-Initiated).\n * Assertion and nameId encryption.\n * Assertion signatures.\n * Message signatures: AuthNRequest, LogoutRequest, LogoutResponses.\n * Enable an Assertion Consumer Service endpoint.\n * Enable a Single Logout Service endpoint.\n * Publish the SP metadata (which can be signed).\n\nKey features:\n\n * **saml2int** - Implements the SAML 2.0 Web Browser SSO Profile.\n * **Session-less** - Forget those common conflicts between the SP and\n   the final app; the toolkit delegates session in the final app.\n * **Easy to use** - Programmer will be allowed to code high-level and\n   low-level programming; 2 easy-to-use APIs are available.\n * **Tested** - Thoroughly tested.\n\n## Security warning\n\nIn production, the **onelogin.saml2.strict** setting parameter MUST be set as **\"true\"**. Otherwise your environment is not secure and will be exposed to attacks.\n\nIn production also we highly recommend to register on the settings the IdP certificate instead of using the fingerprint method. The fingerprint, is a hash, so at the end is open to a collision attack that can end on a signature validation bypass. Other SAML toolkits deprecated that mechanism, we maintain it for compatibility and also to be used on test environment.\n\nThe IdPMetadataParser class does not validate in any way the URL that is introduced in order to be parsed.\n\nUsually the same administrator that handles the Service Provider also sets the URL to the IdP, which should be a trusted resource.\n\nBut there are other scenarios, like a SAAS app where the administrator of the app delegates this functionality to other users. In this case, extra precaution should be taken in order to validate such URL inputs and avoid attacks like SSRF.\n\n\n## Installation\n### Hosting\n#### Github\nThe toolkit is hosted on github. You can download it from:\n* Latest release: https://github.com/onelogin/java-saml/releases/latest\n* Master repo: https://github.com/onelogin/java-saml/tree/master\n\n#### Maven\nThe toolkit is hosted at [Sonatype OSSRH (OSS Repository Hosting)](http://central.sonatype.org/pages/ossrh-guide.html) that is synced to the Central Repository.\n\nInstall it as a maven dependency:\n```xml\n  \u003cdependency\u003e\n      \u003cgroupId\u003ecom.onelogin\u003c/groupId\u003e\n      \u003cartifactId\u003ejava-saml\u003c/artifactId\u003e\n      \u003cversion\u003e2.9.0\u003c/version\u003e\n  \u003c/dependency\u003e\n```\n\n\n### Dependencies\njava-saml (com.onelogin:java-saml-toolkit) has the following dependencies:\n\n*core:*\n* org.apache.santuario:xmlsec\n* joda-time:joda-time\n* org.apache.commons:commons-lang3\n* commons-codec:commons-codec\n* testing:\n  * org.hamcrest:hamcrest-core and org.hamcrest:hamcrest-library\n  * junit:junit\n  * org.mockito:mockito-core\n* logging:\n  * org.slf4j:slf4j-api\n  * ch.qos.logback:logback-classic\n* For CI:\n  * org.jacoco:jacoco-maven-plugin\n\nalso the [Java Cryptography Extension (JCE)](https://en.wikipedia.org/wiki/Java_Cryptography_Extension) is required. If you don't have it, download the version of [jce-8](http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html), unzip it, and drop its content at\n*${java.home}/jre/lib/security/*. JDK 9 and later offer the stronger cryptographic algorithms by default.\n\n*toolkit:*\n* com.onelogin:java-saml-core\n* javax.servlet:servlet-api\n\n*maven:*\n* org.apache.maven.plugins:maven-jar-plugin\n* org.apache.maven.plugins:maven-surefire-plugin\n* org.apache.maven.plugins:maven-enforcer-plugin\n\nFor more info, open and read the different pom.xml files:\n[core/pom.xml](https://github.com/onelogin/java-saml/blob/v2.5.0/core/pom.xml), [toolkit/pom.xml](https://github.com/onelogin/java-saml/blob/v2.5.0/toolkit/pom.xml)\n\n## Working with the github repository code and Eclipse.\n### Get the toolkit.\nThe toolkit is hosted on github. You can download it from:\n* Latest release: https://github.com/onelogin/java-saml/releases/latest\n* Master repo: https://github.com/onelogin/java-saml/tree/master\n\n### Adding java-saml toolkit components as a project\n1. Open Eclipse and set a workspace\n2. File \u003e Import \u003e Maven : Existing Maven Projects \u003e Select the path where the core folder of the Java Toolkit is  *\u003cpath\u003e/java-saml/core*, resolve the Workspace project and select the pom.xml\n3. File \u003e Import \u003e Maven : Existing Maven Projects \u003e Select the path where the toolkit folder of the Java Toolkit is  *\u003cpath\u003e/java-saml/toolkit*, resolve the Workspace project and select the pom.xml\n\n### Adding the java-saml-tookit-jspsample as a project\n1. File \u003e Import \u003e Maven : Existing Maven Projects \u003e Select the path where the core folder of the Java Toolkit is  *\u003cpath\u003e/java-saml/samples/java-saml-tookit-jspsample*, resolve the Workspace project and select the pom.xml\n\n### Deploy the java-saml-tookit-jspsample\n\nAt the Package Explorer, select the jsp-sample project, 2nd bottom of the mouse and Run As \u003e Run Server\nSelect a [Tomcat Server](http://crunchify.com/step-by-step-guide-to-setup-and-install-apache-tomcat-server-in-eclipse-development-environment-ide/) in order to deploy the server.\n\n## Getting started\n### Learning the toolkit\n\nJava SAML Toolkit contains different folders (core, toolkit, samples) and some files.\n\nLet's start describing them:\n\n#### core (com.onelogin:java-saml-core) ####\nThis folder contains a maven project with the heart of java-saml, classes and methods to handle AuthNRequest, SAMLResponse, LogoutRequest, LogoutResponse and Metadata (low level API). In addition, it contains classes to load the settings of the toolkit and the HttpRequest class, a framework-agnostic representation of an HTTP request.\n\nIn the repo, at *src/main/java* you will find the source; at *src/main/resources/schemas*, there are xsd schemas used to validate the SAML messages; at *src/test/java* are the tests for its classes; and at *src/test/resources* can be found different settings, SAML messages and certificates used by the junit tests.\n\n\n#### toolkit (com.onelogin:java-saml) ####\nThis folder contains a maven project with the Auth class to handle the low level classes of java-saml-core and the ServletUtils class to handle javax.servlet.http objects, used on the Auth class.\nIn the repo, at *src/main/java* you will find the source and at *src/test/java* the junit tests for the classes Auth and ServletUtils.\n\n#### samples (com.onelogin:java-saml-tookit-samples) ####\nThis folder contains a maven project with a jsp app used to learn how the java-saml toolkit works.\n\nWithin the *java-saml-tookit-jspsample/src/main/webapp* folder are several jsp files, each one representing a different endpoint:\n- *index.jsp* Index of the webapp.\n- *dologin.jsp* SP-initiated SSO endpoint.\n- *dologout.jsp* SP-initiated SLO endpoint.\n- *acs.jsp* Service Provider Assertion Consumer Service endpoint.\n- *attrs.jsp* Shows attributes collected from the SAMLResponse.\n- *sls.jsp* Service Provider Single Logout Service endpoint.\n- *metadata.jsp* Publish SP metadata.\n\nAt *java-saml-tookit-jspsample/src/main/resources* folder is the *onelogin.saml.properties* file which contains the SAML settings.\n\n### How it works\n\n#### Javadocs\n\n* [toolkit (com.onelogin:java-saml)](https://onelogin.github.io/java-saml/toolkit/index.html)\n* [core (com.onelogin:java-saml-core)](https://onelogin.github.io/java-saml/core/index.html)\n\n#### Settings\nFirst of all we need to configure the toolkit. The SP's info, the IdP's info, and in some cases, configuration for advanced security issues, such as signatures and encryption.\n\n##### Properties File\nAll the settings are defined in one unique file; by default, the Auth class loads a *onelogin.saml.properties* file with the Auth() method, but if we named it in a different way, we can use Auth(filename);\n\nHere are the list of properties to be defined on the settings file:\n```properties\n#  If 'strict' is True, then the Java Toolkit will reject unsigned\n#  or unencrypted messages if it expects them signed or encrypted\n#  Also will reject the messages if not strictly follow the SAML\nonelogin.saml2.strict =  false\n\n# Enable debug mode (to print errors)\nonelogin.saml2.debug =  false\n\n\n## Service Provider Data that we are deploying ##\n\n#  Identifier of the SP entity  (must be a URI)\nonelogin.saml2.sp.entityid = http://localhost:8080/java-saml-tookit-jspsample/metadata.jsp\n\n# Specifies info about where and how the \u003cAuthnResponse\u003e message MUST be\n# returned to the requester, in this case our SP.\n# URL Location where the \u003cResponse\u003e from the IdP will be returned\nonelogin.saml2.sp.assertion_consumer_service.url = http://localhost:8080/java-saml-tookit-jspsample/acs.jsp\n\n# SAML protocol binding to be used when returning the \u003cResponse\u003e\n# message.  SAMLToolkit supports for this endpoint the\n# HTTP-POST binding only\nonelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\n\n# Specifies info about where and how the \u003cLogout Response\u003e message MUST be\n# returned to the requester, in this case our SP.\nonelogin.saml2.sp.single_logout_service.url = http://localhost:8080/java-saml-tookit-jspsample/sls.jsp\n\n# SAML protocol binding to be used when returning the \u003cLogoutResponse\u003e or sending the \u003cLogoutRequest\u003e\n# message.  SAMLToolkit supports for this endpoint the\n# HTTP-Redirect binding only\nonelogin.saml2.sp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect\n\n# Specifies constraints on the name identifier to be used to\n# represent the requested subject.\n# Take a look on core/src/main/java/com/onelogin/saml2/util/Constants.java to see the NameIdFormat supported\nonelogin.saml2.sp.nameidformat = urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified\n\n# Usually x509cert and privateKey of the SP are provided by files placed at\n# the certs folder. But we can also provide them with the following parameters\n\nonelogin.saml2.sp.x509cert =\n\n# Future SP certificate, to be used during SP Key roll over\nonelogin.saml2.sp.x509certNew =\n\n# Requires Format PKCS#8   BEGIN PRIVATE KEY\n# If you have     PKCS#1   BEGIN RSA PRIVATE KEY  convert it by   openssl pkcs8 -topk8 -inform pem -nocrypt -in sp.rsa_key -outform pem -out sp.pem\nonelogin.saml2.sp.privatekey =\n\n# Organization\nonelogin.saml2.organization.name = SP Java\nonelogin.saml2.organization.displayname = SP Java Example\nonelogin.saml2.organization.url = http://sp.example.com\nonelogin.saml2.organization.lang = en\n\n# Contacts (use indexes to specify multiple contacts, multiple e-mail addresses per contact, multiple phone numbers per contact)\nonelogin.saml2.sp.contact[0].contactType=administrative\nonelogin.saml2.sp.contact[0].company=ACME\nonelogin.saml2.sp.contact[0].given_name=Guy\nonelogin.saml2.sp.contact[0].sur_name=Administrative\nonelogin.saml2.sp.contact[0].email_address[0]=administrative@example.com\nonelogin.saml2.sp.contact[0].email_address[1]=administrative2@example.com\nonelogin.saml2.sp.contact[0].telephone_number[0]=+1-123456789\nonelogin.saml2.sp.contact[0].telephone_number[1]=+1-987654321\nonelogin.saml2.sp.contact[1].contactType=other\nonelogin.saml2.sp.contact[1].company=Big Corp\nonelogin.saml2.sp.contact[1].email_address=info@example.com\n\n# Legacy contacts (legacy way to specify just a technical and a support contact with minimal info)\nonelogin.saml2.contacts.technical.given_name = Technical Guy\nonelogin.saml2.contacts.technical.email_address = technical@example.com\nonelogin.saml2.contacts.support.given_name = Support Guy\nonelogin.saml2.contacts.support.email_address = support@example.com\n\n## Identity Provider Data that we want connect with our SP ##\n\n# Identifier of the IdP entity  (must be a URI)\nonelogin.saml2.idp.entityid =\n\n# SSO endpoint info of the IdP. (Authentication Request protocol)\n# URL Target of the IdP where the SP will send the Authentication Request Message\nonelogin.saml2.idp.single_sign_on_service.url =\n\n# SAML protocol binding to be used to deliver the \u003cAuthnRequest\u003e message\n# to the IdP.  SAMLToolkit supports for this endpoint the\n# HTTP-Redirect binding only\nonelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect\n\n# SLO endpoint info of the IdP.\n# URL Location of the IdP where the SP will send the SLO Request\nonelogin.saml2.idp.single_logout_service.url =\n\n# Optional SLO Response endpoint info of the IdP.\n# URL Location of the IdP where the SP will send the SLO Response. If left blank, same URL as onelogin.saml2.idp.single_logout_service.url will be used.\n# Some IdPs use a separate URL for sending a logout request and response, use this property to set the separate response url\nonelogin.saml2.idp.single_logout_service.response.url =\n\n# SAML protocol binding to be used when returning the \u003cResponse\u003e\n# message.  SAMLToolkit supports for this endpoint the\n# HTTP-Redirect binding only\nonelogin.saml2.idp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect\n\n# Public x509 certificate of the IdP\nonelogin.saml2.idp.x509cert =\n\n# Instead of using the whole x509cert you can use a fingerprint in order to\n# validate a SAMLResponse (but you still need the x509cert to validate LogoutRequest and LogoutResponse using the HTTP-Redirect binding).\n# But take in mind that the fingerprint, is a hash, so at the end is open to a collision attack that can end on a signature validation bypass,\n# that why we don't recommend it use for production environments.\n# (openssl x509 -noout -fingerprint -in \"idp.crt\" to generate it,\n# or add for example the -sha256 , -sha384 or -sha512 parameter)\n#\n# If a fingerprint is provided, then the certFingerprintAlgorithm is required in order to\n# let the toolkit know which Algorithm was used. Possible values: sha1, sha256, sha384 or sha512\n# 'sha1' is the default value.\n# onelogin.saml2.idp.certfingerprint =\n# onelogin.saml2.idp.certfingerprint_algorithm = sha256\n\n# Security settings\n#\n\n# Indicates that the nameID of the \u003csamlp:logoutRequest\u003e sent by this SP\n# will be encrypted.\nonelogin.saml2.security.nameid_encrypted = false\n\n# Indicates whether the \u003csamlp:AuthnRequest\u003e messages sent by this SP\n# will be signed.              [The Metadata of the SP will offer this info]\nonelogin.saml2.security.authnrequest_signed = false\n\n# Indicates whether the \u003csamlp:logoutRequest\u003e messages sent by this SP\n# will be signed.\nonelogin.saml2.security.logoutrequest_signed = false\n\n# Indicates whether the \u003csamlp:logoutResponse\u003e messages sent by this SP\n# will be signed.\nonelogin.saml2.security.logoutresponse_signed = false\n\n# Indicates a requirement for the \u003csamlp:Response\u003e, \u003csamlp:LogoutRequest\u003e and\n# \u003csamlp:LogoutResponse\u003e elements received by this SP to be signed.\nonelogin.saml2.security.want_messages_signed = false\n\n# Indicates a requirement for the \u003csaml:Assertion\u003e elements received by this SP to be signed.\nonelogin.saml2.security.want_assertions_signed = false\n\n# Indicates a requirement for the Metadata of this SP to be signed.\n# Right now supported null (in order to not sign) or true (sign using SP private key)\nonelogin.saml2.security.sign_metadata =\n\n# Indicates a requirement for the Assertions received by this SP to be encrypted\nonelogin.saml2.security.want_assertions_encrypted = false\n\n# Indicates a requirement for the NameID received by this SP to be encrypted\nonelogin.saml2.security.want_nameid_encrypted = false\n\n\n# Authentication context.\n# Set Empty and no AuthContext will be sent in the AuthNRequest,\n# Set comma separated values urn:oasis:names:tc:SAML:2.0:ac:classes:Kerberos,urn:oasis:names:tc:SAML:2.0:ac:classes:Password\nonelogin.saml2.security.requested_authncontext = urn:oasis:names:tc:SAML:2.0:ac:classes:Password\n\n# Allows the authn comparison parameter to be set, defaults to 'exact'\nonelogin.saml2.security.requested_authncontextcomparison = exact\n\n# Allows duplicated names in the attribute statement\nonelogin.saml2.security.allow_duplicated_attribute_name = false\n\n# Indicates if the SP will validate all received xmls.\n# (In order to validate the xml, 'strict' and 'wantXMLValidation' must be true).\nonelogin.saml2.security.want_xml_validation = true\n\n# Algorithm that the toolkit will use on signing process. Options:\n#  'http://www.w3.org/2000/09/xmldsig#rsa-sha1'\n#  'http://www.w3.org/2000/09/xmldsig#dsa-sha1'\n#  'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'\n#  'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384'\n#  'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512'\nonelogin.saml2.security.signature_algorithm = http://www.w3.org/2001/04/xmldsig-more#rsa-sha256\n\n# Algorithm that the toolkit will use on digest process. Options:\n#  'http://www.w3.org/2000/09/xmldsig#sha1'\n#  'http://www.w3.org/2001/04/xmlenc#sha256'\n#  'http://www.w3.org/2001/04/xmldsig-more#sha384'\n#  'http://www.w3.org/2001/04/xmlenc#sha512'\nonelogin.saml2.security.digest_algorithm = http://www.w3.org/2001/04/xmlenc#sha256\n\n\n# Reject Signatures with deprecated algorithms (sha1)\nonelogin.saml2.security.reject_deprecated_alg = true\n\n# Enable trimming of parsed Name IDs and attribute values\n# SAML specification states that no trimming for string elements should be performed, so no trimming will be\n# performed by default on extracted Name IDs and attribute values. However, some SAML implementations may add\n# undesirable surrounding whitespace when outputting XML (possibly due to formatting/pretty-printing).\n# These two options allow to optionally enable value trimming on extracted Name IDs (including issuers) and\n# attribute values.\nonelogin.saml2.parsing.trim_name_ids = false\nonelogin.saml2.parsing.trim_attribute_values = false\n\n# Prefix used in generated Unique IDs.\n# Optional, defaults to ONELOGIN_ or full ID is like ONELOGIN_ebb0badd-4f60-4b38-b20a-a8e01f0592b1.\n# At minimun, the prefix can be non-numeric character such as \"_\".\n# onelogin.saml2.unique_id_prefix = _\n```\n\n\n##### KeyStores\n\nThe Auth constructor supports the ability to read SP public cert/private key from a KeyStore. A KeyStoreSettings object must be provided with the KeyStore, the Alias and the KeyEntry password.\n\n```java\nimport java.io.FileInputStream;\nimport java.security.KeyStore;\nimport com.onelogin.saml2.Auth\nimport com.onelogin.saml2.model.KeyStoreSettings\n\nString keyStoreFile = \"oneloginTestKeystore.jks\";\nString alias = \"keywithpassword\";\nString storePass = \"changeit\";\nString keyPassword = \"keypassword\";\n\nKeyStore ks = KeyStore.getInstance(\"JKS\");\nks.load(new FileInputStream(keyStoreFile), storePass.toCharArray());\n\nKeyStoreSettings keyStoreSettings =  new keyStoreSettings(ks, alias, keyPassword);\nAuth auth = new Auth(KeyStoreSettings keyStoreSetting);\n```\n\n##### Dynamic Settings\nIt is possible to build settings programmatically. You can load your values from different sources such as files, databases, or generated values.\n\nThe `SettingsBuilder` class exposes the method `fromValues(Map\u003cString, Object\u003e samlData)` which let you build your settings dynamically. The `key` strings are the same from the *Properties file*\n```java\nMap\u003cString, Object\u003e samlData = new HashMap\u003c\u003e();\nsamlData.put(\"onelogin.saml2.sp.entityid\", \"http://localhost:8080/java-saml-tookit-jspsample/metadata.jsp\");\nsamlData.put(\"onelogin.saml2.sp.assertion_consumer_service.url\", new URL(\"http://localhost:8080/java-saml-tookit-jspsample/acs.jsp\"));\nsamlData.put(\"onelogin.saml2.security.want_xml_validation\",true);\nsamlData.put(\"onelogin.saml2.sp.x509cert\", myX509CertInstance);\n\nSettingsBuilder builder = new SettingsBuilder();\nSaml2Settings settings = builder.fromValues(samlData).build();\n```\n\nTo instantiate the `Auth` class you write\n```java\nAuth auth = new Auth(settings, request, response);\n```\n\n#### The HttpRequest\njava-saml-core uses HttpRequest class, a framework-agnostic representation of an HTTP request.\n\njava-saml depends on javax.servlet:servlet-api, and the classes Auth and ServletUtils use HttpServletRequest and HttpServletResponse objects.\n\nIf you want to use anything different than javax.servlet.http, you will need to reimplement Auth and ServletUtils based on that new representation of the HTTP request/responses.\n\n#### Initiate SSO\nIn order to send an AuthNRequest to the IdP:\n```java\nAuth auth = new Auth(request, response);\nauth.login();\n```\nThe AuthNRequest will be sent signed or unsigned based on the security settings 'onelogin.saml2.security.authnrequest_signed'.\n\nThe IdP will then return the SAML Response to the user's client. The client is then forwarded to the Attribute Consumer Service of the SP with this information.\n\nWe can set a 'RelayState' parameter containing a return url to the login function:\n```java\nString returnUrl = 'https://example.com';\nauth.login(relayState=returnUrl)\n```\nThe login method can receive 3 more optional parameters:\n- *authnRequestParams* which in turn allows to shape the AuthNRequest with the following properties:\n  - *forceAuthn* When true the AuthNRequest will have the `ForceAuthn` attribute set to `true`\n  - *isPassive* When true the AuthNRequest will have the `IsPassive` attribute set to `true`\n  - *setNameIdPolicy* When true the AuthNRequest will set a `NameIdPolicy` element\n  - *allowCreate* When true, and *setNameIdPolicy* is also true, the AuthNRequest will have the `AllowCreate` attribute set to `true` on the `NameIdPolicy` element\n  - *nameIdValueReq* Indicates to the IdP the subject that should be authenticated\n- *stay* Set to true to stay (returns the url string), otherwise set to false to execute a redirection to that url (IdP SSO URL)\n- *parameters* Use it to send extra parameters in addition to the AuthNRequest\n\nBy default, the login method initiates a redirect to the SAML Identity Provider. You can use the *stay* parameter, to prevent that, and execute the redirection manually. We need to use that if a match on the future SAMLResponse ID and the AuthNRequest ID to be sent is required.  That AuthNRequest ID must be extracted and stored for future validation, so we can't execute the redirection on the login.  Instead, set *stay* to true, then get that ID by\n```\nauth.getLastRequestId()\n```\nand later executing the redirection manually.\n\n\n#### The SP Endpoints\nRelated to the SP there are 3 important endpoints: The metadata view, the ACS view and the SLS view. The toolkit provides at the demo of the samples folder those views.\n\n##### SP Metadata\nThis code will provide the XML metadata file of our SP, based on the info that we provided in the settings files.\n```java\nAuth auth = new Auth();\nSaml2Settings settings = auth.getSettings();\nString metadata = settings.getSPMetadata();\nList\u003cString\u003e errors = Saml2Settings.validateMetadata(metadata);\nif (errors.isEmpty()) {\n   out.println(metadata);\n} else {\n   response.setContentType(\"text/html; charset=UTF-8\");\n   for (String error : errors) {\n       out.println(\"\u003cp\u003e\"+error+\"\u003c/p\u003e\");\n   }\n}\n```\nThe getSPMetadata will return the metadata signed or not based on the security parameter of the settings `onelogin.saml2.security.sign_metadata`.\n\nBefore the XML metadata is exposed, a check takes place to ensure that the info to be provided is valid.\n\n##### Attribute Consumer Service(ACS)\nThis code handles the SAML response that the IdP forwards to the SP through the user's client.\n```java\nAuth auth = new Auth(request, response);\nauth.processResponse();\nif (!auth.isAuthenticated()) {\n   out.println(\"Not authenticated\");\n}\n\nList\u003cString\u003e errors = auth.getErrors();\nif (!errors.isEmpty()) {\n    out.println(StringUtils.join(errors, \", \"));\n    if (auth.isDebugActive()) {\n        String errorReason = auth.getLastErrorReason();\n        if (errorReason != null \u0026\u0026 !errorReason.isEmpty()) {\n            out.println(auth.getLastErrorReason());\n        }\n    }\n} else {\n    Map\u003cString, List\u003cString\u003e\u003e attributes = auth.getAttributes();\n    String nameId = auth.getNameId();\n    String nameIdFormat = auth.getNameIdFormat();\n    String sessionIndex = auth.getSessionIndex();\n    String nameidNameQualifier = auth.getNameIdNameQualifier();\n    String nameidSPNameQualifier = auth.getNameIdSPNameQualifier();\n\n    session.setAttribute(\"attributes\", attributes);\n    session.setAttribute(\"nameId\", nameId);\n    session.setAttribute(\"nameIdFormat\", nameIdFormat);\n    session.setAttribute(\"sessionIndex\", sessionIndex);\n    session.setAttribute(\"nameidNameQualifier\", nameidNameQualifier);\n    session.setAttribute(\"nameidSPNameQualifier\", nameidSPNameQualifier);\n\n    String relayState = request.getParameter(\"RelayState\");\n\n    if (relayState != null \u0026\u0026 relayState != ServletUtils.getSelfRoutedURLNoQuery(request)) {\n        response.sendRedirect(request.getParameter(\"RelayState\"));\n    } else {\n        if (attributes.isEmpty()) {\n            out.println(\"You don't have any attributes\");\n        }\n       else {\n            Collection\u003cString\u003e keys = attributes.keySet();\n            for(String name :keys){\n                out.println(name);\n                List\u003cString\u003e values = attributes.get(name);\n                for(String value :values) {\n                    out.println(\" - \" + value);\n                }\n            }\n        }\n    }\n}\n```\nThe SAML response is processed and then checked to ensure that there are no errors. It also verifies that the user is authenticated, and then the userdata is stored in the session.\nAt that point there are 2 possible alternatives:\n- If no RelayState is provided, we could show the user data in this view or however we wanted.\n- If RelayState is provided, a redirection take place.\nNotice that we saved the user data in the session before the redirection to have the user data available at the RelayState view.\n\nIn order to retrieve attributes we use:\n```\nMap\u003cString, List\u003cString\u003e\u003e attributes = auth.getAttributes();\n```\n\nWith this method we get a Map with all the user data provided by the IdP in the Assertion of the SAML Response.\n```\n{\n    \"cn\": [\"Jhon\"],\n    \"sn\": [\"Doe\"],\n    \"mail\": [\"Doe\"],\n    \"groups\": [\"users\", \"members\"]\n}\n```\nEach attribute name can be used as a key to obtain the value. Every attribute is a list of values. A single-valued attribute is a list of a single element.\n\nBefore trying to get an attribute, check that the user is authenticated. If the user isn't authenticated, an empty Map will be returned. For example, if we call to getAttributes before a auth.processResponse, the getAttributes() will return an empty Map.\n\n##### Single Logout Service (SLS)\nThis code handles the Logout Request and the Logout Responses.\n```java\nAuth auth = new Auth(request, response);\nauth.processSLO();\nList\u003cString\u003e errors = auth.getErrors();\nif (errors.isEmpty()) {\n   out.println(\"Sucessfully logged out\");\n} else {\n   for(String error : errors) {\n      out.println(error);\n   }\n}\n```\nIf the SLS endpoints receives a Logout Response, the response is validated and the session of the HttpRequest could be closed.\n\nIf the SLS endpoints receives an Logout Request, the request is validated, the session is closed and a Logout Response is sent to the SLS endpoint of the IdP.\n\nIf we don't want that processSLO to destroy the session, pass the keepLocalSession parameter as true to the processSLO method.\n\n#### Initiate SLO\nIn order to send a Logout Request to the IdP:\n\n```java\nAuth auth = new Auth(request, response);\n\nString nameId = null;\nif (session.getAttribute(\"nameId\") != null) {\n    nameId = session.getAttribute(\"nameId\").toString();\n}\nString nameIdFormat = null;\nif (session.getAttribute(\"nameIdFormat\") != null) {\n    nameIdFormat = session.getAttribute(\"nameIdFormat\").toString();\n}\nString nameidNameQualifier = null;\nif (session.getAttribute(\"nameidNameQualifier\") != null) {\n    nameIdFormat = session.getAttribute(\"nameidNameQualifier\").toString();\n}\nString nameidSPNameQualifier = null;\nif (session.getAttribute(\"nameidSPNameQualifier\") != null) {\n    nameidSPNameQualifier = session.getAttribute(\"nameidSPNameQualifier\").toString();\n}\nString sessionIndex = null;\nif (session.getAttribute(\"sessionIndex\") != null) {\n    sessionIndex = session.getAttribute(\"sessionIndex\").toString();\n}\nauth.logout(null, new LogoutRequestParams(sessionIndex, nameId, nameIdFormat));\n```\n\nThe Logout Request will be sent signed or unsigned based on the security settings 'onelogin.saml2.security.logoutrequest_signed'\n\nThe IdP will return the Logout Response through the user's client to the Single Logout Service of the SP.\n\nWe can set a 'RelayState' parameter containing a return url to the login function:\n\n```java\nString returnUrl = 'https://example.com';\nauth.logout(relayState=returnUrl)\n```\n\nAlso there are other 3 optional parameters that can be set:\n- *logoutRequestParams* which in turn allows to shape the LogoutRequest with the following properties:\n  - *sessionIndex* Identifies the session of the user\n  - *nameId* That will be used to build the LogoutRequest. If no *nameId* parameter is set and the auth object processed a SAML Response with a `NameID`, then this `NameID` will be used\n  - *nameidFormat* The `NameID` `Format` that will be set on the LogoutRequest\n  - *nameIdNameQualifier* The `NameID` `NameQualifier` that will be set on the LogoutRequest\n  - *nameIdSPNameQualifier* The `NameID` `SPNameQualifier` that will be set on the LogoutRequest\n- *stay* True if we want to stay (returns the url string) False to execute a redirection to that url (IdP SLS URL)\n- *parameters* Use it to send extra parameters in addition to the LogoutRequest\n\nBy default the logout method initiates a redirect to the SAML Identity Provider. You can use the *stay* parameter, to prevent that, and execute the redirection manually. We need to use that\nif a match on the future LogoutResponse ID and the LogoutRequest ID to be sent is required, that LogoutRequest ID must be extracted and stored for future validation so we can't execute the redirection on the logout, instead set stay to true, then get that ID by\n\n```java\nauth.getLastRequestId()\n```\nand later executing the redirection manually.\n\n### Extending the provided implementation\n\nAll the provided SAML message classes (`AuthnRequest`, `SamlResponse`, `LogoutRequest`, `LogoutResponse`) can be extended to add or change the processing behavior.\n\nIn particular, the classes used to produce outgoing messages (`AuthnRequest`, `LogoutRequest`, and `LogoutResponse`) also provide a `postProcessXml` method that can be overridden to customise the generation of the corresponding SAML message XML, along with the ability to pass in proper extensions of the input parameter classes (`AuthnRequestParams`, `LogoutRequestParams`, and `LogoutResponseParams` respectively).\n\nOnce you have prepared your extension classes, in order to make the `Auth` class use them, an appropriate `SamlMessageFactory` implementation can be specified. As an example, assuming you've created two extension classes `AuthnRequestEx` and `SamlResponseEx` to customise the creation of AuthnRequest SAML messages and the validation of SAML responses respectively, as well as an extended `AuthnRequestParamsEx` input parameter class to drive the AuthnRequest generation post-processing, you can do the following:\n\n```java\nAuth auth = new Auth(request, response);\nauth.setSamlMessageFactory(new SamlMessageFactory() {\n\t@Override\n\tpublic AuthnRequest createAuthnRequest(Saml2Settings settings, AuthnRequestParams params) {\n\t\treturn new AuthnRequestEx(settings, (AuthnRequestParamsEx) params);\n\t}\n\n\t@Override\n\tpublic SamlResponse createSamlResponse(Saml2Settings settings, HttpRequest request) throws Exception {\n\t\treturn new SamlResponseEx(settings, request);\n\t}\n});\n// then proceed with login...\nauth.login(relayState, new AuthnRequestParamsEx()); // the custom generation of AuthnReqeustEx will be executed\n// ... or process the response as usual\nauth.processResponse(); // the custom validation of SamlResponseEx will be executed\n```\n\n### Working behind load balancer\n\nIs possible that asserting request URL and Destination attribute of SAML response fails when working behind load balancer with SSL offload.\n\nYou should be able to workaround this by configuring your server so that it is aware of the proxy and returns the original url when requested.\n\nFor Apache Tomcat this is done by setting the proxyName, proxyPort, scheme and secure attributes for the Connector. See [here](http://serverfault.com/questions/774300/ssl-offloading-from-apache-to-tomcat-get-overwritten-somewhere) for an example.\n\n\n### IdP with multiple certificates\n\n In some scenarios the IdP uses different certificates for\n signing/encryption, or is under key rollover phase and more than one certificate is published on IdP metadata.\n\n In order to handle that the toolkit offers the `onelogin.saml2.idp.x509certMulti` parameters where you can set additional certificates that will be used to validate IdP signature. However just the certificate set in `onelogin.saml2.idp.x509cert` parameter will be used for encrypting.\n\n\n### Replay attacks\n\nIn order to avoid replay attacks, you can store the ID of the SAML messages already processed, to avoid processing them twice. Since the Messages expires and will be invalidated due that fact, you don't need to store those IDs longer than the time frame that you currently accepting.\n\nGet the ID of the last processed message with the getLastMessageId method of the Auth object.\n\n## Demo included in the toolkit\nThe Java Toolkit allows you to provide the settings in a unique file as described at the [Settings  section](https://github.com/onelogin/java-saml/#Settings).\n\n#### SP setup\nConfigure the SP part and review the metadata of the IdP and complete the IdP info. Later configure how the toolkit will work enabling/disabling the security settings.\n\n#### IdP setup\n\nOnce the SP is configured, the metadata of the SP is published at the /metadata.jsp url. Based on that info, configure the IdP.\n\n#### How it works\nLets imagine we deploy the jsp example project at *http://localhost:8080/java-saml-tookit-jspsample/*.\n\n1. First time you access to the main view *http://localhost:8080/java-saml-tookit-jspsample/index.jsp*, you can select to login and return to the same view or login and be redirected to  the attribute view (attrs).\n\n2. When you click on a link,:\n\n  2.1. In the first link, we are redirected to the */dologin.jsp* view. An AuthNRequest is sent to the IdP, we authenticate at the IdP and then a Response is sent to the SP, specifically to the Assertion Consumer Service view: /acs.jsp. There the SAMLResponse is validated, the NameID and user attributes extracted and stored in the session. Notice that a RelayState parameter is set to the url that initiated the process, the dologin.jsp url, but we are not redirecting the user to that view, and instead we present user data on the /acs.jsp view.\n\n  2.2. In the second link we are redirected to the */dologin.jsp* view with a 'attrs' GET parameter. An AuthNRequest is sent to the IdP with the /attrs.jsp view as RelayState parameter, we authenticate at the IdP and then a Response is sent to the SP, specifically to the Assertion Consumer Service view: /acs.jsp. There the SAMLResponse is validated, the NameID and user attributes extracted and stored in the session and we are redirected to the RelayState view, the attrs.jsp view where user data is read from session and prompted.\n\n3. The single log out functionality could be tested by 2 ways.\n\n  3.1. SLO Initiated by SP. Click on the \"logout\" link at the SP, after that we are redirected to the /dologout.jsp view where a Logout Request is sent to the IdP, the session at the IdP is closed and replies to the SP a Logout Response (sent to the Single Logout Service endpoint). The SLS endpoint /sls.jsp of the SP process the Logout Response and if is valid, close the user session of the local app. Notice that the SLO Workflow starts and ends at the SP.\n\n  3.2. SLO Initiated by IdP. In this case, the action takes place on the IdP side, the logout process is initiated at the IdP, it sends a Logout Request to the SP (SLS endpoint, /sls.jsp). The SLS endpoint of the SP process the Logout Request and if is valid, close the session of the user at the local app and send a Logout Response to the IdP (to the SLS endpoint of the IdP). The IdP receives the Logout Response, process it and close the session at the IdP. Notice that the SLO Workflow starts and ends at the IdP.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSAML-Toolkits%2Fjava-saml","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FSAML-Toolkits%2Fjava-saml","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSAML-Toolkits%2Fjava-saml/lists"}