I'm building a lightweight web interface to SSRS where web app users are mapped to web app roles, which in turn are mapped to SSRS users.
The reason for this convoluted scheme is not up for debate: In short, AD groups can't be used, the site uses Forms auth and there are a fixed number of roles.
Web Role | SSRS User
Admin | AdminUser
Supervisor | SuperUser
User | BasicUser
Guest | GuestUser
The goal is to enumerate all reports a user has permission to view, and allow the user to view the report with the ReportViewer control.
More importantly, it's to simplify the UX for users, both admins and the rest: preventing admins from having to use the Report Manager website (ie, selecting checkboxes rather than hand-typing which web-role-users have access to which reports), and providing a simple UI from which users can see and execute all their reports.
Everything works OK when the user is the AdminUser.
However, I'm having difficulty calling the web service when the user isn't included in a Policy on the Home/Root folder with at least the Browser SSRS role. (The permissions granted to user 'computer\username' are insufficient for performing this operation.)
This is problematic for a couple reasons:
If every user must be a Browser to connect to the web service and enumerate reports they have access to view/execute, then all users will have access to all new reports/folders by default. (Children automatically inherit new permissions)
If a report exists in a nested folder that does not inherit permissions and the user is not a browser of, but the user is a Browser on the nested report, ListChildren() will not return that report.
It seems this leaves me with 2 less than ideal options:
Don't call the web service with the different users. Instead, enumerate reports with ListChildren() using only the admin user. Then, for each report, call GetPolicies(), and from that collection of policies, determine what reports the user is able to view.
Make the call with different users. Live with the pitfalls of newly-published reports being accessible to everyone by default, until permissions are changed. Also live with the pitfalls of nested reports not showing unless the user has access to that path. If an admin wants a nested report within a folder with explicit permissions to be available to a user who can't see that folder, the policies on all ancestor folders and their children must be modified.
#1 is obviously very unwieldy and inefficient. But #2 has significant drawbacks and becomes just as onerous & inefficient when setting permissions in certain situations.
Is there a better way? Have I missed something obvious?
[edit]
A 3rd option is to query the ReportServer database directly using a query like this. This has the benefit of returning everything the user has access to, regardless of whether or not it exists in a subfolder the user cannot access (aka, cannot use the web service's ListChildren method to retrieve). However, if using AD groups, I would have to know which groups the user is a member of, whereas the web service would do this for me. This option feels like a bit of a hack to me, but it could work.
As it turns out, we ran an end-route around this issue by dropping the requirement to restrict report access by web role, and made the path we query in the web service a web.config setting that can change, thus allowing report authors to 'hide' reports in a parent folder if the need arises in the future.
The best solution would have been to query the ReportServer database directly.
However, the client changed their mind & didn't want to restrict reports based on web user role in the end, so problem solved!
Related
Sorry if my English is weird.
I would like to know how a non-admin account can use the Admin SDK.
If you have any suggestions, please let me know.
I'm developing an add-on for an elementary school using Google app script.
I want to limit the API by student, teacher, grade, etc. So I need to get the organization information.
There were a few other similar questions, and apparently it would be impossible to try to do it normally.
When using the Admin SDK, Google will display an acceptance confirmation screen to the user.
Once the user agrees, Google gives the app an access token that is valid for a short period of time. I'm thinking that I can do this by using that access token. Is this approach dangerous from a security point of view?
I'm sorry for the lack of explanation.
I'm currently developing a google slides add-on for an elementary school.
It's supposed to display a SPA made with vuejs in the sidebar and let you manipulate it.
For example, we can manage a whitelist of organizations that can use this application in advance, and not allow organizations that do not match the whitelist to use it.
If the organization is managed by school unit, access control can be done by domain, but in some areas, the organization is managed by city, so access control by school unit cannot be realized...
Also.We want to do the following if we match the whitelist.
The functions that can be used by teachers and students are
different.
The buttons can be changed depending on the grade level of the
students.
Automatically enter student names and class names on slides.
Use an organizational structure to manage the school and students. (https://support.google.com/a/answer/4352075?ref_topic=4390186&hl=en)
We think we can achieve this by using the Admin SDK to get organization information
Answer
It is not possible to use Admin SDK with a non-admin account as Google says in the documentation: This API gives administrators of Google Workspace domains (including resellers) the ability to manage devices, groups, users, and other entities in their domains.
However there are two workarounds for your problem, but you would need to use an admin account to configure the scenario.
Initial approach
Get the user that is running the application with the class Session and the method getActiveUser and getEmail: var email = Session.getActiveUser().getEmail();
Get the organizational unit that each user belongs to. With this information you will be able to filter users and display different options in the add-on. The main problem is that you need to use AdminDirectory.Users.get(userEmail) to get the organizational unit, and it needs the following authorization scope: https://www.googleapis.com/auth/admin.directory.user.readonly.
Solution 1
Create a Spreadsheet with all the users that are going to use the add-on and its organizational unit
Use List all users to get all the users in a domain and write each email in the first column.
Use AdminDirectory.Users.get(email).orgUnitPath to get the organizational unit and write it in the next column
Finally, when users use the add-on, search the email of the active user (Session.getActiveUser().getEmail()) in the Spreadsheet, take the row number and get the value of the organizational unit that is in the second column.
Solution 2
Create a custom admin role and assign it to every user that is going to use the add-on. You must be signed in as a super administrator for this task. You can do it here and select Users -> Read,
Assign the new role to each user creating a role assignment
Finally, users will be able to use var organization = AdminDirectory.Users.get(email).orgUnitPath
I created a messenger application for my clients. I need to get the scope "pages_manage_metadata" to be able to set webhook for their pages.
But test user can only get these scopes
https://i.stack.imgur.com/UG6r1.png
I cannot test my application on a test user and his page because the incoming messages are not working. I can not send an approval request and write how to use my application
Please tell me how to implement this function
Test users don’t work well for stuff that is related to pages. They can not interact with any “real” pages, only pages created by the test user account itself.
Use a real user account, that you add to a role in your app (admin/developer/tester; note that “tester” and “test user” are two different things), and use that account for your testing during development. If you don’t want to interfere with any live pages that user might be an admin of, then create a new page for your testing purposes first.
My company has decided to use FreeIPA in order to make available Single Sign On feature for our employees. I am not familiar at all with Kerberos/LDAP and similar because i have never used those technologies before.
We have 70 users - they have Windows OS machines and SSO should be used for several Python (Django) web apps, WordPress web sites and possibly for Roundcube web email and OpenVPN access. They don't have access to web servers at all so SSH accounts are not important for this story.
Our python web app has database table with users' data which is in relation with some other tables and it is very important for us to have every single user added to those tables (via our web app interface) because otherwise our app will not work properly.
Having that in mind, i would like to know if there is a way somehow to reference user from FreeIPA's database to our web app's and wordpress' databases, example below:
Not every user has access to every web app and not every user has the same privileges in those apps.
We have already defined user privileges in every web app separately and everything works perfect, so main aim is just to make avaliable SSO for our users. I don't want to bother with user groups and privileges in FreeIPA system, will be i able to avoid that?
When user gets Kerberos ticket i want those web apps to recognize his/her account which is referenced to corresponding user account in FreeIPA database, and so has certain privileges in those apps.
In this scenario it is obvious that i will have to add every new user two times - in FreeIPA database and in web app's database, but that's not a problem, i just want to connect/reference those user accounts somehow.
EDIT to Michael Ströder's answer:
As i see, i would have to add every existing user manually to FreeIPA with "--uid" command because FreeIPA gives those attributes to every user automatically. I agree, i would not use user names for UID but only integers. So, i have imagined to make it like this - i would have to link every user's uid number to application's DB user's table ID column. Let say, if John has UID #7 he should also have ID #7 in WordPress wp_users table, and that looks fine to me. I think i could easily manage this in my custom python app, but i'm unsure how to manage this in WordPress, is there some plugin that could be use for such things? I've found AuthLDAP but i'm not sure if that is the right way to do it? Thanks in advance
The usual way is to have unique and persistent user names (String), usually stored in attribute uid in FreeIPA (or other LDAP servers) and use this as key in your application's DB table.
Note that uid does not contain the POSIX-UID (Integer) which is actually stored in attribute uidNumber.
I'd strongly recommend not to derive user names stored in uid from personal names because these often change. Also you should never reuse user names.
FreeIPA also has attribute nsUniqueId which contains a UUID generated during creation of the entry. It will not be modified during life-time of the entry. If you want to use that you have to take care that entries are not deleted/re-created by an external identity management systems all the time.
(Other LDAP servers are using standard attribute entryUUID).
I have created a login app that is responsible for the login of other five applications. So when the user correctly authenticates in the first login, he can access all the other apps.
I have achieved this using the same cookie name for the login app and all the other applications.
But only one of this applications must be accessible from the outside
too, and not only from the login page. So it must have his own login page.
Question:
Is there a way to make this application accessible in two ways?
One way coming from the login application and the other way from its own login page?
Or I must have two separate applications?
Thanks.
So, this "login app" is used as a menu which enables users to access 5 different applications. Those are, I suppose, Apex applications.
If that's so, make the link (i.e. URL) to the one that has to be accessible "outside" of the login app available to users separately. All of URLs are the same, aren't they? You only change the APP_ID value.
Now, the problem might arise with the way of authentication. How did you do that? If it is user-defined, and "available" only in the login app, then you'll have to make it available to that separate application as well. Otherwise, users won't be able to connect to it. Lucky for you, you can create a new authentication scheme as a copy of existing one.
Though, underlying database objects (such as table that stores usernames and passwords, functions and procedures used to create new users and fetch data about existing ones, password validations etc.) will also have to be accessible to another database user. That can be done by granting appropriate privileges (SELECT, INSERT, UPDATE, DELETE on table(s), EXECUTE on stored procedures).
Therefore, no - I don't think that you should maintain two exactly the same copies of that application to make it work.
I have two different objects in my API, we can call them users as tasks. I want to shape the API so users can only access tasks associated with them, but admin can access all tasks. How would I check to make sure what they are requesting matches their username? I have login working as per http://code.tutsplus.com/tutorials/building-rest-apis-using-eve--cms-22961 but I'd like to be able to create a more encompassing API.
You might resort to User Restricted Resource Access
When this feature is enabled, each stored document is associated with the account that created it. This allows the API to transparently serve only account-created documents on all kinds of requests: read, edit, delete and of course create. User authentication needs to be enabled for this to work properly.
See the relevant documentation at the link above.