I have a couple of situations where I can't seem to get the authorization component working as I need it to work for a database source.
1) In the first case, I have two attributes set for "grant security attributes" in the data source, one of which has a single attribute value, and the other which has multiple values, e.g.
I want to set "grant security attributes" to something like "client_id role_id" where for my dataset, client_id will always be a single numeric value, but I might have multiple role_ids that can view this record. How do I specify in my data source query those multiple attribute values? I tried separating them with spaces, e.g.
'A B' role_id
where "A" and "B" represent unique values (looking to match A OR B). I also tried delimiting them with commas, but neither spaces nor commas seems to work consistently.
On the authorization end, using oracle.search.plugin.security.auth.db.DBAuthManager as the authorization plug-in, I have the authorization query set as
SELECT client_id, security_lvl as role_id from test_user_id where user_id = ?
Each user may have more than one role, so in the above query, security_lvl could be something like "B C"; I'm assuming from the documentation that the delimiter for attribute values in this case should be a space.
The crawler logs make it appear that everything is getting indexed, so I suspect the issue is on the authorization front.
2) In the second case, one of my security attributes for the data source may be NULL, meaning that there's no particular authorization restriction on a particular record, so to use the same example as in #1,
role_id might be NULL for some records, in which case, I want those records returned in the search if the client_id matches, but I can't get the records with the NULL role_id to be returned at all. Again, the crawler logs indicate that everything is being indexed, and I'm not sure if there's a log where I can further troubleshooting authorization issues.
Any guidance would be appreciated.
1) The security attributes are OR'd together so if the user has any ONE of the attributes (either client ID or role ID), the document can be seen by the user. What I would try is to create a view to call rather than directly against the table. The view can then leverage a PL/SQL function and encapsulate the logic behind the security tokens to return.
So the view would look like this...
CREATE OR REPLACE VIEW USER_SECURITY_V AS
MY_SECURITY_FUNCTION(USER_T.ID) AS AUTH_ID
The PL/SQL function would look something like this...
CREATE OR REPLACE FUNCTION MY_SECURITY_FUNCTION(USER_ID NUMBER) RETURN VARCHAR2 IS
-- Do whatever you need to do to build a single space-deliminted list of tokens for both Client and Role ID "CLIENTID4 ROLEID5 ROLEID9" then return
The data source authorization query then would look like this...
SELECT AUTH_ID FROM USER_SECURITY_V A WHERE A.ID = ?
Using a PL/SQL Function to control the tokens gives you the flexibility of modifying security without having to touch the data source directly
2) I don't quite follow. If any ONE of the tokens match, the document is returned. If the role ID is null, you might try stamping each document a "master" security token indicating it's open to everyone such as "ALL". Then in the PL/SQL Function, return "ALL" in front of the actual values.
The crawler logs will only tell you what is indexed at crawl time, not how searching is actually working. Try checking the server logs. These should be under something like oracle/ses/seshome/search/base_domain/servers/AdminServer/logs
Hope this helps!
I think you'll find that if there are multiple security attributes (rather than multiple values for the same attribute) then the attributes are ANDed - the user must have a match against BOTH / ALL of the security attributes.
Within any attribute, the values should be space-separated as Stephen says.
Thanks Roger for clarifying, great point. In the past I have used a single security attirbute with multiple values and if the user was found to have any of them, then the document was returned.
So each document was tagged with one or more security tokens in a single columns, including a master "ALL" token such as...
"ALL SECTOKEN1 SECTOKEN2 SECTOKEN3..."
In this case the values are OR'd together. The Function would check who the user was (Admin, Super User, Manager, etc) based on their employee information and returned the appropriate tokens.