Retire stackforge/saml-generator
This commit is contained in:
parent
4aca81fd47
commit
172adf0337
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,4 +0,0 @@
|
||||
.idea/*
|
||||
*.iml
|
||||
dependency-reduced-pom.xml
|
||||
target/*
|
@ -1,4 +0,0 @@
|
||||
[gerrit]
|
||||
host=review.openstack.org
|
||||
port=29418
|
||||
project=stackforge/saml-generator.git
|
176
LICENSE
176
LICENSE
@ -1,176 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
107
README.md
107
README.md
@ -1,107 +0,0 @@
|
||||
SAML Response Generator
|
||||
=======================
|
||||
|
||||
This is a small utility program that makes it easy to generate SAML responses for testing.
|
||||
|
||||
Creating Private and Public Keys for Testing
|
||||
--------------------------------------------
|
||||
|
||||
You will need to generate a private and public key to use for generating saml assertions. The following steps are used for creating the keys:
|
||||
```
|
||||
#create the keypair
|
||||
openssl req -new -x509 -days 3652 -nodes -out saml.crt -keyout saml.pem
|
||||
|
||||
#convert the private key to pkcs8 format
|
||||
openssl pkcs8 -topk8 -inform PEM -outform DER -in saml.pem -out saml.pkcs8 -nocrypt
|
||||
```
|
||||
|
||||
Command line tool
|
||||
-----------------
|
||||
|
||||
You will need to create the jar file in order to use the command line tool. cd to saml-tutorial then run 'mvn package' to create a jar file called 'saml-generator-1.0.jar'. This jar file will be used to create saml assertions.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
java -jar saml-generator-1.0.jar [-domain <arg>] [-issuer <arg>] [-privateKey <arg>] [-publicKey <arg>] [-roles <arg>] [-email <arg>] [-samlAssertionExpirationDays <arg>] [-subject <arg>]
|
||||
|
||||
```
|
||||
-issuer
|
||||
The URI of the issuer for the saml assertion.
|
||||
|
||||
-subject
|
||||
The username of the federated user.
|
||||
|
||||
-domain
|
||||
The domain ID for the federated user.
|
||||
|
||||
-roles
|
||||
A comma separated list of role names for the federated user.
|
||||
|
||||
-email
|
||||
The email address of the federated user.
|
||||
|
||||
-publicKey
|
||||
THe path to the location of the public key to decrypt assertions
|
||||
|
||||
-privateKey
|
||||
The path to the location of the private key to use to sign assertions
|
||||
|
||||
-samlAssertionExpirationDays
|
||||
How long before the assertion is no longer valid
|
||||
```
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
java -jar saml-generator-1.0.jar -domain 7719 -issuer 'http://some.compnay.com' -privateKey saml.pkcs8 -publicKey saml.crt -roles 'role1' -samlAssertionExpirationDays 5 -subject samlUser1
|
||||
|
||||
Output:
|
||||
```
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:xs="http://www.w3.org/2001/XMLSchema" ID="e1af8c40-8b45-4f25-a8c5-fd99df001c0e" IssueInstant="2014-06-17T20:47:33.381Z" Version="2.0">
|
||||
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://test.rackspace.com</saml2:Issuer>
|
||||
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
||||
<ds:SignedInfo>
|
||||
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
||||
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
||||
<ds:Reference URI="#e1af8c40-8b45-4f25-a8c5-fd99df001c0e">
|
||||
<ds:Transforms>
|
||||
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
||||
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
|
||||
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="xs"/>
|
||||
</ds:Transform>
|
||||
</ds:Transforms>
|
||||
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
||||
<ds:DigestValue>fufQ5g8YHPZVT4tX6Xx4LfYO588=</ds:DigestValue>
|
||||
</ds:Reference>
|
||||
</ds:SignedInfo>
|
||||
<ds:SignatureValue>LlYniaVX8EXAZDvKP396IDpDm31mJf3T8HKh4NroTSPWqEjmcN2Wj32QBjSCpzXtE7bhVoRIQQRDRWzAbMjR0gjuy6NK0z1vBQDi4iwuRM6Y+sgsDAqB9wT4h4yi6J7cjnUdNi83VRVYF3F7zVjCq//mDQVkyp+rkhC0Lkxe2kM=</ds:SignatureValue>
|
||||
</ds:Signature>
|
||||
<saml2p:Status>
|
||||
<saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
|
||||
</saml2p:Status>
|
||||
<saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="4ee2be6a-8075-40a2-ba89-cf0991880af2" IssueInstant="2014-06-17T20:47:33.379Z" Version="2.0">
|
||||
<saml2:Issuer>http://some.compnay.com</saml2:Issuer>
|
||||
<saml2:Subject>
|
||||
<saml2:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">samlUser</saml2:NameID>
|
||||
<saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
|
||||
<saml2:SubjectConfirmationData NotOnOrAfter="2014-06-22T20:47:33.373Z"/>
|
||||
</saml2:SubjectConfirmation>
|
||||
</saml2:Subject>
|
||||
<saml2:AuthnStatement AuthnInstant="2014-06-17T20:47:31.963Z">
|
||||
<saml2:AuthnContext>
|
||||
<saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef>
|
||||
</saml2:AuthnContext>
|
||||
</saml2:AuthnStatement>
|
||||
<saml2:AttributeStatement>
|
||||
<saml2:Attribute Name="roles">
|
||||
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">role1</saml2:AttributeValue>
|
||||
</saml2:Attribute>
|
||||
<saml2:Attribute Name="domain">
|
||||
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">14309</saml2:AttributeValue>
|
||||
</saml2:Attribute>
|
||||
</saml2:AttributeStatement>
|
||||
</saml2:Assertion>
|
||||
</saml2p:Response>
|
||||
```
|
7
README.rst
Normal file
7
README.rst
Normal file
@ -0,0 +1,7 @@
|
||||
This project is no longer maintained.
|
||||
|
||||
The contents of this repository are still available in the Git source code
|
||||
management system. To see the contents of this repository before it reached
|
||||
its end of life, please check out the previous commit with
|
||||
"git checkout HEAD^1".
|
||||
|
124
pom.xml
124
pom.xml
@ -1,124 +0,0 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.rackspace.saml</groupId>
|
||||
<artifactId>saml-generator</artifactId>
|
||||
<version>1.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- Configure jar plugin -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addClasspath>true</addClasspath>
|
||||
<classpathPrefix>lib/</classpathPrefix>
|
||||
<mainClass>com.rackspace.saml.Main</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>default-package</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>2.5.1</version>
|
||||
</plugin>
|
||||
|
||||
<!-- Ensure all dependent jars are packaged together -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<transformers>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<mainClass>com.rackspace.saml.Main</mainClass>
|
||||
</transformer>
|
||||
</transformers>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
<excludes>
|
||||
<exclude>META-INF/*.SF</exclude>
|
||||
<exclude>META-INF/*.DSA</exclude>
|
||||
<exclude>META-INF/*.RSA</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<!-- slf4j -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.7</version>
|
||||
</dependency>
|
||||
|
||||
<!-- JUnit -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.8.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Hamcrest -->
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-all</artifactId>
|
||||
<version>1.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Jaxb -->
|
||||
<dependency>
|
||||
<groupId>javax.xml</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
<version>2.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Open SAML -->
|
||||
<dependency>
|
||||
<groupId>org.opensaml</groupId>
|
||||
<artifactId>opensaml</artifactId>
|
||||
<version>2.5.3</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Command Line Tool -->
|
||||
<dependency>
|
||||
<groupId>commons-cli</groupId>
|
||||
<artifactId>commons-cli</artifactId>
|
||||
<version>1.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -1,52 +0,0 @@
|
||||
package com.rackspace.saml;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
|
||||
import org.opensaml.xml.security.credential.Credential;
|
||||
import org.opensaml.xml.security.x509.BasicX509Credential;
|
||||
|
||||
public class CertManager {
|
||||
|
||||
/**
|
||||
* gets credential used to sign saml assertionts that are produced. This method
|
||||
* assumes the cert and pkcs formatted primary key are on file system. this data
|
||||
* could be stored elsewhere e.g keystore
|
||||
*
|
||||
* a credential is used to sign saml response, and includes the private key
|
||||
* as well as a cert for the public key
|
||||
*
|
||||
* @return
|
||||
* @throws Throwable
|
||||
*/
|
||||
public Credential getSigningCredential(String publicKeyLocation, String privateKeyLocation) throws Throwable {
|
||||
// create public key (cert) portion of credential
|
||||
InputStream inStream = new FileInputStream(publicKeyLocation);
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
X509Certificate publicKey = (X509Certificate)cf.generateCertificate(inStream);
|
||||
inStream.close();
|
||||
|
||||
// create private key
|
||||
RandomAccessFile raf = new RandomAccessFile(privateKeyLocation, "r");
|
||||
byte[] buf = new byte[(int)raf.length()];
|
||||
raf.readFully(buf);
|
||||
raf.close();
|
||||
|
||||
PKCS8EncodedKeySpec kspec = new PKCS8EncodedKeySpec(buf);
|
||||
KeyFactory kf = KeyFactory.getInstance("RSA");
|
||||
PrivateKey privateKey = kf.generatePrivate(kspec);
|
||||
|
||||
// create credential and initialize
|
||||
BasicX509Credential credential = new BasicX509Credential();
|
||||
credential.setEntityCertificate(publicKey);
|
||||
credential.setPrivateKey(privateKey);
|
||||
|
||||
return credential;
|
||||
}
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
package com.rackspace.saml;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.CommandLineParser;
|
||||
import org.apache.commons.cli.GnuParser;
|
||||
import org.apache.commons.cli.HelpFormatter;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.joda.time.DateTime;
|
||||
import org.opensaml.saml2.core.Response;
|
||||
import org.opensaml.saml2.core.impl.ResponseMarshaller;
|
||||
import org.opensaml.xml.util.XMLHelper;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
HashMap<String, List<String>> attributes = new HashMap<String, List<String>>();
|
||||
String issuer = null;
|
||||
String subject = null;
|
||||
String privateKey = null;
|
||||
String publicKey = null;
|
||||
Integer samlAssertionExpirationDays = null;
|
||||
|
||||
Options options = new Options();
|
||||
options.addOption("issuer", true, "Issuer for saml assertion");
|
||||
options.addOption("subject", true, "Subject of saml assertion");
|
||||
options.addOption("email", true, "Email associated with the subject");
|
||||
options.addOption("domain", true, "Domain attribute");
|
||||
options.addOption("roles", true, "Comma separated list of roles");
|
||||
options.addOption("publicKey", true, "Location of public key to decrypt assertion");
|
||||
options.addOption("privateKey", true, "Location or private key use to sign assertion");
|
||||
options.addOption("samlAssertionExpirationDays", true, "How long before assertion is no longer valid. Can be negative.");
|
||||
|
||||
CommandLineParser parser = new GnuParser();
|
||||
CommandLine cmd = parser.parse(options, args);
|
||||
|
||||
if (args.length == 0) {
|
||||
HelpFormatter formatter = new HelpFormatter();
|
||||
formatter.printHelp( "saml-util-1.0", options, true);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
issuer = cmd.getOptionValue("issuer");
|
||||
subject = cmd.getOptionValue("subject");
|
||||
privateKey = cmd.getOptionValue("privateKey");
|
||||
publicKey = cmd.getOptionValue("publicKey");
|
||||
|
||||
samlAssertionExpirationDays = cmd.getOptionValue("samlAssertionExpirationDays") != null ? Integer.valueOf(cmd.getOptionValue("samlAssertionExpirationDays")) : null;
|
||||
|
||||
if (cmd.getOptionValue("domain") != null)
|
||||
attributes.put("domain", Arrays.asList(cmd.getOptionValue("domain")));
|
||||
|
||||
if (cmd.getOptionValue("roles") != null)
|
||||
attributes.put("roles", Arrays.asList(cmd.getOptionValue("roles").split(",")));
|
||||
|
||||
if (cmd.getOptionValue("email") != null)
|
||||
attributes.put("email", Arrays.asList(cmd.getOptionValue("email")));
|
||||
|
||||
SamlAssertionProducer producer = new SamlAssertionProducer();
|
||||
producer.setPrivateKeyLocation(privateKey);
|
||||
producer.setPublicKeyLocation(publicKey);
|
||||
|
||||
Response responseInitial = producer.createSAMLResponse(subject, new DateTime(), "password", attributes, issuer, samlAssertionExpirationDays);
|
||||
|
||||
ResponseMarshaller marshaller = new ResponseMarshaller();
|
||||
Element element = marshaller.marshall(responseInitial);
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
XMLHelper.writeNode(element, baos);
|
||||
String responseStr = new String(baos.toByteArray());
|
||||
|
||||
System.out.println(responseStr);
|
||||
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,267 +0,0 @@
|
||||
package com.rackspace.saml;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.opensaml.DefaultBootstrap;
|
||||
import org.opensaml.common.SAMLVersion;
|
||||
import org.opensaml.saml2.core.Assertion;
|
||||
import org.opensaml.saml2.core.Attribute;
|
||||
import org.opensaml.saml2.core.AttributeStatement;
|
||||
import org.opensaml.saml2.core.AttributeValue;
|
||||
import org.opensaml.saml2.core.AuthnContext;
|
||||
import org.opensaml.saml2.core.AuthnContextClassRef;
|
||||
import org.opensaml.saml2.core.AuthnRequest;
|
||||
import org.opensaml.saml2.core.AuthnStatement;
|
||||
import org.opensaml.saml2.core.Issuer;
|
||||
import org.opensaml.saml2.core.NameID;
|
||||
import org.opensaml.saml2.core.Response;
|
||||
import org.opensaml.saml2.core.Status;
|
||||
import org.opensaml.saml2.core.StatusCode;
|
||||
import org.opensaml.saml2.core.Subject;
|
||||
import org.opensaml.saml2.core.SubjectConfirmation;
|
||||
import org.opensaml.saml2.core.SubjectConfirmationData;
|
||||
import org.opensaml.saml2.core.impl.AssertionBuilder;
|
||||
import org.opensaml.saml2.core.impl.AttributeBuilder;
|
||||
import org.opensaml.saml2.core.impl.AttributeStatementBuilder;
|
||||
import org.opensaml.saml2.core.impl.AuthnContextBuilder;
|
||||
import org.opensaml.saml2.core.impl.AuthnContextClassRefBuilder;
|
||||
import org.opensaml.saml2.core.impl.AuthnStatementBuilder;
|
||||
import org.opensaml.saml2.core.impl.IssuerBuilder;
|
||||
import org.opensaml.saml2.core.impl.NameIDBuilder;
|
||||
import org.opensaml.saml2.core.impl.ResponseBuilder;
|
||||
import org.opensaml.saml2.core.impl.ResponseMarshaller;
|
||||
import org.opensaml.saml2.core.impl.StatusBuilder;
|
||||
import org.opensaml.saml2.core.impl.StatusCodeBuilder;
|
||||
import org.opensaml.saml2.core.impl.SubjectBuilder;
|
||||
import org.opensaml.saml2.core.impl.SubjectConfirmationBuilder;
|
||||
import org.opensaml.saml2.core.impl.SubjectConfirmationDataBuilder;
|
||||
import org.opensaml.xml.schema.XSString;
|
||||
import org.opensaml.xml.schema.impl.XSStringBuilder;
|
||||
import org.opensaml.xml.signature.Signature;
|
||||
import org.opensaml.xml.signature.SignatureConstants;
|
||||
import org.opensaml.xml.signature.Signer;
|
||||
import org.opensaml.xml.signature.impl.SignatureBuilder;
|
||||
import org.opensaml.xml.util.XMLHelper;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
|
||||
public class SamlAssertionProducer {
|
||||
|
||||
private String privateKeyLocation;
|
||||
private String publicKeyLocation;
|
||||
private CertManager certManager = new CertManager();
|
||||
|
||||
public Response createSAMLResponse(final String subjectId, final DateTime authenticationTime,
|
||||
final String credentialType, final HashMap<String, List<String>> attributes, String issuer, Integer samlAssertionDays) {
|
||||
|
||||
try {
|
||||
DefaultBootstrap.bootstrap();
|
||||
|
||||
Signature signature = createSignature();
|
||||
Status status = createStatus();
|
||||
Issuer responseIssuer = null;
|
||||
Issuer assertionIssuer = null;
|
||||
Subject subject = null;
|
||||
AttributeStatement attributeStatement = null;
|
||||
|
||||
if (issuer != null) {
|
||||
responseIssuer = createIssuer(issuer);
|
||||
assertionIssuer = createIssuer(issuer);
|
||||
}
|
||||
|
||||
if (subjectId != null) {
|
||||
subject = createSubject(subjectId, samlAssertionDays);
|
||||
}
|
||||
|
||||
if (attributes != null && attributes.size() != 0) {
|
||||
attributeStatement = createAttributeStatement(attributes);
|
||||
}
|
||||
|
||||
AuthnStatement authnStatement = createAuthnStatement(authenticationTime);
|
||||
|
||||
Assertion assertion = createAssertion(new DateTime(), subject, assertionIssuer, authnStatement, attributeStatement);
|
||||
|
||||
Response response = createResponse(new DateTime(), responseIssuer, status, assertion);
|
||||
response.setSignature(signature);
|
||||
|
||||
ResponseMarshaller marshaller = new ResponseMarshaller();
|
||||
Element element = marshaller.marshall(response);
|
||||
|
||||
if (signature != null) {
|
||||
Signer.signObject(signature);
|
||||
}
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
XMLHelper.writeNode(element, baos);
|
||||
|
||||
return response;
|
||||
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getPrivateKeyLocation() {
|
||||
return privateKeyLocation;
|
||||
}
|
||||
|
||||
public void setPrivateKeyLocation(String privateKeyLocation) {
|
||||
this.privateKeyLocation = privateKeyLocation;
|
||||
}
|
||||
|
||||
public String getPublicKeyLocation() {
|
||||
return publicKeyLocation;
|
||||
}
|
||||
|
||||
public void setPublicKeyLocation(String publicKeyLocation) {
|
||||
this.publicKeyLocation = publicKeyLocation;
|
||||
}
|
||||
|
||||
private Response createResponse(final DateTime issueDate, Issuer issuer, Status status, Assertion assertion) {
|
||||
ResponseBuilder responseBuilder = new ResponseBuilder();
|
||||
Response response = responseBuilder.buildObject();
|
||||
response.setID(UUID.randomUUID().toString());
|
||||
response.setIssueInstant(issueDate);
|
||||
response.setVersion(SAMLVersion.VERSION_20);
|
||||
response.setIssuer(issuer);
|
||||
response.setStatus(status);
|
||||
response.getAssertions().add(assertion);
|
||||
return response;
|
||||
}
|
||||
|
||||
private Assertion createAssertion(final DateTime issueDate, Subject subject, Issuer issuer, AuthnStatement authnStatement,
|
||||
AttributeStatement attributeStatement) {
|
||||
AssertionBuilder assertionBuilder = new AssertionBuilder();
|
||||
Assertion assertion = assertionBuilder.buildObject();
|
||||
assertion.setID(UUID.randomUUID().toString());
|
||||
assertion.setIssueInstant(issueDate);
|
||||
assertion.setSubject(subject);
|
||||
assertion.setIssuer(issuer);
|
||||
|
||||
if (authnStatement != null)
|
||||
assertion.getAuthnStatements().add(authnStatement);
|
||||
|
||||
if (attributeStatement != null)
|
||||
assertion.getAttributeStatements().add(attributeStatement);
|
||||
|
||||
return assertion;
|
||||
}
|
||||
|
||||
private Issuer createIssuer(final String issuerName) {
|
||||
// create Issuer object
|
||||
IssuerBuilder issuerBuilder = new IssuerBuilder();
|
||||
Issuer issuer = issuerBuilder.buildObject();
|
||||
issuer.setValue(issuerName);
|
||||
return issuer;
|
||||
}
|
||||
|
||||
private Subject createSubject(final String subjectId, final Integer samlAssertionDays) {
|
||||
DateTime currentDate = new DateTime();
|
||||
if (samlAssertionDays != null)
|
||||
currentDate = currentDate.plusDays(samlAssertionDays);
|
||||
|
||||
// create name element
|
||||
NameIDBuilder nameIdBuilder = new NameIDBuilder();
|
||||
NameID nameId = nameIdBuilder.buildObject();
|
||||
nameId.setValue(subjectId);
|
||||
nameId.setFormat("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent");
|
||||
|
||||
SubjectConfirmationDataBuilder dataBuilder = new SubjectConfirmationDataBuilder();
|
||||
SubjectConfirmationData subjectConfirmationData = dataBuilder.buildObject();
|
||||
subjectConfirmationData.setNotOnOrAfter(currentDate);
|
||||
|
||||
SubjectConfirmationBuilder subjectConfirmationBuilder = new SubjectConfirmationBuilder();
|
||||
SubjectConfirmation subjectConfirmation = subjectConfirmationBuilder.buildObject();
|
||||
subjectConfirmation.setMethod("urn:oasis:names:tc:SAML:2.0:cm:bearer");
|
||||
subjectConfirmation.setSubjectConfirmationData(subjectConfirmationData);
|
||||
|
||||
// create subject element
|
||||
SubjectBuilder subjectBuilder = new SubjectBuilder();
|
||||
Subject subject = subjectBuilder.buildObject();
|
||||
subject.setNameID(nameId);
|
||||
subject.getSubjectConfirmations().add(subjectConfirmation);
|
||||
|
||||
return subject;
|
||||
}
|
||||
|
||||
private AuthnStatement createAuthnStatement(final DateTime issueDate) {
|
||||
// create authcontextclassref object
|
||||
AuthnContextClassRefBuilder classRefBuilder = new AuthnContextClassRefBuilder();
|
||||
AuthnContextClassRef classRef = classRefBuilder.buildObject();
|
||||
classRef.setAuthnContextClassRef("urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport");
|
||||
|
||||
// create authcontext object
|
||||
AuthnContextBuilder authContextBuilder = new AuthnContextBuilder();
|
||||
AuthnContext authnContext = authContextBuilder.buildObject();
|
||||
authnContext.setAuthnContextClassRef(classRef);
|
||||
|
||||
// create authenticationstatement object
|
||||
AuthnStatementBuilder authStatementBuilder = new AuthnStatementBuilder();
|
||||
AuthnStatement authnStatement = authStatementBuilder.buildObject();
|
||||
authnStatement.setAuthnInstant(issueDate);
|
||||
authnStatement.setAuthnContext(authnContext);
|
||||
|
||||
return authnStatement;
|
||||
}
|
||||
|
||||
private AttributeStatement createAttributeStatement(HashMap<String, List<String>> attributes) {
|
||||
// create authenticationstatement object
|
||||
AttributeStatementBuilder attributeStatementBuilder = new AttributeStatementBuilder();
|
||||
AttributeStatement attributeStatement = attributeStatementBuilder.buildObject();
|
||||
|
||||
AttributeBuilder attributeBuilder = new AttributeBuilder();
|
||||
if (attributes != null) {
|
||||
for (Map.Entry<String, List<String>> entry : attributes.entrySet()) {
|
||||
Attribute attribute = attributeBuilder.buildObject();
|
||||
attribute.setName(entry.getKey());
|
||||
|
||||
for (String value : entry.getValue()) {
|
||||
XSStringBuilder stringBuilder = new XSStringBuilder();
|
||||
XSString attributeValue = stringBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, XSString.TYPE_NAME);
|
||||
attributeValue.setValue(value);
|
||||
attribute.getAttributeValues().add(attributeValue);
|
||||
}
|
||||
|
||||
attributeStatement.getAttributes().add(attribute);
|
||||
}
|
||||
}
|
||||
|
||||
return attributeStatement;
|
||||
}
|
||||
|
||||
private Status createStatus() {
|
||||
StatusCodeBuilder statusCodeBuilder = new StatusCodeBuilder();
|
||||
StatusCode statusCode = statusCodeBuilder.buildObject();
|
||||
statusCode.setValue(StatusCode.SUCCESS_URI);
|
||||
|
||||
StatusBuilder statusBuilder = new StatusBuilder();
|
||||
Status status = statusBuilder.buildObject();
|
||||
status.setStatusCode(statusCode);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
private Signature createSignature() throws Throwable {
|
||||
if (publicKeyLocation != null && privateKeyLocation != null) {
|
||||
SignatureBuilder builder = new SignatureBuilder();
|
||||
Signature signature = builder.buildObject();
|
||||
signature.setSigningCredential(certManager.getSigningCredential(publicKeyLocation, privateKeyLocation));
|
||||
signature.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1);
|
||||
signature.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
|
||||
|
||||
return signature;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user