External authentication and deep linking
507803Jul 5 2007 — edited Jul 6 2007Can someone explain deep linking to me? All of the information I can find on this seems to come from a time before session info was required in the links. How do I link into an APEX app when I don't know the session info? This app has an "automatic" login based on the headers that are tacked on by the security proxy that handles logins.
I have a custom page sentry; my Apex app is only accessible via a security proxy that sets a username in the header. So, if you can get to my app, you're authenticated. My page sentry then just checks if that authenticated user is in it's user table, inserts if not, and then sets some application items with some info from the user table. I just modified the mod_nmlt example to do this (and I have noooooo idea what some of that example is doing, so I left it alone as much as possible).
I can make a link that has a recent sessionid in it, and then a new sessionid gets generated and it works as I hope, but otherwise I get "null sessionid" or "page not found" errors, depending on what I try to stick in for bogus sessionid.
Here's my page sentry:
create or replace FUNCTION Custom_Page_Sentry_Func (p_htmldb_user VARCHAR2 DEFAULT 'APEX_PUBLIC_USER' )RETURN BOOLEAN AS
l_authenticated_username VARCHAR2(256) := nvl(UPPER(OWA_UTIL.GET_CGI_ENV('HTTP_IV_USER')),'NOT_AF_AUTH');
IS_USER NUMBER := 0;
L_CURRENT_SID NUMBER;
v_userid NUMBER;
v_user_baseid NUMBER;
v_user_basename VARCHAR2(4000);
BEGIN
--The server is behind the login system, so if the ApEx pages are shown, the login has succeeded (and we will find the cookie)
-- If logged in user is not a app user (doesn't exists in USERS table)
-- THEN insert into app user table
SELECT COUNT(*)
INTO IS_USER
FROM USERS
WHERE UPPER(USERNAME) = l_authenticated_username ;
IF IS_USER = 0 THEN
INSERT INTO USERS (USERNAME,USERSTUFF) VALUES (l_authenticated_username,'111111111');
END IF;
apex_application.g_user := l_authenticated_username;
SELECT USERID, BASEID, BASENAME INTO v_userid, v_user_baseid, v_user_basename FROM USERS
LEFT OUTER JOIN CONTACT_PROFILES USING (USERID)
LEFT OUTER JOIN BASES USING (BASEID)
WHERE upper(USERNAME) = l_authenticated_username;
apex_util.set_session_state('F105_USERID', v_userid);
apex_util.set_session_state('F105_USER_BASEID', v_user_baseid);
apex_util.set_session_state('F105_USER_BASENAME', v_user_basename);
L_CURRENT_SID := WWV_FLOW_CUSTOM_AUTH_STD.GET_SESSION_ID_FROM_COOKIE;
IF WWV_FLOW_CUSTOM_AUTH_STD.IS_SESSION_VALID THEN
-- session is valid
WWV_FLOW.G_INSTANCE := L_CURRENT_SID;
IF l_authenticated_username = WWV_FLOW_CUSTOM_AUTH_STD.GET_USERNAME THEN
WWV_FLOW_CUSTOM_AUTH.DEFINE_USER_SESSION(P_USER => l_authenticated_username ,
P_SESSION_ID => L_CURRENT_SID);
RETURN TRUE;
ELSE
-- username mismatch. Unset the session cookie and redirect back here to take other branch
WWV_FLOW_CUSTOM_AUTH_STD.LOGOUT(P_THIS_FLOW => V('APP_ID'),
P_NEXT_FLOW_PAGE_SESS => V('APP_ID') || ':' ||
NVL(V('APP_PAGE_ID'),
0) || ':' ||
L_CURRENT_SID);
WWV_FLOW.G_UNRECOVERABLE_ERROR := TRUE; -- tell htmldb engine to quit
RETURN FALSE;
END IF;
ELSE
-- application session cookie not valid; we need a new htmldb session
WWV_FLOW_CUSTOM_AUTH.DEFINE_USER_SESSION(P_USER => l_authenticated_username ,
P_SESSION_ID => WWV_FLOW_CUSTOM_AUTH.GET_NEXT_SESSION_ID);
WWV_FLOW.G_UNRECOVERABLE_ERROR := TRUE; -- tell htmldb engine to quit
--
IF OWA_UTIL.GET_CGI_ENV('REQUEST_METHOD') = 'GET' THEN
WWV_FLOW_CUSTOM_AUTH.REMEMBER_DEEP_LINK(P_URL => 'f?'
|| WWV_FLOW_UTILITIES.URL_DECODE2(OWA_UTIL.GET_CGI_ENV('QUERY_STRING')));
ELSE
WWV_FLOW_CUSTOM_AUTH.REMEMBER_DEEP_LINK(P_URL => 'f?p=' ||
TO_CHAR(WWV_FLOW.G_FLOW_ID) || ':' ||
TO_CHAR(NVL(WWV_FLOW.G_FLOW_STEP_ID,
0)) || ':' ||
TO_CHAR(WWV_FLOW.G_INSTANCE));
END IF;
--
WWV_FLOW_CUSTOM_AUTH_STD.POST_LOGIN( -- register session in apex sessions table, set cookie, redirect back
P_UNAME => l_authenticated_username ,
P_FLOW_PAGE => WWV_FLOW.G_FLOW_ID || ':' ||
NVL(WWV_FLOW.G_FLOW_STEP_ID,
0));
RETURN FALSE;
END IF;
--RETURN TRUE;
END Custom_Page_Sentry_Func;