Issues and clarification regarding O365 APIs - azure

I have been working with the O365 APIs and found some weaknesses. I understand we are in preview, I just want to confirm the following, thanks.
There is no expiration information returned with the AuthenticationInfo object. It seems the suggested pattern is to get an AuthenticationInfo object before each call.
The SharePointClient class only supports files, not lists or other resources at this point.
The AuthenticationInfo class cannot be used to secure an entire web application. Instead, each application must authenticate users as appropriate and then use AuthenticationInfo to make subsequent calls to O365.
As an interesting side note, I tried to combine MVC5 "Organizational Accounts" authentication with the AuthenticationInfo class and the application made endless round trips to Azure AD without ever returning a token. Is there some conflict between MVC5 Organizational Account authentication and AuthenticationInfo behavior?

On the AuthenticationInfo object expiration - it expires when the refresh token does, which should be a least two weeks. The AuthenticationInfo.GetAccessToken delegate implementation keeps track of the issuance time and validity of access tokens and makes sure to refresh them automatically when they are nearing expiration.
Re: SharePointClient and Lists, etc.
You are entirely right. This was a scoping decision for this release, but we will be adding support for lists in near future.
There is not supposed to be any conflict between "Organizational Accounts" and AuthenticationInfo.
I just tried using the combo and it worked fine from project creation (using single organization and read-write access to data) through F5. I had to make sure the project had a unique name because otherwise, the web project was picking up a redirect URL from an old registration. That was unrelated to Office 365 APIs, though.

Related

Suggestion required on how to implement a better permission system

I have a user permission system in place where i have a set of permissions within the database, for example
id
Permission
1
POST:CreateBooking
2
GET:AllBookings
And i have another table (junction table) where i put dependent permissions such as
if i want to create a Booking, i need to fetch Package details and so POST:CreateBooking requires the user to also have GET:AllPackages permission.
There's a template system in place as well, where the users can group multiple permissions together and once that template is assigned to any employee, that employee will get THAT set of permissions and it's dependent permissions.
What my nodejs system does is that when user logs in, it fetches all permissions from DB and puts it in a redis set from where on each request, the permission is checked against user id.
Is there any tool from where i can do exactly this but in an intuitive and better way?
I tried keycloak but i don't know how to cover my needs mentioned above.
Thank you
if I'm understanding correctly and trying to generify your scenario, you have a classical situation where:
You have groups which can have multiple permissions assigned;
groups can be created dinamically;
each permission correspond to a specific functionality.
So, implementing the OIDC (Open Id Connect) protocol might fit you needs. As you suggested youself you might be interested in a OpenID provider (do not reinvent the wheel) keycloak is good, you can give a look also to Vault Hashicorp.
So assuming that your backend have an already existing framework to handle security and permissions (eg. Spring Security) you can produce JWT token with the OpenId provider and check throught PreAuthorize claims (permissions) inside the token.
At the end your security layer it's just an annotation you need to insert before your method controller or before you class controller.
Behind the scenes, instead, this is what will happen:
Your user connect to your app;
User insert username and password -> the Open Id provider gives you a JWT
Your Front End app everytime it make a REST req will send also the JWT
The back end controller method called it's under authorization
Given the public keys of the OpenId provider, the validity of the token it's enstablished
If the specific permission claim it's found inside the token, the request can be elaborated else a 403 Forbidden it's returned.
OIDC - as the conceptual model/backdrop to any tool of choice, is certainly a popular/good choice, but as long as you're willing to deal with an element of complexity - the understanding required to implement an OIDC arrangement (- think of it as a possible investment - effort up front with hopefully the rewards tricking-in over time); e.g. OIDC is an ideal choice for supporting SSO (Single Sign On), especially when it comes to supporting/allowing for authentication/login via providers such as Facebook, LinkedIn & Google, etc (- as well as more Corporate OPs (OIDC Providers) including AAD/Azure AD).
Try to first step-back, and consider the possible bigger/future picture, before selecting a tool based upon only your starting/current requirements.

Migrating Users From Facebook's "Raw" Authentication to Firebase Based Facebook Authentication

I am working on a project which needs User Authentication. The "Clients" are iOS (Swift) or Android (Kotlin) native applications. The original form of the API (NodeJS) used Facebook and Account Kit for OAuth and Phone authentication respectively. Since Account Kit shutdown, we moved to Firebase Phone Authentication for Phone but left Facebook in its original form. Now, we're wanting to consolidate our Authentication providers (to Firebase) but I can't seem to find a way to "convert" or "import" Facebook users to Firebase-based Facebook users.
So far, I've read through the Documentation, including the category about importing users, but it doesn't seem to indicate an ability to maintain backwards compatibility, while also moving forward to Firebase. What I mean is, it has an ability to set information, but it doesn't indicate that the same information will be used to authenticate that user as the same unique visitor.
What I am looking for is either transitory logic, which will handle this during login, or preferably, a "bulk-insert" type migration. Essentially, I want to have it setup so that the API only needs to keep a single authentication UID, and use only a single third party (even if they then use another subsequent third party) while maintaining user uniqueness (so that it doesn't create a new user for the same Facebook account).
Part of my problem in creating a temporary patch (not necessary if the main question is answered) is that I don't know of a way to differentiate between a Facebook UID and a Firebase UID to fork the logic. Again, this is only relevant if there isn't a solution for migration.
Feel free to request any more details that would be useful.
Update #1
I realized my question was open ended in what I was asking. I've been digging further and can better define my question:
I need a way to bulk insert users into Firebase's Authentication with a provider of Facebook. I know I can import them, via admin.auth().importUsers([...]) and that I can create accounts via admin.auth().createUser({...}) but when I do the former I can't seem to get back the user's UID, and the latter doesn't seem to allow specifying a provider. Am I missing something?

Implementing Two Factor Authentication on Liferay DXP 7.2

I am using Liferay DXP 7.2 and I need to implement Two Factor Authentication.
My problem is that when a user logs in into the portal, he can immediately access all the private pages.
I'm searching for a way to log in, redirect the user to a page where he needs to submit the code sent to him and only after that grant access to the private pages.
I thought of an idea to add and remove roles in the first and second authentication but I was required to find a better way without changing the user's role.
Any suggestions?
You can try having a portal filter which checks for the second authentication ,
if second authentication is not done you can redirect to a page where second authentication will happen. with this at anytime second authentication is kept in check .
After second authentication you can save the it in session or db as per your requirement and clear it on logout/session timeout .
For Portal filter you can refer below.
https://portal.liferay.dev/docs/7-1/tutorials/-/knowledge_base/t/servlet-filters
Thanks
If you want two different levels of access, you'll end up adding and removing roles one way or another - most likely. I recommend not going the route of implementing your own permission checker (while it's possible to do so, it's quite complex and it's easy to make mistakes, leading to unintended sideeffects.
If you want a single level of access, but two factor authentication, my recommendation is to go through a SSO system that can do so. As soon as you're authenticated, you can grant the full permissions and access the portal.

Obtaining Instagram Access Token

We have a client who has a simple Instagram feature on the site to pull photos by a certain tag. They just noticed it isn't working. Getting an error - invalid access token. I guess since the 1st because of the updates. We didn't used to need an access token since we're not doing anything with users - just tags.
Now it looks like we need one and the documentation makes zero sense on how to obtain one. And it seems like they're not accepting most apps. The app is in sandbox mode too. So I'm assuming it's because it got switched to that? Got no notification of this happening.
The first step in documentation to get an access token is "Direct the user to our authorization url." What does that even mean? There's not a link provided or anything. It also says "Company Name, Contact Email and Privacy Policy URL are required to start a submission." Our app doesn't have a privacy policy... it's just a simple tag feed. I don't understand why everything is so complex to have a simple tag feed.
Is there a wait time to get the app approved..if it gets approved... Do I have to have it approved before getting an access token? This isn't outlined anywhere.
You got it right. As of June 2016 any Instagram API calls require an access token.
Getting an access token is described in the documentation. App approval is not required.
There are two ways to get one: server-side or client-side. The second option (called implicit authentication) can only be used when implicit OAuth is enabled in the client settings (Manage Clients > Edit Client > Security > Disable implicit OAuth). It is disabled by default.
In either case you need to redirect the user to the authorization URL to obtain an access token.
The URL for explicit mode (server side) is:
https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=code
The URL for implicit mode (client side) is:
https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=token
After this you will be redirected to the REDIRECT-URI, which will be passed an argument. For explicit mode this will be a query string with a code, while for implicit mode you will get the access token directly as a hash:
http://your-redirect-uri?code=CODE
http://your-redirect-uri#access_token=ACCESS-TOKEN
For implicit mode you can then get the access token from the window.location.hash in Javascript.
For explicit mode, however, you need to further process the code to obtain the access token. You can read how this can be done in the API Documentation. I'm not going to take this any further here.
The problem is that every user who wants to see your feed needs to login to Instagram (and have an account) in order to view it. In your case this might not be desired. However, there are a few options to get around this (rather annoying) problem:
You can reuse your own (already obtained) access token(s) to display the Instagram feed for every user. You will need to be aware of rate limits for each token. For sandboxed apps this is 500 API calls / hour, while live mode allows 5000 API calls / hour. [source] You could store tokens in a table and use them in a round-robin manner, to allow more API calls. This involves manually obtaining a bunch of tokens which your application can use (the more the better). This might not be the ideal solution considering Instagram doesn't warrant access tokens to have an unlimited lifetime.
You can retreive JSON data without authentication by appending /media/ to a user page URL, as described in this post. No tokens or client IDs are required for this to work. However, this only works for users, not for tags. Besides, Instagram doesn't document this feature so it is not garanteed to work in the future.
You can use an aggregator like Juicer or Dialogfeed instead which will handle access tokens for you. This is usually not free of charge.
I'm also in the process of making an Instagram feed for my website, and this is what I concluded from my research. Please bare with any errors I made.
Edit: Here are some more limitations for sandbox apps.
In sandbox mode you can only access data from sandbox users (thus users who received a sandbox invite). This means that:
Media retreived by user, e.g. /users/{user-id}/media/recent, will return an empty response if the user is not any of the sandbox users.
Media retreived by tag, e.g. /tags/{tag-name}/media/recent, will only contain tagged media belonging to sandbox users.
Thus, for a tag feed to work, it needs to be live (reviewed and approved). If you don't want to do this, the only alternative is to use an aggregator as I mentioned above.

Caching per-user principal objects for service calls from a plug-in

I have a Microsoft Dynamics CRM implementation (either 2010 or 2011 in not 100% sure). This CRM system needs to call our internal service framework services from plug ins.
In order to call the service framework we use an API with a login method that goes to an STS and gets a security token. This is per user to authenticate and get that users claims. The login call returns an IPrincipal object that we put on the Thread.CurrentPrincipal property and from then on we can call services with our framework and the user is authenticated for each call because of the principal on the executing thread.
In an asp.net website we usually log the user in and immediately go to the STS to get a token, then cache that token for the user in session because the login is not something we want to do every time we want to call a service.
How would I do this with a CRM plugin. Do I have access to a per user session store? I noticed IServiceProvider is passed in as a parameter, can I add services to this container and solve this problem in a service with a thread safe dictionary of some kind? I know very little about CRM development and Im even wondering if a plugin is the right way to do this?
The plugin is created and cleaned on a regular basis, you wouldn't be able to store anything for any period of time (or at least store it and rely on it being there).
You could potentially store this in a custom entity though if that is something that is possible?
e.g.
- Plugin is called for x event
Get CallingUser from Plugin
Search for MyCustomSTS entity for the User
See if Token exists and/or has expired
If you have the token - hooray
If not, run off and grab one
This may, of course, take longer than reauthenticating each time!
Is the token you are fetching for individual users or for the service account?
Ideally you should write your plugin to be stateless.
Write a Plug-In
For improved performance, Microsoft Dynamics CRM caches plug-in instances. The plug-in's Execute method should be written to be stateless because the constructor is not called for every invocation of the plug-in. Also, multiple system threads could execute the plug-in at the same time. All per invocation state information is stored in the context, so you should not use global variables or attempt to store any data in member variables for use during the next plug-in invocation unless that data was obtained from the configuration parameter provided to the constructor. Changes to a plug-ins registration will cause the plug-in to be re-initialized.
If you are fetching a token for individual users you could save that in CRM somewhere but that approach has a number of problems as glosrob suggests. In this case its probably just best to authenticate every time.
If its for the service account, you could go against the recommendations of Microsoft and cache the token in memory. Logically as long as your write your code to be happy with randomly loosing and having to reacquire its token you should be okay.
I agree with people who says that each time authentication is better solution, but if you need storage for tokens, you can create custom CRM entity and write logic which will work with tokens stored in CRM from plugins.

Resources