Thursday, February 10, 2011

External Custom Login Forms with Oracle Access Manager 11g

This is the 2nd post in my OAM 11g Academy series. To view the first post in the series which will be updated throughout to contain links to the entire series, click here: http://fusionsecurity.blogspot.com/2011/02/oracle-access-manager-11g-academy.html

While my intent was to make the first few posts on the topic of the OAM 11g policy model, I’ve been getting a ton of requests for help on how to do form based logins using a custom, externally hosted login form with OAM 11g. So, I’ve decided to take a short break from the policy model to tackle that topic.

It is very common for customers to want to redirect users to their own custom login form to authenticate into OAM. There are actually several sub-scenarios to this use case that I will address in a broader post about authentication in OAM 11g, but the thing I want to focus on today is the case of redirecting the user to a login page or application that is “externally” hosted outside of the OAM managed server.

The idea is that when it is time to authenticate the user, the user will be redirected to your own page or application that can be built using whatever technology you like including JSP pages, ASP/.net, perl, PHP, etc.. You can render the form to look like whatever you want and even potentially do some pre-processing of the users submission (POST) before sending the credentials along to OAM.

The information on how to do this can be divided into two sections: the authentication scheme configuration and the login.jsp itself.
The Authentication Scheme

You want to create a new authentication scheme that you will use in your authentication policy. You can give it whatever name you want.

The settings should be as follows, this is basically what is in the 11g documentation on authentication schemes that can be found here except that there is a bug in the documentation that puts a “/” in the front of the challenge URL. You do not want the “/”.

Challenge Method: FORM

Challenge Redirect URL: /oam/server/ (note that you do not want to change this from the value used for the default OAM form)

Authentication Module: LDAP (or whatever you had before for the default OAM form scheme)

Challenge URL: The full URL starting with http or https of your login form which can be hosted wherever you like

Context Type: external




The Process


When you set up a form based authentication scheme with challenge type external, the webgate redirects the user first to the obrareq.cgi url which then redirect the user to the login page specified in the authentication scheme “challenge url”.

On the redirect to the login page it adds two things to the query string: request_id and redirect_url as in the following query string ?request_id=5092769420627701289&redirect_url=http%3A%2F%2Fateam-hq61.us.oracle.com%3A7777%2Fscripta%2Fprintenv

The Form/App

Again, the form or login application can be written using any technology you care to use to process the redirect from the user and render the HTML. The following is what you need to know about what is required in the login form you create. Beyond these three items, the login page can take whatever shape you’d like it to. These items are also documented in the “About custom login pages” section of the doc:

  • You need to post back to the OAM server to the URI: “/oam/server/auth_cred_submit”. Note that in my sample, I’m on the same machine so I just have the URI and not the full URL, but if you are on a different server you’ll need the full URL.
  • You need to post variables “username” and “password”
  • You need code that will grab the request_id off of the query string and post it (as a hidden form variable) as well
Here is code from a sample login.jsp page that works as a external login form for OAM 11g.

Sample login.jsp:

<%@ page contentType="text/html; charset=iso-8859-1" language="java" %> <% String error=request.getParameter("error"); if(error==null || error=="null"){ error=""; } String paramName = "request_id"; String reqId = request.getParameter( paramName ); %> <html> <head> <title>User Login JSP</title> <script> function trim(s) { return s.replace( /^\s*/, "" ).replace( /\s*$/, "" ); } function validate() { if(trim(document.frmLogin.sUserName.value)=="") { alert("Login empty"); document.frmLogin.sUserName.focus(); return false; } else if(trim(document.frmLogin.sPwd.value)=="") { alert("password empty"); document.frmLogin.sPwd.focus(); return false; } } </script> </head> <body> <p>Acme Clinical Applications Login Screen - OAM edition</p> <p> &nbsp; </p> <div><%=error%></div> <form name="frmLogin" onSubmit="return validate();" action="http://auth.acme.com/oam/server/auth_cred_submit" method="post"> <p> User Name<input type="text" name="username"/><br/>Password &nbsp;<input type="password" name="password"/> <input name="request_id" value="<%=reqId%>" type="hidden"> <br/> </p> <p> <input type="submit" name="sSubmit" value="Submit"/> </p> </form> </body> </html>

22 comments:

  1. Hi Brian,

    I have few questions related to this example.
    1) An external login page should alert user about next attempt will lock the account how would you achieve that?

    2) How would you lock the account after say 3 attempt, I suppose OID will lock it once OID is made primary identity store in access manager but does not work

    3) "CSSUtil" where can I find javadoc for that?

    4) Does your example show wrong password attempt as I can see some code like class="loginFailed"

    ReplyDelete
  2. Is it possible to do RSA SecureID integration in OAM 11G using this approach? In OAM 10g there is a well document way to do it (see link below). But I can't find any info on how to do the same in OAM 11G.

    http://download.oracle.com/docs/cd/E12530_01/oam.1014/e10356/rsa.htm

    ReplyDelete
  3. Hi Brian

    Thanks for the post. It was really helpful.
    I have a couple of questions.

    1. Do I need to have webgate installed on the server where login page is hosted?

    2. I have OHS reverse proxy configured for OAM server. Do I have to install webgate on that server? What resources do I need to protect on that webgate?

    Thanks
    Kiran Thakkar

    ReplyDelete
  4. Hi Vinay,

    Thanks for the valuable post on the Custom SSO Pages for OAM 11g. I am using a HTML page for SSO. And i am using OHS as Webserver to deploy the SSO Page. Can you help me in, how to get the request ID through by using HTML.

    Thanks,
    Sandy

    ReplyDelete
  5. Sandy,

    You could try using JAVA script to take the request ID off of the query string and including it in the form as a hidden variable. Alternively, you could just make the page a perl CGI.

    Good luck.

    Brian

    ReplyDelete
  6. Kiran,

    You do not have to have the webgate installed on the web server hosting the login form or on the OHS server fronting the OAM server.

    --Brian

    ReplyDelete
  7. Vamsee,

    OOTB support for SecureID is not there yet in 11g. You should contact support or your security account team to discuss further.

    Good luck,

    Brian

    ReplyDelete
  8. Yes, I do have webgate installed on the OHS server configured as RP to OAM server. However using that webgate and Virtual host same as OAM server, I could not protect any resources. It used to throw an exception. I had to create new Virtual host for the resources I wanted to protect on OAM server.

    Why do I have to do that? It used to throw an error saying the Authentication scheme used to protect the resource does not start with http or http(s). I have used same Authentication scheme to protect other resources and it works well.

    Thanks
    Kiran Thakkar

    ReplyDelete
  9. Kiran: I had the same problem and filed a bug. I don't have the bug number, but I know it was fixed in 11.1.1.3 BP04. That patch was made after 11.1.1.5 was frozen so it didn't make it into the initial release of 11.1.1.5.

    If you are running 11.1.1.3 try applying BP04. If you are running 11.1.1.5 let me know and I can help you with a workaround.

    ReplyDelete
  10. Hi
    I am using an HTML form. Could you please provide a sample code to receive the required parameters in html.
    Thanks,

    ReplyDelete
  11. Hi
    How do I receive "request_id" in html page. please provide a sample code.
    Thanks,

    ReplyDelete
  12. Lucky,

    The request_id is just a query string parameter. The post includes sample code on how to get this with a jsp page. If you really want to use HTML you may have to figure out how to do this with javascript that runs on the client.

    Try searching for query string parameters and java script.

    --Brian

    ReplyDelete
  13. Updating my previous comment to Kiran.

    Apparently I was wrong about the releases - the redirection bug (number 11894215 BTW) was fixed in 11.1.1.3 BP 03 (i.e. 11.1.1.3.3) and it DID make it into the base 11.1.1.5 WebGate release.

    Just goes to show: don't trust everything you read on some blog.

    ReplyDelete
  14. As an FYI - Oracle has removed "request_url" from the query string. I was told it was because it seemed redundant. It seemed very useful to me.

    ReplyDelete
  15. Brad,

    Thanks for pointing it out. While the request_url is redundant to a straight forward form login (since the request_url is contained in the record associated with the request ID), I agree that it is useful in many advanced use cases.

    I will look in to having it brought back.

    Thanks,

    Brian

    ReplyDelete
  16. Has there been any progress to getting request back in 11.1.1.5 (as in patches or workarounds) ? It would be really useful!

    ReplyDelete
  17. Brian -

    I have heard from support that dev is considering this for 11.1.1.6. Hopefully, they will add this back in.

    Brad

    ReplyDelete
  18. Hi Brian,

    We have a situation where we have two sets of users; internal users who access the resource via WNA, and external users (coming from the internet) who uses the form based. Everything works great but for a small issue. For the form based authentication to work we have to make HTTP POST along with userid,password,and request_id to the OAM server directly. We'd like to keep the OAM server behind the proxy so that the HTTP POST goes to the proxy first and then come to OAM (this is for security reason). We tried changing the HTTP POST in the form from the OAM server to the proxy, but it errors out. Our setup is OAM11g with OHS being used as proxy. First, is it possible to do what we are trying to do? And, second, where else can I look to make it work. Would highly appreciate your help in this regard.

    Thanks

    Manish

    ReplyDelete
  19. Hi Brain,

    Does the user submitting the login form submit directly to the OAM server or is the submit request captured by the webgate and sent to the OAM server?

    I'm querying this because I need to know how to configure firewalls etc

    J

    ReplyDelete
  20. I got custom login page to work on IE. However, on Firefox and Chrome, I see the obrareq.cgi display the raw html page that calls the body onLoad function to load the custom login page with the appropriate parameters. Has anyone seen this?

    ReplyDelete
  21. @joker3001 The login form must post to the OAM server itself but you can put a web server (reverse proxy using WLS plug-in) in front of the OAM server.

    In any case, end users will need access to the OAM server or the web server fronting it.

    @Ravi Sounds like you might have javascript disabled on Firefox and Chrome

    ReplyDelete
  22. Thanks a ton Brian for this blog. It was very useful as we have the exactly same scenario where we need to use the existing app login page to post credentials to OAM 11g for authentication.

    However concern raised by our security folks is it is a risk to expose/proxy OAM (authentication engine) app url (/oam/server/*) through webserver to the internet.

    I think until OAM10g there was an option to post login credentials to webgate url which in-turn communicates to OAM for user authen.

    Is there an option in OAM 11g where we can submit the login credentials to Apache webgate? so we dont have to open-up the reverse proxy from webserevr to OAM server?

    My second question is: (based on some of the comments on teh blog)
    It seems request_url is removed from query string in OAM11g. How can I get an handle onto requested url as we need to do some pre-processing in login page based on the requested url.

    Appreciate your response.

    ReplyDelete

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