Sql 使用自定义身份验证跟踪用户ID

Sql 使用自定义身份验证跟踪用户ID,sql,authentication,plsql,session-variables,oracle-apex,Sql,Authentication,Plsql,Session Variables,Oracle Apex,我目前正在apex.oracle.com上制作一个应用程序,我已经尝试解决这个问题好几个小时了,但我不知道如何解决 好的,基本上我的应用程序具有基于我在应用程序内部创建的用户表的自定义身份验证。因此,它似乎使大多数APEX_UTIL函数无法检索当前用户的信息。问题是,我正在尝试在会话中从我的表中存储用户的数字ID,这样我就可以在整个应用程序的查询中直接检索它,以便执行类似于WHERE ID=:MEMBER\u ID的操作,而不是WHERE UPPER(username)=UPPER(:APP\u

我目前正在apex.oracle.com上制作一个应用程序,我已经尝试解决这个问题好几个小时了,但我不知道如何解决

好的,基本上我的应用程序具有基于我在应用程序内部创建的用户表的自定义身份验证。因此,它似乎使大多数APEX_UTIL函数无法检索当前用户的信息。问题是,我正在尝试在会话中从我的表中存储用户的数字ID,这样我就可以在整个应用程序的查询中直接检索它,以便执行类似于
WHERE ID=:MEMBER\u ID
的操作,而不是
WHERE UPPER(username)=UPPER(:APP\u user)

现在,我尝试这样做的方法是创建一个身份验证后过程,该过程基于用户名检索用户ID,并使用
APEX\u UTIL.SET\u session\u STATE(p\u name=>'MEMBER\u ID',p\u value=>MEMBER\u ID)
将该值存储在会话中。但是,
SET\u SESSION\u STATE
似乎无法创建自定义会话值或其他内容,每次我使用文档中未特别提到的值名称时,都会返回一个
ERR-1002

我是APEX的新手,所以我可能不知道什么,但是我做了很多搜索,但是我找不到任何与我的问题相关的东西


非常感谢您的帮助。

您正在尝试将值存储到项目中,无论是页面还是应用程序级别。这要求具有该名称的项存在于其中一个作用域中。那么,您是否有一个名为
MEMBER\u ID
的项目?

我建议您在应用范围内创建一个。浏览共享组件>应用程序项。创建后,您应该能够通过
apex\u util.set\u session\u state
或使用绑定变量语法(例如
:MEMBER\u ID:=somevariable)分配值

您正在尝试将值存储到项目中,无论是页面还是应用程序级别。这要求具有该名称的项存在于其中一个作用域中。那么,您是否有一个名为
MEMBER\u ID
的项目?

我建议您在应用范围内创建一个。浏览共享组件>应用程序项。创建后,您应该能够通过
apex\u util.set\u session\u state
或使用绑定变量语法(例如
:MEMBER\u ID:=somevariable)分配值

有很多方法可以做到这一点。其他答案中已经提出了一些建议

  • 申请项目(根据Tom的回答)

  • PL/SQL包全局(根据hol的回答)-尽管您必须为每次调用重置它(例如,通过向应用程序的安全属性添加代码初始化PL/SQL代码,并通过向清除PL/SQL代码)添加代码来清除它)

  • 全局可访问上下文-此方法虽然有点复杂,但有一些好处,特别是在安全性和调试方面。我在这里描述过:,但基本上:

  • 创建全局可访问的上下文:

    CREATE OR REPLACE CONTEXT MY_CONTEXT USING MY_PACKAGE ACCESSED GLOBALLY;
    
  • 在后身份验证过程中(在数据库包
    MY_包
    中),您可以存储希望跟踪的数据,例如:

    DBMS_SESSION.set_context
      (namespace => 'MY_CONTEXT'
      ,attribute => 'MEMBER_ID'
      ,value     => '12345whatever'
      ,client_id =>  v('APP_USER') || ':' || v('APP_SESSION'));
    
    (请注意我的博客文章中的警告以及其他人随后关于在后期授权阶段未可靠设置客户机_标识符的评论)

  • 在视图、代码等中,只需参考
    SYS\u CONTEXT('MY\u CONTEXT','MEMBER\u ID')
    即可访问成员ID


  • 有很多方法可以做到这一点。其他答案中已经提出了一些建议

  • 申请项目(根据Tom的回答)

  • PL/SQL包全局(根据hol的回答)-尽管您必须为每次调用重置它(例如,通过向应用程序的安全属性添加代码初始化PL/SQL代码,并通过向清除PL/SQL代码)添加代码来清除它)

  • 全局可访问上下文-此方法虽然有点复杂,但有一些好处,特别是在安全性和调试方面。我在这里描述过:,但基本上:

  • 创建全局可访问的上下文:

    CREATE OR REPLACE CONTEXT MY_CONTEXT USING MY_PACKAGE ACCESSED GLOBALLY;
    
  • 在后身份验证过程中(在数据库包
    MY_包
    中),您可以存储希望跟踪的数据,例如:

    DBMS_SESSION.set_context
      (namespace => 'MY_CONTEXT'
      ,attribute => 'MEMBER_ID'
      ,value     => '12345whatever'
      ,client_id =>  v('APP_USER') || ':' || v('APP_SESSION'));
    
    (请注意我的博客文章中的警告以及其他人随后关于在后期授权阶段未可靠设置客户机_标识符的评论)

  • 在视图、代码等中,只需参考
    SYS\u CONTEXT('MY\u CONTEXT','MEMBER\u ID')
    即可访问成员ID


  • 非常完整的答案!我自己并没有真正想过使用初始化plsql代码设置包变量,但我不确定我是否会这样做,除非我被迫这样做(对于包变量,我的意思是)。在我看来,应用程序项或上下文已经足够了。初始化/清除PL/SQL代码很有用,但需要谨慎对待,因为它对数据库的每个调用(即每个页面请求)都运行一次。就我个人而言,我更喜欢使用应用程序项或上下文。非常完整的答案!我自己并没有真正想过使用初始化plsql代码设置包变量,但我不确定我是否会这样做,除非我被迫这样做(对于包变量,我的意思是)。在我看来,应用程序项或上下文已经足够了。初始化/清除PL/SQL代码很有用,但需要谨慎对待,因为它对数据库的每个调用(即每个页面请求)都运行一次。就个人而言,我更喜欢使用应用程序项或上下文。是的,这正是我最终使用的,作为som