Tuesday, April 3, 2012

Unsolicited login with OAM 11g

In a previous post I talked a little about protecting only a part of an application with OAM. I included this bit of text describing the use case:
But what if you want to let users access part of the app anonymously, but require them to log in to access some of the apps features? I don't know what anyone else calls this sort of flow, but I call it the shopping cart model (browse around tossing stuff in your card, then sign in to check out).

That post talked about how to support the "shopping cart" login model with OAM if you're using ADF, but what if you're trying to accomplish that with plain old HTML or something else?

First start with a simple page - for example your company's home page. I stuck mine in a virtual directory named UnsolicitedLoginDemonstration. Then create an OAM policy that makes that page Unprotected:

Notice that I set the Protection Level to "Unprotected" and put it in the Public Resource Authentication and Authorization Policies. I specifically want this to be Unprotected, not Excluded. I'll explain why later.

Then create another new resource - this one called something like "loggedin.jsp":

Notice that this resource is Protected by OAM.

That's all you need to do in OAM, the rest is inside your web app.

In the HTML of your web app (or your company's home page) add an iframe with the src set to loggedin.jsp:

    For example here's how you would do it with an iframe directly:
<iframe src="loggedin.jsp"> Sorry, your browser doesn't support iframes (which means it's old and busted). </iframe>
Note: it's really important that you close the iframe with </iframe>. You can't just close the iframe tag directly like <iframe src="something"/> because browsers stop parsing the page at that point!

I'm going to skip the rest of the HTML lesson here, but if you want to support browsers that don't support iframes you can just put HTML inside iframe where I put the "Sorry" text.

If you load up that page you'll see something like this:

When a user enters their username and password and hits Login they'll load the protected URL - in this case "loggedin.jsp". So all that remains is to have that page reload the parent page. I did that with a little bit of JavaScript. Here's my loggedin.jsp:
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
<script language="JavaScript">
function blastFrame() {
    var parentloc = parent.location;
    //alert( "Parent location is " + parentloc );
    parent.window.location = parentloc;
}
</script>
        
    </head>
    <body onload="blastFrame();">
Your browser doesn't support onload in an iframe.
<input type="button" value="click me" onclick="blastFrame();">

    </body>
</html>

If you want to get clever you can go a couple of steps forward and only make the login box appear when the user actually clicks a button or hovers over a chunk of text, and disappears when the user mouses out of it.

To do that we do a little bit of CSS and JavaScript magic. Here's what I have in the HEAD:

<style type="text/css">

#LoginLayer { 
background-color: yellow;
height:200px;
width:400px;
left:100px;
top:100px;
visibility: hidden;
}
</style>

<script language="JavaScript">
  function setVisible( setting )
  {
    var myElement = document.getElementById("LoginLayer");
    
    if(setting)
            myElement.style.visibility="visible";
    else
            myElement.style.visibility="hidden";
    }
</script>
  
    <title>Demonstration of unsolicited login with OAM 11g</title>
    </head>

The CSS there makes the LoginLayer (which we'll see in a minute) hidden. The JavaScript either makes the LoginLayer visible or hidden depending on the boolean passed in. The only remaining fun is the actual HTML for the login form:

    Or you could do the same thing with a layer so it appears when you click a button:
    <P/>
    
      <form>
        <input type="BUTTON" value="Click to hide" onClick="setVisible(false)" />
        <input type="BUTTON" value="Click to show" onClick="setVisible(true)" />
      </form>    
    
    or mouseover an image <img src="loginbutton.gif" onmouseover="setVisible(true)"/>
    or <div onmouseover="setVisible(true)"><B>this text</B></div> to show the login iframe below
    <BR/>
    
    <p id="LoginLayer" onmouseout="setVisible(false)" >
    <iframe src="loggedin.jsp" height="200px" width="400px">
        Sorry, your browser doesn't support iframes (which means it's old and busted).
    </iframe>

    </p>
The result is something like this:
When you click or mouseover the login box appears like this:

I did this all with a <P>, but you could do it with an actual layer if you wanted. Or you could use JQuery to make it even cooler. Whatever floats your boat.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.