Traffic decoration with user-agent header in sharepoint online - microsoft-graph-api

What should be the value of User-Agent header in the http request to microsoft graph api? Based on this documentation, the decoration string format for Enterprise Application is like:
User-Agent = NONISV|CompanyName|AppName/Version
However when we register an app, we have AppId and App title(or display name) which is not consistent with what the decoration string is expecting?
Some other blogs mentioned that just the presence of the user-agent header string is important and not the value?

The User-Agent doesn't really factor into anything when it comes to the Microsoft Graph API - just make it something that identifies your application.

Related

Can the OIDC "jwks_uri" URI defined in the "/.well-known/openid-configuration" be cached?

I'm writing a service which requires OIDC. I've seen a number of client libraries (the programming language and library here is irrelevant) which allow auto-refreshing/re-fetching the content at the "jwks_uri" endpoint which is defined in the discovery document at the IdP's "/.well-known/openid-configuration" endpoint.
I know the content defined at the actual "jwks_uri" endpoint can change. But can the value of this "jwks_uri" (the URI itself) change in the discovery document? I can't seem to find any answer in the specs.
Yes it can be cached. For example some clients (like in .NET) do for example cache this information (including the singing keys) and refresh this information every 24 hours.
If you validate your token remotely (in the IDP side) yes you can cache the content of .Well-known for ever, in the most case the endpoints of your IDP will never change, but if you validate your token locally, you need the last keys in IDP side, and you need to know the frequency change of keys in your IDP, basing on that you can cache your keys.

Extract Twitter using RapidMiner - Going beyond the limited "Search Twitter" Operator

I already have an account in Twitter Dev, which allowed me to get a Consumer Key and secret, which I used to generate my token. Now I am trying to send token in request for Twitter API by using the operators "Get Page", "Jason to XML" and "Write Document". However, I do not know which URL to write in the "Get Page" operator. Is it Request token URL Authorize URL or Access token URL ?
In general the request URL contains the REST API call, while you are providing your authorization credentials e.g. via request properties in the HTTP header, OAuth mechanisms and the like. An REST API call is build up on a base URL awaiting a call, in case of twitter https://api.twitter.com/1.1/search/tweets.json, combined with a state and HTTP options forming your request. If your searching for tweets from a given user account (like #twitterapi) your request URL part would look like q=%40twitterapi. Here a key q is given with the value %40twitterapi, where %40 is a representation of the '#' symbol.
Providing key-value-pairs via GET using the HTTP protocol is initialized with a leading '?'. Hence your REST request would look like this:
https://api.twitter.com/1.1/search/tweets.json?q=%40twitterapi. This example is taken from the Twitter documentation.
That's about the URL.
For the RapidMiner site, I'd try to use the Enrich Data by Webservice operator. You can fill in the url parameter with your request URL and set the HTTP header for using an authentication token using the request properties parameter. As a property use Authorization and for the value you use a string starting with Bearer followed by your token. So a potential value could be Bearer 943582034-IH3k6hlskfdj32l4hks.
You can choose betweent different query types (e.g., String Matching, Regular Expression and others) to define the handling of the received payload given as an response to your request.
Before playing around with the operator, you can try using a tool like Postman (Chrome Plugin) or HTTPrequester (Firefox Add-on) to work directly with the HTTP GET request and its response.
Sorry for not including more references, but Stackoverflow doesn't allow for more than two if your reputation is below 10...
I concur with the above - use the Enrich Data via Webservice operator. You'll need to download the Web Mining extension in order to see it. If you re-post on the RapidMiner user community forum, you may get more RapidMiner-specific help as well.

401 when accessing Dynamics CRM 2016 Web APIs

I am struggling to access the Dynamics 2016 CRM OData Web APIs from a console application.
We have Dynamics CRM 2016 installed, configured with Claims-based authentication, and using AD FS v3.0.
My understanding is that a console app (or web app) should be able to access the Web APIs using Windows integrated authentication (i.e. NTML or Kerberos) without any special treatment ... or maybe the OAuth flow should work when enabled.
For a regular user accessing Dynamics "pages", the authentication works fine (redirection to AD FS log in page), but accessing the OData APIs does not seem to work (for instance : https://crm.domain.org/api/discovery/v8.0/ ) :
in a browser I get a Windows login prompt and typing valid credentials always results in a HTTP 401 unauthorized error
in a brower, if I navigate to a Web API url after having logged on on the pages , then I can access the Web APIs (i.e. some cookies must be set and I am already implicitly authorized)
from code, using an HttpClient with specific valid credentials (or current credentials) , I also get a 401
Things I have tried :
if I disable Claims-based authentication completely , HttpClient works fine and I can access the OData APIs
if I leave Claims-based authentication enabled, and activate OAuth via PowerShell Add-PSSnapin Microsoft.Crm.PowerShell ; $ClaimsSettings = Get-CrmSetting -SettingType OAuthClaimsSettings; $ClaimsSettings.Enabled = $true ; Set-CrmSetting -Setting $ClaimsSettings ;.
Windows integrated authentication still does not work, but using Bearer authentication is now possible. I can use this snippet to retrieve the OAuth Endpoint for token generation, and use AuthenticationContext.AcquireTokenAsync to issue a token, and then pass it in the Authorization HTTP Header ... but then, no matter what, I get this error :
Bearer error=invalid_token, error_description
=Error during token validation!, authorization_uri=https://our.adfs.domain.org/adfs/oauth2/authorize, resource_id=https://crm.domain.org/
Am I missing something ? is that possibly a configuration issue ?
From this answer from the dynamics community forum, it looks like the api is pretty strict about the parameters and headers it requires. When doing the request, make sure you have the Cache-Control: no-cache and Content-Type: application/x-www-form-urlencoded headers set.
In the subsequent request to access the api with the retrieved token you should set the Authorization header in the form of Bearer: TOKEN (worth noting since a lot of people actually thought they could directly put the token), the OData-Version: 4.0, Cache-Control: no-cache and Accept: application/json ones too.
Looking at the different OAuth endpoints and the previously linked answer, I'm not sure the authorization uri is the right one (eg https://login.windows.net), so do you make sure that's correct. It's also stated that you should use the OAuth endpoint url and use the WWW-Authenticate header that returns the valid one, even if this route will respond with a 401. I'm sure you already saw this example, but it provides a pretty complete overview of an auth flow and how the token is retrieved using AcquireTokenAsync where you pass your resource and clientID. I might also be looking at an updated page and it's not relevant in your case.
You also want to check if the resource id you specified is the correct one, some people reported to have to specify one in the form of https://crm3.domain.org/ or https://crm4.domain.org/ instead of the bare one, so that could be one thing.
It could also be a configuration issue, given what #l said about the fact an IP would work instead of the domain name. It could very well be a certificate problem, where it's not validated correctly or untrusted, thus creating the error you see even if it's not the appropriate message. Also make sure your 443 port is allowed through your firewall(s).
One interesting post where the author explains that the Form Authentication setting of the AD FS Management Console was required for him to proceed (it's CRM 2013, but might still be related).

Why do I need to follow the OAuth spec/guidelines?

I feel silly even asking this question, but am at the limits of my understanding, and am hoping someone can provide some context.
I'm looking at the following (https://stormpath.com/blog/token-auth-for-java/) which states:
The access_token is what will be used by the browser in subsequent requests... The Authorization header is a standard header. No custom headers are required to use OAuth2. Rather than the type being Basic, in this case the type is Bearer. The access token is included directly after the Bearer keyword.
I'm in the process of building a website, for which I'll be coding both the back-end REST service, as well as the front-end browser client. Given this context, why do I need to follow any of the guidelines given above? Instead of using the access_token, Authorization and Bearer keywords, what's stopping me from using any keywords I like, or skipping the Bearer keyword entirely in the header? After all, as long as the front-end and back-end services both read/write the data in a consistent manner, shouldn't everything work fine?
Are the keywords and guidelines given above merely best-practice suggestions, to help others better understand your code/service? Are they analogous to coding-styles? Or is there any functional impact in not following the above guidelines?
Given this context, why do I need to follow any of the guidelines given above?
Because they are standardized specifications that everyone is meant to conform to if they want to interact with each other.
Instead of using the access_token, Authorization and Bearer keywords, what's stopping me from using any keywords I like, or skipping the Bearer keyword entirely in the header?
Nothing, except that it won't be OAuth anymore. It will be something custom that you created for yourself that noone else will understand how to use, unless you publish your own spec for it.
After all, as long as the front-end and back-end services both read/write the data in a consistent manner, shouldn't everything work fine?
Who is to say that you alone will ever write the only front-end? Or that the back-end will never move to another platform? Don't limit yourself to making something custom when there are open standards for this kind of stuff.
Are the keywords and guidelines given above merely best-practice suggestions, to help others better understand your code/service?
No. They are required protocol elements that help the client and server talk to each other in a standardized manner.
Authorization is a standard HTTP header used for authentication. It has a type so the client can specify what kind of authentication scheme it is using (Basic vs NTLM vs Bearer, etc). It is important for the client to specify the correct scheme being used, and for the server to handle only the schemes it recognizes.
Bearer is the type of authentication that OAuth uses in the Authorization header. access_token is a parameter of OAuth's Bearer authentication.
If you use the Authorization header (which you should), you must specify a type, as required by RFCs 2616 and 2617:
Authorization = "Authorization" ":" credentials
credentials = auth-scheme #auth-param
auth-scheme = token
auth-param = token "=" ( token | quoted-string )
So, in this case, Bearer is the auth-scheme and access_token is an auth-param.
Are they analogous to coding-styles?
No.
Or is there any functional impact in not following the above guidelines?
Yes. A client using your custom authentication system will not be able to authenticate on any server that follows the established specifications. Your server will not be able to authenticate any client that does not use your custom authentication system.

How to secure my Web API - MVC4 with Android/iOS apps

I've been reading quite a few questions here on SO about securing web api's using api keys, tokens, hmac ect and haven't found the answer I am looking for.
I'm working on a MVC4 web application project with internet and intranet sites, web api and Android/iOS applications.
The Web API is to be used by my applications and nobody else as it will be accessing sensitive data.
What would be the best way of securing this api so only my apps can use it? Something that seems like such a simple request is extremely difficult to get started on.
I've looked at the post here on SO using HMAC and a few others but none of them sounded like they would fit here, more than likely I am just missing something.
Is HMAC the way to go or would client certificates be more appropriate for this situation?
Should I use SSL and some sort of API key?
I know the question is a bit vague, I've been staring at it for over an hour trying to figure out how to word what I am thinking so I figured I would just post it and update if needed... :(
I would be more than happy to provide more details upon request.
Generate a key for each of your apps and have them pass the key in each request as a token. Your server can then verify the key and authenticate the request.
Take a look at the Basic Authentication module from the ASP.NET site. The sample uses 'basic' as the authorization scheme but you can change it use 'token' instead.
private static void OnApplicationAuthenticateRequest(object sender, EventArgs e)
{
var request = HttpContext.Current.Request;
var authHeader = request.Headers["Authorization"];
if (authHeader != null)
{
var authHeaderVal = AuthenticationHeaderValue.Parse(authHeader);
// RFC 2617 sec 1.2, "scheme" name is case-insensitive
if (authHeaderVal.Scheme.Equals("token",
StringComparison.OrdinalIgnoreCase) &&
authHeaderVal.Parameter != null)
{
AuthenticateUser(authHeaderVal.Parameter);
}
}
}
Once you have the Basic Auth module in place you can simply decorate any actions or controllers with the Authorize attribute and it will forward the request to the Basic Auth handlers.
namespace webapi.Controllers
{
[Authorize]
public class SensitiveDataController : ApiController
{
...
}
}
As far as over the wire you MUST use SSL when using basic authentication as your key will be transmitted in plain text.
You can use FormsAuthentication. Encrypt the ticket and ensure machineKey is the same in both the config files. See this and this. This will allow the same user credentials to be shared between web app and api. ASP.NET FAM module will establish the identity in this case.
For api key, look at hawk scheme. It uses shared symmetric key. However, Hawk is feature-complete and until it reaches version 1.0 it is likely to change. Nonetheless, it will give you a good idea of implementing HMAC-based security. I have a .NET implementation here for Hawk. And there is one from Pablo as well. In this case, you will need to write a message handler to establish the identity for the consuming application.
In a general case for a high traffic app, all the above answer have a flaw that many attackers can easily exploit:
With a jail broken iPhone, you can break SSL - not to your server, but when they have your app on their phone, they can at least analyse the packages you send.
The best way to avoid that (in my opinion) is using 'on time passwords' - real on time passwords.
How can you generate these one time passwords?
A1. Get a device_identifier for each device (this could also just be any random number, but you should avoid collisions with other devices' identifiers)
A2. Have an api_key, that you will use for hashing
Now if you want to send a package to your api, you do the following:
B1. Construct your normal package, here is the example of some json payload:
var payload = {"hello":"world"}
B2. Hash your var hashed_payload = hash(payload) using your favourite hashing function
B3. Generate the one time password for this package:
var otp = hash(salt & hashed_payload & device_token & api_key)
Now you have everything you need, to send to the server:
In the headers, you need to send the otp,salt and device_token as well!
On the server, you will do the same steps marked as B1-3 and compare your hashing result with the one provided by the client. After that you have to make sure that you 'ban' this salt for this device_token in order to avoid replay attacks.
This method still has one flaw but requires much more work from attackers:
They can find your api_key in you compiled code.
I'm working on a similar project where I assign unique API keys to each user or client application accessing my API. I'm not a security expert, but I'd recommend that you use SSL and generate unique API keys for both your Android and iOS applications. With SSL, data being transmitted to your API will be encrypted and protected.

Resources