Another one of my 'I was trying to do this and having no luck finding solutions' posts, so I'll post my solution and hopefully it will help someone else in the same predicament.
This time I was working on a .NET MVC project, and trying to do some reporting. Basically it's a simple app that records users' steps-per-day. The users are assigned to teams and I wanted to create a page that showed the ranking of the different teams each month based on their total number of steps. As you can imagine, I had three tables. tblTeams, tblUsers, and tblSteps. So, my problem was, I have a model built using Linq to SQL, and it works fine if you're working with one of the objects that relates to its table. But, in this case I just wanted to do a simple join query, with some grouping, and return that to the view to create an html table of the different teams and their totals. So, here's how I made it work:
First off, I created a new very simple model containing the class to hold the results of the query:
namespace StepsChallenge.Models
{
public class TeamTotalsModel
{
public string TeamName { get; set; }
public string Sum { get; set; }
}
}
Then, in my view I added a reference to this model:
Inherits="System.Web.Mvc.ViewPage<IEnumerable<StepsChallenge.Models.TeamTotalsModel>>"
OK, now we're wired-up. On to the data.
I wrote a Linq to SQL query that looked like this in my controller and passed it into an instance of the model class:
public class HomeController : Controller
{
public ActionResult Index()
{
//get monthly steps for the teams
var allTeamsMonthlySteps = from stepRecord in homeModel.Steps
join userRecord in homeModel.Users
on stepRecord.EmpID equals userRecord.EmpID
join teamRecord in homeModel.Teams
on userRecord.TeamID equals teamRecord.TeamID
where stepRecord.Date.Month == DateTime.Now.Month
group stepRecord by teamRecord.TeamName into result
orderby result.Key ascending
select new TeamTotalsModel
{
TeamName = result.Key.ToString(),
Sum = result.Sum(r => r.Steps).ToString()
};
return View(allTeamsMonthlySteps);
}
}
Then finally, back at the view I wrote something like this:
<table>
<tr>
<th>
TeamName
</th>
<th>
Sum
</th>
</tr>
<% foreach (var item in Model) { %>
<tr>
<td>
<%= Html.Encode(item.TeamName) %>
</td>
<td>
<%= Html.Encode(item.Sum) %>
</td>
</tr>
<% } %>
</table>
So, this isn't all that complicated, but the problem I was having is that every search I did on almost every piece of this pointed me back to all the Visual Studio drag-and-drop BS for working with Linq to SQL models where there's a one-to-one relationship between objects and tables. And, I couldn't find much help at all on writing a Linq to SQL query with multiple joins, grouping, and 'where' clauses, all together, and passing it to the view.
Anyway, maybe some poor slob like me will stumble across this and find what he needs. Until next time.
Thursday, January 13, 2011
Friday, December 3, 2010
Apache configuration for SimpleSAMLphp on OS X Snow Leopard
I needed to do some testing with the SimpleSAMLphp (http://simplesamlphp.org/) application today. I’m not a php developer so my mac wasn’t setup to run php in Apache. That part was trivially simple to setup, but I ran into problems trying to get the SimpleSAMLphp application running in a configuration that made sense to me. What I wanted to do was install the application into my /Sites/ directory, and create another directory under /Sites/ that would act as the php site that uses it. It may seem odd to install the app in the sites directory, but I just wanted to keep the two together. So, the directory structure looked like this:
~/Sites/simplesamlphp/
~/Sites/phpsite/
Then, I wanted to change my Apache configuration so that http://localhost/ would remain the same (pointing at /Library/WebServer/Documents/), http://phpsite/ would point to ~/Sites/phpsite/, and http://phpsite/simplesaml would point to ~/Sites/simplesamlphp/www.
It took some trial and error, but I ended up with these configurations:
First I uncommented the following line in the /etc/apache2/httpd.conf file:
Include /private/etc/apache2/extra/httpd-vhosts.conf
Then I went to that file and changed the following line from this:
NameVirtualHost *:80
to this:
NameVirtualHost 127.0.0.1:80
and, added this:
<VirtualHost phpsite>
DocumentRoot "/Users/sysadmin/Sites/phpsite"
ServerName phpsite
<Directory "/Users/sysadmin/Sites/phpsite">
Options FollowSymLinks MultiViews Includes
AllowOverride All
Order allow,deny
Allow from all
</Directory>
Alias /simplesaml /Users/sysadmin/Sites/simplesamlphp/www
</VirtualHost>
Then I went to my /etc/hosts file and added this line:
127.0.0.1 phpsite
Then, a quick Apache restart and everything was running smoothly.
http://localhost - still points to /Library/WebServer/Documents
http://localhost/~sysadmin/ - still points to ~/Sites/
http://phpsite - points to ~/Sites/phpsite
http://phpsite/simplesaml - points to ~/Sites/simplesamlphp/www
Obviously you wouldn’t want to configure it this way if this was a production server, but when I’m doing development work like this I’d prefer to keep everything under my own home folder.
~/Sites/simplesamlphp/
~/Sites/phpsite/
Then, I wanted to change my Apache configuration so that http://localhost/ would remain the same (pointing at /Library/WebServer/Documents/), http://phpsite/ would point to ~/Sites/phpsite/, and http://phpsite/simplesaml would point to ~/Sites/simplesamlphp/www.
It took some trial and error, but I ended up with these configurations:
First I uncommented the following line in the /etc/apache2/httpd.conf file:
Include /private/etc/apache2/extra/httpd-vhosts.conf
Then I went to that file and changed the following line from this:
NameVirtualHost *:80
to this:
NameVirtualHost 127.0.0.1:80
and, added this:
<VirtualHost phpsite>
DocumentRoot "/Users/sysadmin/Sites/phpsite"
ServerName phpsite
<Directory "/Users/sysadmin/Sites/phpsite">
Options FollowSymLinks MultiViews Includes
AllowOverride All
Order allow,deny
Allow from all
</Directory>
Alias /simplesaml /Users/sysadmin/Sites/simplesamlphp/www
</VirtualHost>
Then I went to my /etc/hosts file and added this line:
127.0.0.1 phpsite
Then, a quick Apache restart and everything was running smoothly.
http://localhost - still points to /Library/WebServer/Documents
http://localhost/~sysadmin/ - still points to ~/Sites/
http://phpsite - points to ~/Sites/phpsite
http://phpsite/simplesaml - points to ~/Sites/simplesamlphp/www
Obviously you wouldn’t want to configure it this way if this was a production server, but when I’m doing development work like this I’d prefer to keep everything under my own home folder.
Thursday, February 18, 2010
DRY up your content using ASP.NET user controls
I was doing a little code-cleanup on an app I support this week. I was trying to find some places where I could implement the DRY (don't repeat yourself) methodology. It was fairly easy picking, because this app is leaning a little more toward the RYE (repeat yourself everywhere) methodology. Anyway, I came up with a way to use ASP.NET User Controls in a project to move some of that repetitive content out of the individual pages, and into a centralized place.
This may not be anything new to anyone, but I had never thought of using a user control for content. I created two controls, one for some contact information that was used on every page (pointing to different departments in the company), and one to encapsulate some page framework that needed to be slightly different depending on where the application was deployed (I was able to put this logic into the user control and read the location from the web.config).
The contact control renders asp labels to display content on the page, and the framework control renders standard divs. The code had to be slightly different in the code-behind to search for the controls, but once you set up the controls this way, you wouldn't need to ever change the c# code if you wanted to add a new label or div to the .ascx file.
Anyway, like I said I just came up with this idea earlier this week, but I'm anxious to add it to the toolkit. I'm already thinking of some more uses for this. You could perhaps have a 'snippets.ascx' file that had all the reusable content, and enclose each piece in a div. Then all you'd have to do is call the user control in your app with the name of the div you wanted to render.
i.e. <userControl:Snippets ID="SnippetControl" DivID="WhateverDivIwantToShow" runat="server" />
I'll add the relevant code. Should be easy to see what I'm talking about.
------------------------------------------------------------------
front-end for user control to deterministically expose asp label controls:
<asp:Label ID="Payroll" Visible="false" runat="server">
<p>
For questions regarding the content of your documents contact the Payroll Department at 555-5555.
</p>
</asp:Label>
<asp:Label ID="HelpDesk" Visible="false" runat="server">
<p>
For technical questions or support please contact the Help Desk at 555-5555.
</p>
</asp:Label>
c# code-behind for user control:
public partial class Contact : System.Web.UI.UserControl
{
string strLabelID = string.Empty;
public string LabelID
{
get
{
return strLabelID;
}
set
{
strLabelID = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
foreach (Control ctrl in Controls)
{
if (ctrl is Label)
{
if (ctrl.ID == strLabelID)
{
ctrl.Visible = true;
}
}
}
}
}
usage of control:
<ucContact:Contact ID="PayrollContact" LabelID="Payroll" runat="server" />
<ucContact:Contact ID="HelpDeskContact" LabelID="HelpDesk" runat="server" />
------------------------------------------------------------------------------
Another Example:
front-end for user control to deterministically expose generic div elements:
<div id="Header" visible="false" runat="server">
put stuff in here for the header
</div>
<div id="Footer" visible="false" runat="server">
put stuff in here for the footer
</div>
c# code-behind for user control:
public partial class PortalFramework : System.Web.UI.UserControl
{
private string strDivID = string.Empty;
public string DivID
{
get
{
return strDivID;
}
set
{
strDivID = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
foreach (Control ctrl in Controls)
{
if (ctrl is HtmlGenericControl)
{
if (ctrl.ID == strDivID)
{
ctrl.Visible = true;
}
}
}
}
}
usage of control:
<ucFramework:PortalFramework ID="PortalFrameworkHeader" runat="server" DivID="Header" />
<ucFramework:PortalFramework ID="PortalFrameworkFooter" runat="server" DivID="Footer" />
Friday, December 18, 2009
Tuesday, September 22, 2009
TestDisk to the rescue!
Last night I had a serious problem with my netbook. I'm running Ubuntu on a Dell mini with most of the data on an SD card. Anyway, I think the SD card got messed up when the machine went into hibernation, and when I opened the lid I was getting cryptic messages about the drive not being able to mount. I tried the usual tools, fsck, dumpe2fs, gpart, etc. Nothing doing. Everything that was working for other people wasn't working for me... Kept researching the messages I was getting from the various tools:
Block bitmap for group 1 not in group
Bad Magic Number in Superblock
Disk doesn't contain a valid partition table
etc. etc.
The last one ended up being the clue. Found a utility called TestDisk and it had me fixed up in less than 15 minutes.
http://www.cgsecurity.org/wiki/TestDisk_Step_By_Step
It was able to figure out the partitions based on the good data still on the disk. Then it was just a matter of using the tool to rewrite the partition table and I was back in business!
Block bitmap for group 1 not in group
Bad Magic Number in Superblock
Disk doesn't contain a valid partition table
etc. etc.
The last one ended up being the clue. Found a utility called TestDisk and it had me fixed up in less than 15 minutes.
http://www.cgsecurity.org/wiki/TestDisk_Step_By_Step
It was able to figure out the partitions based on the good data still on the disk. Then it was just a matter of using the tool to rewrite the partition table and I was back in business!
Wednesday, July 22, 2009
Receiving a SAML Response with a Java servlet
As an addendum to my previous post, if you need to receive a SAML Response in a Java servlet using OpenSAML you can use this code. This is, obviously, more likely than needing to create a Response object from an XML file. The 'request' variable is just an input to the processRequest method on the servlet.
import org.opensaml.ws.message.MessageContext;
import org.opensaml.ws.transport.http.HttpServletRequestAdapter;
import org.opensaml.common.binding.BasicSAMLMessageContext;
import org.opensaml.saml2.binding.decoding.HTTPPostDecoder;
import org.opensaml.saml2.core.Response;
//get the message context
MessageContext messageContext = new BasicSAMLMessageContext();
messageContext.setInboundMessageTransport(new HttpServletRequestAdapter(request));
HTTPPostDecoder samlMessageDecoder = new HTTPPostDecoder();
samlMessageDecoder.decode(messageContext);
//get the SAML Response
Response samlResponse = (Response)messageContext.getInboundMessage();
import org.opensaml.ws.message.MessageContext;
import org.opensaml.ws.transport.http.HttpServletRequestAdapter;
import org.opensaml.common.binding.BasicSAMLMessageContext;
import org.opensaml.saml2.binding.decoding.HTTPPostDecoder;
import org.opensaml.saml2.core.Response;
//get the message context
MessageContext messageContext = new BasicSAMLMessageContext();
messageContext.setInboundMessageTransport(new HttpServletRequestAdapter(request));
HTTPPostDecoder samlMessageDecoder = new HTTPPostDecoder();
samlMessageDecoder.decode(messageContext);
//get the SAML Response
Response samlResponse = (Response)messageContext.getInboundMessage();
Monday, July 6, 2009
Processing SAML in Java using OpenSAML
I'm currently doing all of my SAML 2.0 work in a .NET environment, but I wanted to verify my SAML in Java too so I created this tester utilizing OpenSAML. It certainly isn't pretty at this point, and I'm certainly not saying it represents any best-practices, but I'm going to post it in its current state because I think it illustrates some useful things. It's basically just unmarshalling xml to an OpenSAML response object, verifying the signature on the response, and decrypting an assertion. Nothing terribly mind-blowing, but it might prove useful to someone.
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.List;
import javax.xml.namespace.QName;
import javax.xml.validation.Schema;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.PublicKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.X509EncodedKeySpec;
import org.opensaml.DefaultBootstrap;
import org.opensaml.common.xml.SAMLSchemaBuilder;
import org.opensaml.saml2.core.Assertion;
import org.opensaml.saml2.core.Attribute;
import org.opensaml.saml2.core.AttributeStatement;
import org.opensaml.saml2.core.Response;
import org.opensaml.saml2.encryption.Decrypter;
import org.opensaml.xml.Configuration;
import org.opensaml.xml.XMLObject;
import org.opensaml.xml.encryption.DecryptionException;
import org.opensaml.xml.encryption.InlineEncryptedKeyResolver;
import org.opensaml.xml.io.Unmarshaller;
import org.opensaml.xml.parse.BasicParserPool;
import org.opensaml.xml.security.keyinfo.StaticKeyInfoCredentialResolver;
import org.opensaml.xml.security.x509.BasicX509Credential;
import org.opensaml.xml.signature.Signature;
import org.opensaml.xml.signature.SignatureValidator;
import org.opensaml.xml.validation.ValidationException;
public class Tester
{
public static void main(String[] args)
{
try
{
//initialize the opensaml library
DefaultBootstrap.bootstrap();
Schema schema = SAMLSchemaBuilder.getSAML11Schema();
//get parser pool manager
BasicParserPool parserPoolManager = new BasicParserPool();
parserPoolManager.setNamespaceAware(true);
parserPoolManager.setIgnoreElementContentWhitespace(true);
parserPoolManager.setSchema(schema);
//grab the xml file
File xmlFile = new File("C:\\Documents and Settings\\kgellis\\My Documents\\Eclipse\\Workspace\\MyOpenSamlTester\\Files\\Raw_AssertionEncrypted.xml");
//parse xml file
FileInputStream fileInputStream = new FileInputStream(xmlFile);
InputStream inputStream = fileInputStream;
Document document = parserPoolManager.parse(inputStream);
Element metadataRoot = document.getDocumentElement();
QName qName= new QName(metadataRoot.getNamespaceURI(), metadataRoot.getLocalName(), metadataRoot.getPrefix());
//get an unmarshaller
Unmarshaller unmarshaller = Configuration.getUnmarshallerFactory().getUnmarshaller(qName);
//unmarshall using the document root element
Response response = (Response)unmarshaller.unmarshall(metadataRoot);
//we have the xml unmarshalled to a response object
System.out.println("Response object created");
System.out.println("Issue Instant: " + response.getIssueInstant().toString());
System.out.println("Signature Reference ID: " + response.getSignatureReferenceID().toString());
//grab the certificate file
File certificateFile = new File("C:\\Documents and Settings\\kgellis\\My Documents\\Eclipse\\Workspace\\MyOpenSamlTester\\Files\\Con-wayPublicKey.cer");
//get the certificate from the file
InputStream inputStream2 = new FileInputStream(certificateFile);
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate)certificateFactory.generateCertificate(inputStream2);
inputStream2.close();
//pull out the public key part of the certificate into a KeySpec
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(certificate.getPublicKey().getEncoded());
//get KeyFactory object that creates key objects, specifying RSA
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
System.out.println("Security Provider: " + keyFactory.getProvider().toString());
//generate public key to validate signatures
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
//we have the public key
System.out.println("Public Key created");
//create credentials
BasicX509Credential publicCredential = new BasicX509Credential();
//add public key value
publicCredential.setPublicKey(publicKey);
//create SignatureValidator
SignatureValidator signatureValidator = new SignatureValidator(publicCredential);
//get the signature to validate from the response object
Signature signature = response.getSignature();
//try to validate
try
{
signatureValidator.validate(signature);
}
catch (ValidationException ve)
{
System.out.println("Signature is NOT valid.");
System.out.println(ve.getMessage());
return;
}
//no validation exception was thrown
System.out.println("Signature is valid.");
//start decryption of assertion
//grab the KeyStore file
File keyStoreFile = new File("C:\\Documents and Settings\\kgellis\\My Documents\\Eclipse\\Workspace\\MyOpenSamlTester\\Files\\WWCPrivateKey.jks");
KeyStore keyStore = KeyStore.getInstance("JKS");
//load up a KeyStore
keyStore.load(new FileInputStream(keyStoreFile), "!c3c0ld".toCharArray());
RSAPrivateKey privateKey = (RSAPrivateKey) keyStore.getKey("pvktmp:bd5ba0e0-9718-48ea-b6e6-32cd9c852d76", "!c3c0ld".toCharArray());
//we have the private key
System.out.println("Private Key created");
System.out.println("Private Key Algorithm: " + privateKey.getAlgorithm());
//create the credential
BasicX509Credential decryptionCredential = new BasicX509Credential();
decryptionCredential.setPrivateKey(privateKey);
StaticKeyInfoCredentialResolver skicr = new StaticKeyInfoCredentialResolver(decryptionCredential);
//create a decrypter
Decrypter decrypter = new Decrypter(null, skicr, new InlineEncryptedKeyResolver());
//decrypt the first (and only) assertion
Assertion decryptedAssertion;
try
{
decryptedAssertion = decrypter.decrypt(response.getEncryptedAssertions().get(0));
}
catch (DecryptionException de)
{
System.out.println("Assertion decryption failed.");
System.out.println(de.getMessage());
return;
}
System.out.println("Assertion decryption succeeded.");
System.out.println("Assertion ID: " + decryptedAssertion.getID());
//loop through the nodes to get what we want
List<AttributeStatement> attributeStatements = decryptedAssertion.getAttributeStatements();
for (int i = 0; i < attributeStatements.size(); i++)
{
List<Attribute> attributes = attributeStatements.get(i).getAttributes();
for (int x = 0; x < attributes.size(); x++)
{
String strAttributeName = attributes.get(x).getDOM().getAttribute("Name");
List<XMLObject> attributeValues = attributes.get(x).getAttributeValues();
for (int y = 0; y < attributeValues.size(); y++)
{
String strAttributeValue = attributeValues.get(y).getDOM().getTextContent();
System.out.println(strAttributeName + ": " + strAttributeValue);
}
}
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.List;
import javax.xml.namespace.QName;
import javax.xml.validation.Schema;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.PublicKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.X509EncodedKeySpec;
import org.opensaml.DefaultBootstrap;
import org.opensaml.common.xml.SAMLSchemaBuilder;
import org.opensaml.saml2.core.Assertion;
import org.opensaml.saml2.core.Attribute;
import org.opensaml.saml2.core.AttributeStatement;
import org.opensaml.saml2.core.Response;
import org.opensaml.saml2.encryption.Decrypter;
import org.opensaml.xml.Configuration;
import org.opensaml.xml.XMLObject;
import org.opensaml.xml.encryption.DecryptionException;
import org.opensaml.xml.encryption.InlineEncryptedKeyResolver;
import org.opensaml.xml.io.Unmarshaller;
import org.opensaml.xml.parse.BasicParserPool;
import org.opensaml.xml.security.keyinfo.StaticKeyInfoCredentialResolver;
import org.opensaml.xml.security.x509.BasicX509Credential;
import org.opensaml.xml.signature.Signature;
import org.opensaml.xml.signature.SignatureValidator;
import org.opensaml.xml.validation.ValidationException;
public class Tester
{
public static void main(String[] args)
{
try
{
//initialize the opensaml library
DefaultBootstrap.bootstrap();
Schema schema = SAMLSchemaBuilder.getSAML11Schema();
//get parser pool manager
BasicParserPool parserPoolManager = new BasicParserPool();
parserPoolManager.setNamespaceAware(true);
parserPoolManager.setIgnoreElementContentWhitespace(true);
parserPoolManager.setSchema(schema);
//grab the xml file
File xmlFile = new File("C:\\Documents and Settings\\kgellis\\My Documents\\Eclipse\\Workspace\\MyOpenSamlTester\\Files\\Raw_AssertionEncrypted.xml");
//parse xml file
FileInputStream fileInputStream = new FileInputStream(xmlFile);
InputStream inputStream = fileInputStream;
Document document = parserPoolManager.parse(inputStream);
Element metadataRoot = document.getDocumentElement();
QName qName= new QName(metadataRoot.getNamespaceURI(), metadataRoot.getLocalName(), metadataRoot.getPrefix());
//get an unmarshaller
Unmarshaller unmarshaller = Configuration.getUnmarshallerFactory().getUnmarshaller(qName);
//unmarshall using the document root element
Response response = (Response)unmarshaller.unmarshall(metadataRoot);
//we have the xml unmarshalled to a response object
System.out.println("Response object created");
System.out.println("Issue Instant: " + response.getIssueInstant().toString());
System.out.println("Signature Reference ID: " + response.getSignatureReferenceID().toString());
//grab the certificate file
File certificateFile = new File("C:\\Documents and Settings\\kgellis\\My Documents\\Eclipse\\Workspace\\MyOpenSamlTester\\Files\\Con-wayPublicKey.cer");
//get the certificate from the file
InputStream inputStream2 = new FileInputStream(certificateFile);
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate)certificateFactory.generateCertificate(inputStream2);
inputStream2.close();
//pull out the public key part of the certificate into a KeySpec
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(certificate.getPublicKey().getEncoded());
//get KeyFactory object that creates key objects, specifying RSA
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
System.out.println("Security Provider: " + keyFactory.getProvider().toString());
//generate public key to validate signatures
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
//we have the public key
System.out.println("Public Key created");
//create credentials
BasicX509Credential publicCredential = new BasicX509Credential();
//add public key value
publicCredential.setPublicKey(publicKey);
//create SignatureValidator
SignatureValidator signatureValidator = new SignatureValidator(publicCredential);
//get the signature to validate from the response object
Signature signature = response.getSignature();
//try to validate
try
{
signatureValidator.validate(signature);
}
catch (ValidationException ve)
{
System.out.println("Signature is NOT valid.");
System.out.println(ve.getMessage());
return;
}
//no validation exception was thrown
System.out.println("Signature is valid.");
//start decryption of assertion
//grab the KeyStore file
File keyStoreFile = new File("C:\\Documents and Settings\\kgellis\\My Documents\\Eclipse\\Workspace\\MyOpenSamlTester\\Files\\WWCPrivateKey.jks");
KeyStore keyStore = KeyStore.getInstance("JKS");
//load up a KeyStore
keyStore.load(new FileInputStream(keyStoreFile), "!c3c0ld".toCharArray());
RSAPrivateKey privateKey = (RSAPrivateKey) keyStore.getKey("pvktmp:bd5ba0e0-9718-48ea-b6e6-32cd9c852d76", "!c3c0ld".toCharArray());
//we have the private key
System.out.println("Private Key created");
System.out.println("Private Key Algorithm: " + privateKey.getAlgorithm());
//create the credential
BasicX509Credential decryptionCredential = new BasicX509Credential();
decryptionCredential.setPrivateKey(privateKey);
StaticKeyInfoCredentialResolver skicr = new StaticKeyInfoCredentialResolver(decryptionCredential);
//create a decrypter
Decrypter decrypter = new Decrypter(null, skicr, new InlineEncryptedKeyResolver());
//decrypt the first (and only) assertion
Assertion decryptedAssertion;
try
{
decryptedAssertion = decrypter.decrypt(response.getEncryptedAssertions().get(0));
}
catch (DecryptionException de)
{
System.out.println("Assertion decryption failed.");
System.out.println(de.getMessage());
return;
}
System.out.println("Assertion decryption succeeded.");
System.out.println("Assertion ID: " + decryptedAssertion.getID());
//loop through the nodes to get what we want
List<AttributeStatement> attributeStatements = decryptedAssertion.getAttributeStatements();
for (int i = 0; i < attributeStatements.size(); i++)
{
List<Attribute> attributes = attributeStatements.get(i).getAttributes();
for (int x = 0; x < attributes.size(); x++)
{
String strAttributeName = attributes.get(x).getDOM().getAttribute("Name");
List<XMLObject> attributeValues = attributes.get(x).getAttributeValues();
for (int y = 0; y < attributeValues.size(); y++)
{
String strAttributeValue = attributeValues.get(y).getDOM().getTextContent();
System.out.println(strAttributeName + ": " + strAttributeValue);
}
}
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
Labels:
Decrypting,
Example,
OpenSAML,
Signature,
Unmarshalling
Subscribe to:
Posts (Atom)