Monday Aug 10, 2009

Store & Retrieve Authentication Info with OpenSSO, She & Him

Here are some words on storing authentication information in an OpenSSO session and retrieving it. It assumes that the authentication module extends AMLoginModule and the information is to be shared with a post authentication plug-in.

If the size of the information is small, you can store it in the SSOToken. If the information is security sensitive and not to be readable by the Client SDK, you could encrypt it before setting it in the SSOToken. (Prefixing the property name with am.protected. defines it as NOT readable by the Client SDK.)

After you put the required information from the authentication module into the module principal class, implement the com.sun.identity.authentication.service.AuthenticationPrincipalDataRetriever interface. It has the following method to get the module principal from authSubject, retrieve the required data, and return that data as a Map (key/value pairs).
    /\*\*
     \* Returns the attribute map from the required Authentication module
     \* Principal, to be set in the SSOToken.    
     \*
     \* @param authSubject Authenticated user Subject.
     \* @return the Attribute Map.
     \*/
    Map getAttrMapForAuthenticationModule(Subject authSubject);
The Authentication Service will store this Map in the authenticated SSOToken. A post authentication plug-in can retrieve this data from the SSOToken later. You will need to set your implementation class as a value of the com.sun.identity.authentication.principalDataRetriever property in the OpenSSO configuration data store.

Now here is Zooey Deschanel and M. Ward, plugged in as She & Him. Why Do You Let Me Stay Here? is from their album, Volume 1. I love M (especially his album Transistor Radio), love Zooey (especially as an actress in the ScyFy take on Oz called Tin Man) and also Zooey's sis, Emily (especially as the femme lead on Bones). The video is quirky and endearing and bloody.

Wednesday Jul 23, 2008

Here Comes the Express...OpenSSO and B.T.

Today is the day that Sun announces the OpenSSO Express build, and support and indemnification for OpenSSO. Here are some links with a bunch more information. In honor of this occasion, here comes the B.T. Express with, what else, Express.

Friday May 16, 2008

A Realm is a Bin for Data When You Need to Store

When you deploy OpenSSO in your favorite web container, opensso is configured as the root realm. A realm (under the Access Control tab) is a group of authentication properties and authorization policies that can be associated with a user or group of users, or a collection of protected resources. For example, you can create a realm that groups all servers and services accessed by employees in one region. Within that regional realm, you can group all servers and services accessed regularly by employees in a specific division, such as Human Resources. And even more fine-grained, you can add constraints that allow users to access a particular service from Monday through Friday, 9:00 a.m. to 5:00 p.m.

The root realm is where you configure user (identity) data stores, manage policies and create authentication chains globally. A Realm Administrator can do all these operations in the root realm while the Policy Administrator can only create and manage policies. Under the root realm, you configure sub-realms. Sub-realms enable the following scenarios.
  1. You need an administrator who can create policies for a sub-set of resources only. For example, let's assume you want an administrator to create policies for resources that reside at https://paycheck.sun.com/paycheck.

    1. Create a subrealm under opensso named paycheck.
    2. Under the opensso root realm, create a policy referral with the Resource Name defined as https://paycheck.sun.com/paycheck.
    3. Under the paycheck sub-realm, create a group under Subjects called PaycheckAdmin and select the appropriate privilege (Read and write access only for policy properties) under Privileges.
    4. Modify the appropriate user profile and policy under the sub-realm to reflect this new privilege and the user can then login to the sub-realm and create policies for the defined resources. The sub-realm, in this case, is mainly for the policy administrator to manage the policies for the configured resources.

    By default, paycheck will have the same data store and authentication chains as opensso, its parent realm. If configurations change in the parent realm, a corresponding change in the sub-realm policy might be needed.
  2. You need each sub-realm to have its own set of data stores (identities), authentication chains and policy administrators. Ideally there would be nothing in common between the root and the sub-realm except for the referral policy created under the root realm to delegate all, or a subset of, resources to the sub-realm. With this scenario, users would be created within, and authenticate to, their sub-realm. Agents would also have to be configured to redirect user authentication to the sub-realm.

Regarding performance, the most resource-consuming component of the realm architecture is the persistent searches done using the one data store in the first scenario. This is not really an issue in the second as the searches go to different directories. A guess on the number of sub-realms that can be supported would be about 100 for the first scenario and about 50 for the second.

And although a realm is a bin for data when you need to store, remember that a dream is a wish you heart makes when you're fast asleep. Sing along below but not too loud if you're in an office with the door open.

Oy, did I really just post a music video from Cinderella? Should I have posted something from La Cenerentola to show how couth I am? Maybe but unfortunately I don't understand Italian and thus couldn't find a cute title for this entry a la Rossini.

Tuesday Apr 01, 2008

Setting Up Web Services Security, the Security Token Service and the Tokens

This procedure assumes that you already have an instance of the Glassfish Application Server installed. The following sections must be completed.

  1. Creating Glassfish Domains and Deploying OpenSSO WAR
  2. Deploying the Web Service Provider on Glassfish
  3. Configuring the WSP to Use the Security Token Service
  4. Configuring the Web Service Client (WSC) and the WSP to Use the Security Token Service
  5. Configuring the WSC to Use the Security Token Service

Creating Glassfish Domains and Deploying OpenSSO WAR
  1. Using Glassfish, create two domains - one named wsc and the other wsp.

    1. Create /tmp/passfile with following content:

      AS_ADMIN_ADMINPASSWORD=adminadmin
      AS_ADMIN_MASTERPASSWORD=changeit
    2. Create the domains using the asadmin command line tool located in /GLASSFISH_INSTALL_DIR/bin.

      ./asadmin create-domain --adminuser admin --passwordfile /tmp/passfile --portbase 7000 wsc

      ./asadmin create-domain --adminuser admin --passwordfile /tmp/passfile --portbase 9000 wsp
  2. Change to the GLASSFISH_INSTALL_DIR/domains/wsc/config/ directory and make the following changes to the domain.xml file.

    1. Change jvm-options from -client to -server.
    2. Change jvm-options from -Xmx512m to -Xmx1G.
  3. OPTIONAL: If OpenSSO has already been deployed and configured, remove the deployed WAR as follows:

    1. Undeploy the application using the Glassfish console.
    2. Delete the /opensso configuration directory.

      rm -rf /opensso
    3. Delete the /AccessManager directory.

      rm -rf /AccessManager
  4. Start the two domains using the asadmin command line tool located in /GLASSFISH_INSTALL_DIR/bin.

    ./asadmin start-domain wsc
    ./asadmin start-domain wsp
  5. (Re)deploy the OpenSSO WAR in the wsc domain using the Glassfish console.

    Keep the default values and click OK.
  6. Launch the deployed OpenSSO web application from the Glassfish console and, when the configuration wizard is displayed, under Custom Configuration, select Create New Configuration.
  7. Use the following values to create the new configuration and click Create Configuration when finished.

    1. Enter a password for amadmin under the General settings, confirm it and click Next.
    2. Keep the default Server Settings values (or modify as necessary) and click Next.

      • Server URL - for example, http://sid.opensso.com:8080
      • Cookie Domain - for example, .opensso.com
      • Platform Locale - for example, en_US
      • Configuration Directory - for example, /openssoconfig
    3. Keep the default Configuration Store values (or modify as necessary) and click Next.

      • Data Store Type - for example, Embedded (Open DS)
      • Port - for example, 50389
      • Encryption Key - as populated by configurator
      • Root Suffix - for example, dc=opensso,dc=java,dc=net
    4. Ensure that the Embedded radio button is selected as the default User Store Settings value and click Next.
    5. Ensure that the No radio button is selected as the default Site Configuration value for the question Will this instance be deployed behind a load balancer as part of a site configuration? and click Next.
    6. Enter a password for amldapuser under the Agent Information settings, confirm it and click Next.

      This password must be different from the one previously entered for amadmin.
    7. Ensure the Summary is correct and click Create Configuration.
    8. After the configuration is complete, click Proceed to Login.

  8. Login to the OpenSSO console as the default amadmin administrator using the corresponding password.

Deploying the Web Service Provider on Glassfish

  1. Download openssowssproviders.zip using the WSS Agent Download link on the OpenSSO Download page.
  2. Make a directory named wss_bits and unzip the contents of the openssowssproviders.zip into it.
  3. Deploy a web service provider (WSP) into the wsp Glassfish domain.

    Use the StockService sample included with the provider download. Information on deploying the Stock Service can be found in the README located in the samples/glassfish directory of the exploded openssowssproviders.zip.
  4. Stop the wsp domain using the asadmin command line tool located in /GLASSFISH_INSTALL_DIR/bin.

    ./asadmin stop-domain wsp
  5. Change to the GLASSFISH_INSTALL_DIR/domains/wsp/config/ directory and make the following modifications to the domain.xml file.

    1. Add the following code fragment under the <message-security-config auth-layer="HttpServlet"> tag.

      NOTE : Create the <message-security-config auth-layer="HttpServlet"> tag if it is not already present.

      <provider-config class-name="com.sun.identity.wssagents.glassfish.FAMHttpAuthModule"
      provider-id="FAMHttpProvider" provider-type="server">
      <request-policy auth-source="content"/>
      <response-policy auth-source="content"/>
      </provider-config>
      
      <provider-config class-name="com.sun.identity.wssagents.glassfish.FAMHttpAuthModule"
      provider-id="FAMAuthHttpProvider" provider-type="server">
      <request-policy auth-source="content"/>
      <response-policy auth-source="content"/>
      <property name="providername" value="wsc"/>
      </provider-config>
      
    2. Add the following code fragments under the <message-security-config auth-layer="SOAP"> tag.

      <provider-config class-name="com.sun.identity.wssagents.glassfish.FAMServerAuthModule"
      provider-id="FAMServerProvider-SAML-HolderOfKey" provider-type="server">
      <request-policy auth-source="content"/>
      <response-policy auth-source="content"/>
      <property name="providername" value="SAML-HolderOfKey"/>
      </provider-config>
      
      <provider-config class-name="com.sun.identity.wssagents.glassfish.FAMServerAuthModule"
      provider-id="FAMServerProvider-SAML-SenderVouches" provider-type="server">
      <request-policy auth-source="content"/>
      <response-policy auth-source="content"/>
      <property name="providername" value="SAML-SenderVouches"/>
      </provider-config>
      
      <provider-config class-name="com.sun.identity.wssagents.glassfish.FAMServerAuthModule"
      provider-id="FAMServerProvider-X509Token" provider-type="server">
      <request-policy auth-source="content"/>
      <response-policy auth-source="content"/>
      <property name="providername" value="X509Token"/>
      </provider-config>
      
      <provider-config class-name="com.sun.identity.wssagents.glassfish.FAMServerAuthModule"
      provider-id="FAMServerProvider-LibertySAMLToken" provider-type="server">
      <request-policy auth-source="content"/>
      <response-policy auth-source="content"/>
      <property name="providername" value="LibertySAMLToken"/>
      </provider-config>
      
      <provider-config class-name="com.sun.identity.wssagents.glassfish.FAMClientAuthModule"
      provider-id="FAMClientProvider" provider-type="client">
      <request-policy auth-source="content"/>
      <response-policy auth-source="content"/>
      <property name="providername" value="wsc"/>
      </provider-config>
      
      <provider-config class-name="com.sun.identity.wssagents.glassfish.FAMServerAuthModule"
      provider-id="FAMServerProvider-UserNameToken" provider-type="server">
      <request-policy auth-source="content"/>
      <response-policy auth-source="content"/>
      <property name="providername" value="UserNameToken"/>
      </provider-config>
      
      <provider-config class-name="com.sun.identity.wssagents.glassfish.FAMServerAuthModule"
      provider-id="FAMServerProvider-UserNameToken-Plain" provider-type="server">
      <request-policy auth-source="content"/>
      <response-policy auth-source="content"/>
      <property name="providername" value="UserNameToken-Plain"/>
      </provider-config>
      
      <provider-config class-name="com.sun.identity.wssagents.glassfish.FAMServerAuthModule"
      provider-id="FAMServerProvider-LibertyX509Token" provider-type="server">
      <request-policy auth-source="content"/>
      <response-policy auth-source="content"/>
      <property name="providername" value="LibertyX509Token"/>
      </provider-config>
      
      <provider-config class-name="com.sun.identity.wssagents.glassfish.FAMServerAuthModule"
      provider-id="FAMServerProvider-LibertyBearerToken" provider-type="server">
      <request-policy auth-source="content"/>
      <response-policy auth-source="content"/>
      <property name="providername" value="LibertyBearerToken"/>
      </provider-config>
      
      <provider-config class-name="com.sun.identity.wssagents.glassfish.FAMServerAuthModule"
      provider-id="FAMServerProvider" provider-type="server">
      <request-policy auth-source="content"/>
      <response-policy auth-source="content"/>
      <property name="providername" value="wsp"/>
      </provider-config>
      
      <provider-config class-name="com.sun.identity.wssagents.glassfish.FAMServerAuthModule"
      provider-id="FAMServerProvider-Anonymous" provider-type="server">
      <request-policy auth-source="content"/>
      <response-policy auth-source="content"/>
      <property name="providername" value="Anonymous"/>
      </provider-config>
      
      
    3. Start the wsp domain using the asadmin command line tool located in /GLASSFISH_INSTALL_DIR/bin.

      ./asadmin start-domain wsp

  6. Log in to the Glassfish console as administrator.

Configuring the WSP to Use the Security Token Service

These configurations are done using the Glassfish console and on the machine to which the StockService WSP has been deployed.
  1. From the navigation bar on the left of the Glassfish console, click Configuration > Security > Message Security > SOAP.
  2. Click on the Message Security tab under SOAP.
  3. From the drop down menu, select the providers previously added, FAMServerProvider and FAMClientProvider, as the Default Provider and Default Client Provider, respectively.
  4. Copy /openssowssproviders/resources/AMConfig.properties to the GLASSFISH_INSTALL_DIR/domains/wsp/config directory and update the copied properties file to reflect your environment.

    Refer to AMConfigWSP.properties.
  5. OPTIONAL: Create a GLASSFISH_INSTALL_DIR/addons/accessmanager directory if not already present.
  6. Copy all the JAR files from the /wss_bits/openssowssproviders/lib directory to the GLASSFISH_INSTALL_DIR/addons/accessmanager directory.
  7. Put GLASSFISH_INSTALL_DIR/addons/accessmanager/openssowssproviders.jar and GLASSFISH_INSTALL_DIR/domains/wsp/config in the classpath of the machine on which the WSP is deployed.
  8. To change the logging level, from the navigation bar on the left of the Glassfish console, click Application Server.
  9. Click the Logging tab on the right of the console.
  10. Click the Log Levels tab.
  11. Select FINEST from the drop down list next to Security.
  12. Click Save.
  13. Copy /wss_bits/openssowssproviders/resources/wsit-client.xml and /wss_bits/openssowssproviders/resources/famsts-client.wsdl to GLASSFISH_INSTALL_DIR/domains/wsp/config.
  14. Update GLASSFISH_INSTALL_DIR/domains/wsp/config/famsts-client.wsdl to reflect the actual path to the keystore.jks file.

    Trade out @KEYSTORE_LOCATION@ with the actual value.
  15. Restart the wsp domain using the asadmin command line tool located in /GLASSFISH_INSTALL_DIR/bin.

    ./asadmin stop-domain wsp
    ./asadmin start-domain wsp

Configuring the Web Service Client (WSC) and the WSP to Use the Security Token Service

These configurations are done using the OpenSSO console.

  1. Log in to the OpenSSO console as the administrator and click through the Configuration > Agents > Web Service Client tabs.
  2. Under Agent, click wsc.
  3. Under Security, select STSSecurity as the Security Mechanism.
  4. For STS Configuration, select SecurityTokenService from the drop down.
  5. Under Signing and Encryption, check the Is Request Signed and Is Response Signature Verified options.
  6. Select the following under Key Store:

    Public Key Alias of Web Service Provider - test
    Private Key Alias - test
    Key Store Usage - Default
  7. Enter the end point of the web service.

    For example, http://sid.opensso.com:9080/StockQuoteService-war/StockService.
  8. Click OK.
  9. Back on the home page of the OpenSSO console, click through Configuration > Agents > Web Service Provider.
  10. This time, under Agent, click wsp.
  11. Under Security, select Anonymous, SAML2-HolderOfKey, SAML2-SenderVouches, and UserName Token as the Security Mechanism.
  12. For STS Configuration, select SecurityTokenService from the drop down.
  13. Under Signing and Encryption, check the Is Response Signed and Is Request Signature Verified options.
  14. Select the following under Key Store:

    Public Key Alias of Web Service Provider - test
    Private Key Alias - test
    Key Store Usage - choose Default and uncheck the box next to the Preserve Security Headers in the Message option.
  15. Click OK.

Configuring the WSC to Use the Security Token Service

Use the StandAloneStockClient sample included with the provider download. Information on deploying this sample can be found in the README located in the samples/glassfish directory of the exploded openssowssproviders.zip.

  1. Put the following JAR files in the classpath of the machine on which the WSC is deployed.

    • appserv-rt.jar
    • j2ee.jar
    • javaee.jar
    • webservices-rt.jar
    • webservices-tools.jar
    • openssoclientsdk.jar
  2. Copy /openssowssproviders/resources/AMConfig.properties to the GLASSFISH_INSTALL_DIR/domains/wsp/config directory and update the copied properties file to reflect your environment.

    Refer to AMConfigWSC.properties. Ensure the values for the following properties are correct.

    • com.iplanet.services.debug.level
    • com.iplanet.services.debug.directory
    • com.sun.identity.agents.app.username
    • com.iplanet.am.service.password
    • com.sun.identity.saml.xmlsig.keystore
    • com.sun.identity.saml.xmlsig.storepass
    • com.sun.identity.saml.xmlsig.keypass
    • com.sun.identity.saml.xmlsig.certalias
    • com.sun.identity.classloader.client.jarsPath
  3. Put the directories containing the following files in the classpath.

    • AMConfig.properties
    • wsit-client.xml
    • famsts-client.wsdl
  4. wsit-client.xml and famsts-client.wsdl are in the /osso_bits/openssowssproviders/resources/ directory.

  5. Update GLASSFISH_INSTALL_DIR/domains/wsp/config/famsts-client.wsdl to reflect the actual path to the keystore.jks file.

    Trade out @KEYSTORE_LOCATION@ with the actual value.

Now all communications between the configured WSP and WSC will be secured by the WSS provider and the Security Token Service. And speaking of tokens, how about The Lion Sleeps Tonight as performed by The Tokens, Pat (the hippo), and Stanley (the dog).

Friday Mar 28, 2008

When Peace Guides the planets.sun.com

You might find it interesting to check out the beta site planets.sun.com. Sun employees create planets (feed aggregators based on keywords, features, or other criteria) and their created collection of blogs.sun.com links can be viewed by clicking the planet name. There is a planet specifically for OpenSSO but you might find other planets that might be useful also.

At this time, non-Sun employees can not create planets but, if you have an idea for one that might be beneficial, let me know and I can create it.

In honor of the planets.sun.com aligning, here's the 5th Dimension singing their huuuuggggeee hit Aquarius/Let the Sunshine In (The Flesh Failures). These two songs are NOT a medley in the Broadway musical Hair for which they were both written - separately. The aggregation was most likely a genius idea from the head of producer Bones Howe.

Thursday Mar 27, 2008

A Primer on OpenSSO, Policy Agents and Pan's People

Here's a link to an excellent tutorial on getting started with OpenSSO and policy agents.

http://wikis.sun.com/display/OpenSSO/getstarted

And now that you're finished, you just might want to loosen up so here is a clip of Pan's People, a group of females who would dance to a song on the BBC-TV music chart show Top of the Pops when the artist wasn't available to sing it live (or Memorex). (Think the Solid Gold dancers for those in the States.) This clip is the troupe dancing to Creedence Clearwater Revival's Green River.

And, of course, there's the even funnier take-off by French and Saunders' Pan's Indeedy People moving to Yellow River - with a long yellow cloth to boot.

Yellow River? Don't take me there.

Monday Mar 17, 2008

Telecommunication with an SSL Data Store

This blog entry is two years old. You can do this with the OpenSSO configurator now when you deploy the WAR.

I found this procedure internally and I thought it might help some externally. The engineer was configuring OpenSSO to communicate with an SSL data store.

  1. Set up your data store with SSL enabled.
  2. Import a root certificate for your data store to the web container using the following command:

    JAVA_HOME/bin/keytool -import -keystore keystore_file_name -keyalg RSA -trustcacerts -alias alias_name -storepass changeit -file certificate_file_name

    • For Sun Application Server 9.1, keystore_file_name in the default domain1 is /opt/SUNWappserver/domains/domain1/config/cacerts.jks
    • For Sun Web Server 7.0U1, keystore_file_name is /usr/jdk/entsys-j2se/jre/lib/security/cacerts
  3. Restart the web container.
  4. Deploy opensso.war.
    When running the WAR configurator, you can't point to the SSL port so you must point to the non-SSL port.
  5. Log into the administration console as the administrator; by default amadmin.
  6. Create a new data store configuration or edit the existing one.
    Click the Data Stores tab for the appropriate realm under the Access Control tab. Be sure to enable the following two attributes:
    • LDAP Server must have the host name and SSL port of the SSL data store.
    • LDAP SSL must be checked.
  7. Create a new User that points to the SSL port of the data store.
    Click the Directory Configuration tab after choosing the appropriate Server under the Sites and Servers tab, located under the Configuration tab. Select New... under User and configure the user so that it points to the SSL port.
  8. Delete the default non-SSL user and save.
And now OpenSSO is configured to communicate with a secure directory. In celebration here's another type of communication: Telecommunication, live by A Flock of Seagulls.

Tuesday Mar 04, 2008

Wildcard Matches in Policy Agents

A comment was left in yesterday's entry on policy logic concerning the lack of consistency in how the different policy agents treat the wildcard. Now I am not an agent expert but I did manage to gather some information for Mr. Robinson that, I hope, helps to shed some light on how the wildcard is used by agents.

The Policy Service in OpenSSO supports policy definitions using an asterisk (\*) as the wildcard. Only \* is supported as a wildcard and it can not be escaped as in \\\*.

A \* :

  • matches zero or more occurrences of any character.
  • spans across multiple levels in a URL.

The following matching rules assume (rightfully so) the wildcard character is \* and the delimiter character is /.

  1. \* matches zero or more characters, including /, in the resource name.
  2. \* matches one or more characters, including /, if the \* appears at the end of the resource name and it is immediately preceded by a /. For example, abc/\* doesn't match abc.
  3. Multiple consecutive / characters don't match with a single /. For example, abc/\*/xyz doesn't match abc/xyz.
  4. For purposes of comparison, trailing / characters will not be considered as part of the resource name. For example, abc/ or abc// will be treated the same as abc.

Here are some examples:

Pattern Matches Doesn't Match
http://xyz.sun.com:80/\* http://xyz.sun.com:80/
http://xyz.sun.com:80/index.html
http://xyz.sun.com:80/x.gif
http://abc.sun.com:80/
http://xyz.sun.com/index.html
http://xyz.sun.com:8080/index.html
http://xyz.sun.com:80/\*.html http://xyz.sun.com:80/index.html
http://xyz.sun.com:80/public/abc.html
http://xyz.sun.com:80/private/xyz.html
http://xyz.sun.com/index.html
http://xyz.sun.com:80/x.gif
http://abc.sun.com/index.html
http://xyz.sun.com:80/\*/abc http://xyz.sun.com:80/private/xyz/abc/xyz/abc
http://xyz.sun.com:80/xyz/abc
http://xyz.sun.com/abc
http://xyz.sun.com/abc.html
http://abc.sun.com:80/abc
http://xyz.sun.com:80/abc/\*/def http://xyz.sun.com:80/abc/123/def
http://xyz.sun.com:80/abc/abc/def
http://xyz.sun.com:80/abc/def/abc/def
http://xyz.sun.com:80/abc/def
http://xyz.sun.com:80/abc//def

And while we're on the subject of wild things, think of X, the seminal punk band of all time. The song in this video isn't one they wrote (for that you'd have to check out Johnny Hit and Run Paulene, Nausea or Los Angeles) but it does segue nicely. Here's X covering The Trogg's (not Tone-Loc's) Wild Thing. And that's Chuck Berry on stage at the video's end - a wild thing in his own right.

UPDATE: For more information on policy logic and wildcards see the following entries:

Policy Logic in OpenSSO

Here's some information that, thanks to a comment from a member of the OpenSSO community, I found missing from our doc set. We wrote a great deal about policy but not a heck of a lot about policy logic.

NOTE: If you'd like an overview of policy and authorization take a look at the Authorization and Policy Service chapter in the Sun Java System Access Manager 7.1 Technical overview or the OpenSSO Policy Service Architecture document. I'll wait.

Done? OK. Now that you know everything there is to know about policy, here is the last piece. All of the following should be satisfied for a policy to be applicable to a request.

  1. The Resource Name defined in a policy's Rules should match that of the protected, requested resource. The match can be an exact literal match or one due to the presence of wild cards. Currently, policy agents only support http:// and https:// URLs as a Resource Name; they do not support IP addresses in place of the host name. Wild cards are supported as a substitution for a protocol, a host name, a port number, or a resource - as in:

    http\*://\*:\*/\*.html
  2. The requesting user should satisfy at least one of the Subject(s) defined by the policy. For example, if the Subject type is defined as Access Manager Identity Subject, the requesting user should be a member of the role selected in the policy.
  3. At least one Condition in EACH selected Condition Type defined in a policy should be satisfied by the requesting user, resource and/or environment parameters. For example, if the policy is defined with two Time conditions and two IP Address/DNS Name conditions, the request should satisfy at least one Time condition and at least one IP Address/DNS Name condition.

And sometimes policies collide; when this happens, the following rules take effect:
  1. When multiple policies are applicable to a particular resource, the order in which the policies are evaluated is not deterministic.
  2. If a policy decision for a requested action is boolean, a value of false overrides one of true. For example, when deciding authorization for a web URL, deny overrides allow.
  3. If a policy decision for a requested action is boolean and the request is determined to be false based on policies evaluated thus far, no further policies will be evaluated for the requested action. This behavior can be changed by toggling the Continue Evaluation On Deny Decision attribute in the Policy Configuration Service.

So, in conclusion, sometimes musical styles collide also. When this happens there are no rules. You might get Sammy Davis, Jr. (smokin' a ciggy butt) and Cass Elliot singing their Las Vegas-style version of the Peter, Paul and Mary classic, I Dig Rock and Roll Music.

Or you get Mary dancing like she's in a mosh pit to an acoustic version of the same song.

UPDATE: For more information on policy logic and wildcards see the following entries:

Tuesday Jan 29, 2008

Coupla Access Manager 7.1 Tips

For those using Access Manager 7.1 here are a coupla things you might want to know about.

  • Access Manager 7.1 can be installed in one of two modes: realm or legacy. So after installation how do you determine if Access Manager is running in realm mode or legacy mode?

    Type the following URL into the Location window of your browser and hit Enter.

    protocol://FQDN:portnumber/amserver/SMSServlet?method=isRealmEnabled

    where

    FQDN is the host name and domain of the machine on which the product was installed. If the server returns true, Access Manager is running in realm mode; otherwise, it's running in legacy mode.
  • If the host name and/or domain name of the machine on which Access Manager is running changes, this change needs to be reflected in a number of configuration files. This recently published technical note, Host Name Changes in a Sun Java System Access Manager 7.1 WAR Deployment explains it all for you.

And while we're at it here are a coupla versions of the same classic song, Jolene. The first video is a version by a coupla people in a little band called The White Stripes. The second is a version by the song's writer, Dolly Parton (who has a coupla - no I won't go there even though she does in the video). Take your pick or watch both.

I mean both videos.

Monday Jan 28, 2008

The OpenSSO Bootstrap File Deconstructed

Since build 2, OpenSSO uses a file for bootstrapping itself. Previously, AMConfig.properties held server configuration information but now bootstrap points to a centralized data store that holds the OpenSSO server configuration information.

After deploying the OpenSSO WAR and running the configurator, OpenSSO server configuration data is written to a central instance of OpenDS by the service management (com.sun.identity.sm) API. A setup servlet also creates a file named bootstrap in the top-level /opensso directory. This file contains information that points to the location from which OpenSSO can retrieve configuration data to bootstrap itself. The content in bootstrap can be either of the following:
  • A directory local to OpenSSO (for example, /export/SUNWam) indicates the server was configured with a previous release. The directory is where AMConfig.properties resides.
  • A URL that points to a directory service using the following format:
    ldap://ds-host:ds-port/server-instance-name?pwd=encrypted-amadmin-password&embeddedds=path-to-directory-service-installation&basedn=basedn&dsmgr=directory-admin&dspwd=encrypted-directory-admin-password
    For example:
    ldap://ds.samples.com:389/http%3A%2F%2Fowen2.red.sun.com%3A8080%2Fopensso?pwd=AQIC5wM2LY4Sfcxi1dVZEdtfwar2vhWNkmS8&embeddedds=%2Fopensso%2Fopends&dsbasedn=dc%3Dopensso%2Cdc%3Djava%2Cdc%3Dnet&dsmgr=cn%3DDirectory+Manager&dspwd=AQIC5wM2LY4Sfcxi1dVZEdtfwar2vhWNkmS8
    where:
    • ds.samples.com:389 is the host name and port of the machine on which the directory is installed
    • http%3A%2F%2Fowen2.red.sun.com%3A8080%2Fopensso is the instance name
    • AQIC5wM2LY4Sfcxi1dVZEdtfwar2vhWNkmS8 is the encrypted password of the OpenSSO administrator
    • %2Fopensso%2Fopends is the path to the directory installation
    • dc%3Dopensso%2Cdc%3Djava%2Cdc%3Dnet is the base DN
    • cn%3DDirectory+Manager is the directory administrator
    • BQIC5xM2LY4SfcximdVZEdtfwar4vhWNkmG7 is the encrypted password for the directory administrator
    OpenSSO supports Microsoft's Active Directory, Sun's Directory Server, and the open source OpenDS.
  • Flat files are no longer supported for configuration data but configuration data store failover is supported via the bootstrap file. If more than one URL is present in bootstrap and OpenSSO is unable to connect or authenticate to the data store at the first URL, the bootstrapping servlet will try the second (and so on). Another feature of bootstrap is that the number sign [#] can be used to exclude a URL as in:

    #ldap://ds.samples.com:389/http%3A%2F%2Fowen2.red.sun.com%3A8080%2Fopensso?pwd=AQIC5wM2LY4Sfcxi1dVZEdtfwar2vhWNkmS8&embeddedds=%2Fopensso%2Fopends&dsbasedn=dc%3Dopensso%2Cdc%3Djava%2Cdc%3Dnet&dsmgr=cn%3DDirectory+Manager&dspwd=AQIC5wM2LY4Sfcxi1dVZEdtfwar2vhWNkmS8

    And, for some extracurricular bootstrapping, take the Replacements, some Lou Reed, a dash of early Bowie, a pinch of Violent Femmes, some 60s surf sounds, a big garage with the door closed, and you have the British band Bootstrap and their song Streetlight. The video uses scenes from Faster Pussycat Kill Kill, the classic film by Russ Meyer. A configuration made in heaven!

Thursday Jan 24, 2008

Host Machine and Domain Name Changes: Access Manager 7.1

UPDATE: The completed document has been published to docs.sun.com here. The link to the review copy below has been disabled.

I've just put together a technical note on what to do if the host machine or domain name changes for an instance of Access Manager 7.1 (WAR deployment only). It contains procedures for modifying properties and/or files in both a regular environment and in a federation environment. Here is a PDF version I sent out for engineering review. A complete HTML version should be posted to the Access Manager 7.1 documentation set on docs.sun.com next week after I receive any comments.

There are other things you can do when a host name changes. For example, here is what was done when the host name changed on The Match Game. It's a long clip but you get to see the late Brett Sommers, the late Charles Nelson Reilly, the late Gene Rayburn, and the late Eva Gabor! Or is it Jolie? Or is it Zsa Zsa? Wait...Zsa Zsa is not late.

Tuesday Jan 15, 2008

OpenSSO & OpenDS Sitting in a Tree, K-I-S-S...

In case you hadn't noticed, OpenSSO build 2 (the soon-to-be christened Federated Access Manager) now stores its configuration data in a data store rather than a flat file. OpenDS is the new embedded configuration store, replacing the previous flat file implementation where configuration files were stored...um...all over the place (okay, there was sms). Now, OpenDS is installed with OpenSSO and the configuration data is stored.

The installed version of OpenDS is not complete (for example, the bin scripts have been removed to make the opensso.war as small as possible). But you can always download opends.zip, explode it and point the script parameters to the configuration directory (config_dir_specified_in_configurator/opends). This will most probably change as the OpenDS builds stabilize.

Some things based on this move have already changed. For example, famadm is a utility that lets you manage your OpenSSO installation from the command line. When famadm was developed you needed to point to AMConfig.properties during setup. But from OpenSSO build 2, AMConfig.properties is now stored in an instance of OpenDS. So during setup you need to point famadm to a bootstrap file named, appropriately enough, bootstrap. bootstrap is located under the directory defined during configuration as the Configuration Directory.

The concept is that the CLI will read the bootstrap file, contact OpenDS, fetch the appropriate properties, and bootstrap itself.

So to bring it full-circle, and to tout what I will be doing on my long holiday weekend (which starts as soon as I publish this entry), here's KISS.

Thursday Jan 10, 2008

OpenSSO: Subscribe and Learn

Charles Wesley, one of the QA engineers working on Federated Access Manager and related products, sent this procedure out to the users@opensso.dev.java.net mailing list. This is the type of minutiae (in a good way) that is available on the list. Plus, you can ask questions specific to your deployment, get answers, and help to review the official docs. You can join the list here - but only if you have an account.

Thanks Charles for giving me the opportunity to publicize the list and for this procedure - which only needed a little formatting in its move from email to blog.

Configuring OpenSSO on an Instance of Web Server 7.x Owned by webservd

When installed using the Java Enterprise System installer, Web Server 7.x creates a web server instance owned by the user webservd. In Solaris 10, webservd has a home directory of / by default. If OpenSSO is deployed to an instance owned by webservd with the default settings, the configuration will fail because the OpenSSO configurator will not create files under /. Following is a simple procedure to allow configuration on a webservd-owned web server instance to succeed.
  1. Create a new home directory for webservd
    mkdir /export/home/webservd
  2. Change the ownership of the directory to owner webservd and group webservd
    chmod -R webservd:webservd /export/home/webservd
  3. Replace / with /export/home/webservd as the home directory of webservd in the /etc/passwd file.
  4. Restart the web server instance on which OpenSSO will be deployed.
  5. Deploy the OpenSSO WAR.
  6. Configure the war file and enter /export/home/webservd as the configuration directory that will be used by OpenSSO.
So, in keeping with today's theme, I went looking for a clip of the song, The Things I Will Not Miss (aka On The List), from the 1973 musical remake of Lost Horizon. For those hoping to see Sally Kellerman and Olivia Hussey, fuggedaboutit. Here's Moshe en Joost!

Friday Jan 04, 2008

Changing the Cookie Name in OpenSSO

I found this information in a comment so I figured I'd write it to an entry - in case anyway needs to change the cookie name in OpenSSO which, by default, is not editable.

  1. Login in to the console and click Configuration.
  2. Click Sites and Servers.
  3. Click the server name in the "Servers" table.
  4. On the Edit server name page, click the Security tab and then Inheritance Settings.
  5. Search for "Cookie Name" in the table and uncheck the box
  6. Save the page and click the Back to Server profile button.

You will now see the Cookie Name field is editable and you can change it.

And since we're talking cookies - it must be Cookie Time! So here's a clip of Troop Beverly Hills singing Cookie Time in one of my favorite 80s movie. And for those in the know Jenny Lewis of Rilo Kiley plays Shelly Long's daughter. Can you pick her out?

That's her at about 53 seconds. You can also spot Rosario from Will and Grace (Shelley Morrison) playing the maracas. And since I got you interested here's Jenny with Rilo Kiley singing Silver Lining.

Thursday Jan 03, 2008

REVIEW: Client SDK chapter FAM8 Developer's Guide

I have posted a review PDF of the Client SDK chapter for the Federated Access Manager 8 Developer's Guide and I'd love to hear what you think.

https://opensso.dev.java.net/public/use/docs/opensso/pdf/clientsdk.pdf

And since I am being societally forced to say Happy New Year (society is holding my fingers to the keypads), I'll do it with a catchy little disco anthem from The Ritchie Family.

Monday Dec 17, 2007

SSO Sample: OpenSSO Client SDK

The Single Sign-On Token Verification Sample validates an SSOToken and then displays the user profile associated with it. This sample is accesible from the Client SDK-Samples page.

You must log in to the OpenSSO console in order to run this sample. Once you are logged in, click Click and the user profile associated with the SSOToken you received after authentication is displayed. I logged in as the default administrator, amadmin, and received the following profile:

SSOToken host name: 127.0.0.1
SSOToken Principal name: id=amadmin,ou=user,dc=opensso,dc=java,dc=net
Authentication type used: DataStore
IPAddress of the host: 127.0.0.1
SSO Token validation test succeeded
The token id is AQIC5wM2LY4SfcxaVucZ3AN669OG0Nzq+dA52vuEuaMIQhU=@AAJTSQACMDE=#
Property: Company: Sun Microsystems
Property: Country: USA
User Attributes: {inetUserStatus=[Active], dn=[uid=amAdmin,ou=people,dc=opensso,dc=java,dc=net], roles=[Top-level Admin Role]}

NOTE: One caveat I encountered was that the sample will not work if the machine name and host don't match in the OpenSSO server and the sample SDK WARs. I had installed OpenSSO on my machine, develop2.orange.sunlab.com. The client sample WAR was automatically deployed on localhost - the same machine. But the sample did not work until I manually changed localhost to develop2.orange.sunlab.com in the browser location window.

The code included with this sample is SSOTokenSampleServlet.java and SampleTokenListener.java. These files serve as a basis for using the SSO API, demonstrating how you can create an SSO Token, call various methods from the token, set up an event listener and get notified on event changes.

Friday Dec 14, 2007

OpenSSO v1 Build 2 Is Baked

I mean it's ready to download and try out. How do I know? I had to redo the Download Page. Pretty, ain't it? So download the ZIP, follow the instructions in OpenSSO Build 2 and Glassfish: Ready to Go, and, in a jiffy, your deployment will be baked too.

Wednesday Dec 12, 2007

User and Policy Samples: OpenSSO Client SDK

Now that I've gotten through the installation of the OpenSSO Client SDK sample WAR and it's Service Configuration Servlet sample, let's take a look at other Client SDK samples. The next one on the Client SDK - Samples list is the User Profile (Attributes) Sample Servlet.

The UserProfileServlet.java sample code retrieves and displays the profile that corresponds to the user ID entered in the Username text box. I created a user profile aaaa, entered the ID and password in the text fields and, voila, straight forward and it worked.

Note the email address, given name and other information retreived.

The Policy Evaluator Client Sample Servlet retrieves from the Policy Service a policy decision that would be passed to a web agent for enforcement. I created a policy using the OpenSSO server for the resource http://www.sun.com:80 with a GET allow and POST deny rule for all authenticated users on Fridays. PolicyClientServlet.java is the call on the client side that initiates the retrieval of the policy decision.

And while you're waiting for my follow-up entries on the SSO and command-line samples for the Client SDK, you might want to check out this video of Nellie McKay and learn how to do the dance that's sweeping the nation - come one everyone, 'do the Zombie'. It'll do you good.

Sunday Dec 09, 2007

Federated Access Manager 8.0 Roadmap and Features

I have been asked one particular question many times over the last few months and have been fudging my answer because way back when I wrote an entry that attempted to answer this question I was chastised by some muckety-mucks. On Friday, I was searching for some information and, lo and behold, found that Daniel Raskin, our relatively new marketing guru, had written a blog regarding the answer to the very same question I have been hesitating to answer: can you give me some information regarding FAM 8.0 roadmap and features? So, here are links to the blog entries that answer that question. Way to go, Daniel!

Federated Access Manager 8.0 -- The Overview (Part I)

Federated Access Manager 8.0 -- The Features (Part II)

On Saturday, I was searching for something fun to watch and found this clip of one of the all-time great comics, Totie Fields. Way to go, Totie!

Thursday Dec 06, 2007

OpenSSO Client SDK: Service Configuration Sample

UPDATED: 12/11/07 - answers to questions below

In preparation for writing the Client SDK chapter of the FAM8 Developer's Guide, I am running the Client SDK samples. I did not find a lot of information concerning what these samples are actually doing so I figured I'd tell you what I've done and if you have questions (or answers), comment me.

NOTE: AMConfig.properties has been deprecated for OpenSSO. The server configuration data is now stored in an OpenDS server when you freshly install the soon-to-be-latest release. The Client SDK, however, still uses AMConfig.properties to store its configuration data as it is remote to the installed OpenSSO server.

This Service Configuration Sample Servlet executes the ServiceConfigServlet.java which retrieves and displays attributes from the service name input; in the sample, DAI.
  1. Deploy opensso.war in glassfish.
  2. Deploy and launch the fam-client-jdk15.war

    In the the samples directory of the inflated opensso.zip, you find fam-client.zip. Unzip this and see the war and sdk directories. The war directory contains the Client SDK and web-based samples. The sdk directory contains command line based samples (compile the source code before using it). In the war directory, you will find fam-client-jdk14.war and fam-client-jdk15.war. Deploying the appropriate WAR, depending on the version of Java on your machine, installs the Client SDK. Launching the deployed WAR via the Glassfish console displays the Configurator page.
  3. Configure the Client SDK by pointing it to your local instance of OpenSSO.

    NOTE: Be sure to use an opening forward slash (/) in the Service Deployment URI.
  4. After configuration, click the link to proceed to the samples and, from the resulting page, click Access Management Samples. The following page is displayed.
  5. Click Service Configuration Sample Servlet, enter values on the resulting page and submit.

    You only have to enter the password; admin123, by default. I got an error the first time around and had to change the value of two properties in the Client SDK AMConfig.properties (which, after configuration, I found in the top-level root directory of my machine - not a very organized place for it to land).

    • com.sun.identity.agents.app.username should have a value of UrlAccessAgent
    • com.iplanet.am.service.password should have a value of changeit

    NOTE: Restart the glassfish domain after modifying the file and before entering the password and submitting again.
  6. SUCCESS!! You can see the Client SDK retrieved the attributes of the DAI Service. Also the SSOToken of the questioning user.

    Questioning?\*
\*Yes. Questioning the following:
  • What is the DAI Service? Many moons ago, it referred to the ums.xml. Is DAI just a hold over that is now only used for this sample? Or is it something more?

    ANSWER: The service is still used for an existing directory information tree (DIT) and legacy installs.
  • What is the difference between the Configuration Type options, schema and config? The output for schema you see above. The output for config looks like an LDAP blob. In either case, the output is not very pretty and I can't make heads or tails of it.

    ANSWER: schema refers to the data structure, the template for the data. Default values may be defined dependent on the service. config is the actual data. The output is defined as key/value pairs, one right after t'other. (sic)
  • What happens if I used another OpenSSO Service Name? Would this still work? Or is it, as the name says, just a sample.

    ANSWER: You can use any OpenSSO service as input as long as you use the value defined as the name attribute of the service element in the particular service's XML service file.
  • Now that Amy Winehouse has received six Grammy nominations for her album, Back to Black, will she clean herself up in time to perform?

    ANSWER: With any luck. Even though she cancelled the concert I had tickets for nine months ago, I'm still in Amy's corner. I am, though, getting tired of reading stories that begin, "Troubled singer Amy Winehouse..." In this picture video, Amy covers the Teddy Bears' classic To Know Him Is To Love Him (which, ironically enough, was written by troubled record producer Phil Spector).

See User and Policy Samples: OpenSSO Client SDK for more Client SDK sample information.

Tuesday Dec 04, 2007

Updated OpenSSO FAQ

I took a moment last week to update the OpenSSO FAQ Center. The only question I have now is...

Friday Nov 30, 2007

OpenSSO Build 2 and Glassfish: Ready to Go

Today I installed Glassfish, Sun's open source application server, and OpenSSO Build 2, Sun's open source access manager server. I used a machine running Solaris 10. Glassfish uses either JDK 1.5 or 1.6 so I added /usr/jdk/instances/jdk1.5.0/bin to the path property in my .profile file. Additionally, I set my JAVA_HOME to /usr/jdk/instances/jdk1.5.0. Seven months back, I installed Glassfish and it was pretty easy although there were some caveats. Today, there were no caveats. Deploying the OpenSSO WAR, as has been the case, was a cool drink of water.
  1. Using a browser, download glassfish-installer-v2-b58g.jar from https://glassfish.dev.java.net/downloads/v2-b58g.html.
  2. Using the command line, extract the file using:

    java -Xmx256m -jar glassfish-installer-v2-b58g.jar

    This created a glassfish directory with everything inside. I liked this. So many times I have extracted a JAR to find files flying all over the place.
  3. Change into the glassfish directory.
  4. Run the following commands:

    chmod -R +x lib/ant/bin

    lib/ant/bin/ant -f setup.xml
  5. After a successful build, change to the root directory and start the default domain:

    glassfish/bin/asadmin start-domain domain1
  6. Using a browser, verify the server is running by accessing http://machine.domain:8080.

    You should get a Server Running page.
  7. Login to Glassfish as admin (PW: adminadmin) by accessing the console at https://machine.domain:4848.
  8. Back on the command line, make an opensso directory and change into it.
  9. Using a browser, download Build 2. (This latest stable build will be at this location next week.)
  10. Back on the command line, unzip the zip.
  11. In the Glassfish console, click Web Applications on the left side.
  12. On the right side, click Deploy..., browse for opensso.war, and click OK.

    The WAR will be deployed.
  13. When finished, click Launch.

    The following screen is displayed.

  14. I chose Simple which, in turn, displayed this screen:

  15. Enter the default amAdmin password: admin123 and press Configure.

    The configuration screen is displayed. I clicked View Process Log and watched:

  16. I was too excited to wait five seconds so I clicked to get the login page at http://machine.domain:8080, typed in my credentials and was ready to go...as Republica was, back in the day.

    This is the overseas version, not the US remix with ridiculous overdubbed guitars that sounds like Paris Hilton's wonky left eye looks.

Monday Nov 26, 2007

OpenSSO Download Page Changes

Last week I attempted to explain the myriad downloads available on opensso. This week we modified the OpenSSO download page so it is more concise and understandable. This page will hopefully be used as is for eons to come.

With the new version you can download:
  • opensso.zip Formally named fam.zip, this file includes the deployable opensso.war web archive, relevant Sun libraries, administration tools, samples, and the client SDK. It contains code culled from the amserver and federation directories.

    NOTE: Some of these items are themselves compressed files within the compressed opensso.zip; for instance, fam-client.zip and openssosamples.zip.

    opensso.zip is the most complete download available. I say most complete because it does not contain a few of the authentication modules based on third-party code. Build 1 is the most recent stable version of opensso.zip; Build 2 will be available soon. The opensso.zip download under the Periodic Builds table is pushed twice a week. Within the ZIP, you can use opensso.war to create specialized WARs to deploy, for example, the console or Distributed Authentication only. Instructions are included in the deployable-war directory. These WARs were previously available as separate downloads.
  • famclientsdk.jar contains the complete client SDK including the federation library code which can be used to build a remote federation-based service provider.

    NOTE: The one change I'd like to see is opensso reflected in the name of this JAR. Although "A foolish consistency is the hobgoblin of little minds"\*, this consistency is not foolish.
  • opensso-sun-extlib.zip contains third party libraries needed to build the OpenSSO source code. See the Build Instructions for information on how to use this.
  • openssosrc.zip contains the OpenSSO source code.

Older versions of OpenSSO and stable and nightly versions of the web and J2EE agents can also be downloaded from this page.

Changes\*\*.

\*Ralph Waldo Emerson

\*\*David Bowie

Wednesday Nov 14, 2007

The OpenSSO WAR Name Game

This information refers to the older OpenSSO downloads.

There are so many different web archive (WAR), Java archive (JAR), ZIP (ZIP) files and directories that you can browse and download from opensso that I have decided to put down in bits my take on them - what they are and why they differ. (I am not writing about the lesser-known files and directories - only the full product downloads that people, understandably, get confused about. Most of the other archive files are fully explained at the pages I linked to above.)

Of all the directories that you can browse,
  • amserver contains the access control & management related source code we are developing for Federated Access Manager 8.0. This includes, but is not limited to, authentication, policy, session, and auditing code. It was derived from the non-federation related features developed for Access Manager. This directory becomes part of the fam.war (now opensso.war).
  • federation contains all federation related source code. This code is derived from features developed for Federation Manager and the SAMLv2 plugin. The federation directory contains these subdirectories:
    • library can be downloaded as openfedclientsdk.jar. This can be used in a client application to communicate with an instance of OpenSSO. (I haven't been able to figure out if this directory is part of fam.war. Comment if you know.)
    • openfm contains the federation code we are developing for the 2008 release of Federated Access Manager 8.0. It can be downloaded as part of fam.war. Unlike the amserver directory, I don't believe openfm can be downloaded as a separate WAR. (Back in the day, fam.war was called openfm.war; it no longer is.)
Again, fam.war is comprised of code and files from both the amserver (opensso.war) and federation directories. It is the open source version of what one day will be branded by Sun Microsystems as Federated Access Manager. Download, install, and watch the developing ball bounce.

Now let's end with a tip o' the hat to the originator of The Name Game. Here she is...the rockin' Shirley Ellis. Everyone do The Pony!!

About

docteger

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today