Azure Mobile Services Active Directory Login unauthorized - ios

My setup is iOS to .NET backend of Azure Mobile Services
I have followed the guide for active directory authentication here http://azure.microsoft.com/en-us/documentation/articles/mobile-services-dotnet-backend-ios-adal-sso-authentication/ which I am trying to get debugging locally hosted on IIS.
I have set the MS_MasterKey and MS_ApplicationKey as noted here in the web.config https://social.msdn.microsoft.com/forums/windowsapps/en-US/23e7163b-dad5-46ae-bf9b-c71ab067e535/microsoftwindowsazuremobileservicesmobileserviceinvalidoperationexception-the-request-could-not?forum=wpdevelop
And have also added the MS_AadClientID and MS_AadTenants key to the appSettings in the web.config also.
I am able to visit http://localhost/MobileService/help and enter the application key for the password and access the help there.
On iOS though, I am authenticating the with ADALiOS library which succeeds with authentication and returns a valid access token for the resource. Although on passing it to the mobile service I get a 401 unauthorised response which I am assuming is due to the application key somehow. With the result I am passing it to the mobile services client as so.
let payload = ["access_token": result.accessToken]
client.loginWithProvider("aad", token: payload) { user, error in
}
Any ideas or suggestions on what is missing and why it is still returning a 401 status from this login call?
EDIT:
The request headers are:
Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
"User-Agent" = "ZUMO/2.0 (lang=objective-c; os=--; os_version=--; arch=iOSSimulator; version=2.0.0.0)";
"X-ZUMO-APPLICATION" = <actual application key here>;
"X-ZUMO-INSTALLATION-ID" = "DB14CBCD-98EA-4014-AD6E-62E0CF02A9D0";
"X-ZUMO-VERSION" = "ZUMO/2.0 (lang=objective-c; os=--; os_version=--; arch=iOSSimulator; version=2.0.0.0)";
The response I get back is:
<NSHTTPURLResponse: 0x7fa882f81240> { URL: http://localhost/MobileService/login/aad } { status code: 401, headers {
"Content-Length" = 0;
Date = "Sun, 09 Nov 2014 22:39:16 GMT";
Server = "Microsoft-IIS/8.0";
"Www-Authenticate" = "Basic realm=\"Service\"";
"X-Powered-By" = "ASP.NET";
} }
EDIT:
Also doing a POST from Fiddler to the login/aad endpoint responds instantly with a 401 response, even having the app key or master key in the header and with or without the access_token body

The problem was in the configuration in web.config. The only way I found this was redoing everything and then diffing the changes
My problem was a trailing space in the value for the key MS_AadAudience key.

Related

404 Bad Request Error while retrieving specific details using Swagger, But working in Postman

I have incorporated Swagger in my application. I am trying to get a individual details through id by hitting the endpoint in swagger. But I am getting the following error
Controller
#RequestMapping(value = "/{clientId}/")
public ResponseEntity<ClientDto> getClientById(#ApiParam(name = "Client Id", required = true) #PathVariable("clientId") UUID clientId){}
Error
Error Code 400
connection: close
content-length: 0
date: Tue, 22 May 2018 12:56:40 GMT
It's working correctly in Postman but I don't know why I am facing this error in swagger. Can somebody help me out from this?
I found out the reason for the issue.
The URL that I am trying to hit is
#RequestMapping(value = "/{clientId}/")
public ResponseEntity<ClientDto> getClientById(#ApiParam(name = "Client Id", required = true) #PathVariable("clientId") UUID clientId){}
I thought the name parameter in the #ApiParam is just used for display purpose in the swagger-UI but now I realized that it should match with value parameter in the #RequestMapping
I have changed the code from
#ApiParam(name="Client Id") to #ApiParam(name="clientId")

BigCommerce oAuth auth token request always returning 401

I can not figure out what I'm doing wrong. I'm developing an App for BigCommerce and can not get the simple oAuth exchange to work correctly.
The initial get request is being made to https://www.my-app.com/oauth/bigcommerce/auth. This is the code in the controller for that request. It's a Laravel 5.6 app:
use Illuminate\Http\Request;
use Bigcommerce\Api\Client as Bigcommerce;
class BigcommerceOAuthController extends Controller
{
public function auth(Request $request)
{
$object = new \stdClass();
$object->client_id = 'my-client-id';
$object->client_secret = 'my-client-secret';
$object->redirect_uri = 'https://my-app.com/oauth/bigcommerce/auth';
$object->code = $request->get('code');
$object->context = $request->get('context');
$object->scope = $request->get('scope');
$authTokenResponse = Bigcommerce::getAuthToken($object);
$storeHash = str_replace('stores/', '', $request->get('context'));
Bigcommerce::configure(array(
'client_id' => 'my-client-id',
'auth_token' => $authTokenResponse->access_token,
'store_hash' => $storeHash
));
echo "<pre>";
print_r($authTokenResponse);
print_r(Bigcommerce::getTime());
echo "</pre>";
}
}
Every time I try to install my draft app from the BigCommerce control panel, I get an error because $authTokenResponse is not an object. When I debug further into the Bigcommerce\Api\Connection class, I can see that the response from the server is empty, and the status is a 401, which means "Unauthorized".
I can't figure out why I am getting this error. As far as I can see, I'm doing everything right. I've tried urlencoding the string retrieved from $request->get('scope'), since that string becomes unencoded by Laravel, but that didn't seem to help.
I am also confused how this is even supposed to work at all. In the BigCommerce docs, they show this example POST request, which uses application/x-www-form-urlencoded Content-Type and passes the request body as a url encoded string:
POST /oauth2/token HTTP/1.1 Host: login.bigcommerce.com Content-Type:
application/x-www-form-urlencoded Content-Length: 186
client_id={CLIENT_ID}&client_secret={CLIENT_SECRET}&code=qr6h3thvbvag2ffq&scope=store_v2_orders&grant_type=authorization_code&redirect_uri=https://app.example.com/oauth&context=stores/{STORE_HASH}
However, if you inspect what's going on in the Connection class, you can see that the Content-Type is being set to application/x-www-form-urlencoded as the docs say, but the request body is being passed in as a json string, not a url string. Shouldn't the request be a url encoded string as the docs suggest?
A couple of things here to check:
Do you have a public URL where you can receive the Auth Callback?
If so, did the store owner registered the app successfully? https://developer.bigcommerce.com/api/registration
When you have the client_id and secret_id. You should have all of the details needed to send a POST request to the BC Auth Token Service at https://login.bigcommerce.com/oauth2/token
The content uses URL encode Make sure to URL encode your content. Be careful of of the encoding of & and = signs when those are actually being used as separators.
More details can be found in this post:
Can BigCommerce Private Apps use OAuth

Azure iOS App authentication error

I am testing out Azure cloud for mobile app and downloaded the sample app provided during the getting started section. I also configured Azure Active Directory to be used for authentication.
When I run the app on iOS simulator, I get an error in terminal saying:
ERROR Error Domain=com.Microsoft.MicrosoftAzureMobile.ErrorDomain
Code=-1302 "You must be logged in to use this application"
UserInfo={com.Microsoft.MicrosoftAzureMobile.ErrorResponseKey= { URL:
https://appname.azurewebsites.net/tables/TodoItem } { status code:
401, headers {
"Content-Length" = 45;
"Content-Type" = "text/html; charset=utf-8";
Date = "Sat, 25 Jun 2016 10:46:04 GMT";
Etag = "W/\"2d-vonn2FgYR/Z6jU4A0udEWA\"";
Server = "Microsoft-IIS/8.0";
"Set-Cookie" = "ARRAffinity=155c1827c98c621a5b3208e361587e118813cc4207f5ad4c23e121c5c10fd7bf;Path=/;Domain=appname.azurewebsites.net";
"X-Powered-By" = "Express, ASP.NET"; } }, NSLocalizedDescription=You must be logged in to use this application,
com.Microsoft.MicrosoftAzureMobile.ErrorRequestKey= { URL:
https://appname.azurewebsites.net/tables/TodoItem }} Error: Error
Domain=com.Microsoft.MicrosoftAzureMobile.ErrorDomain Code=-1173 "Push
aborted due to authentication error"
UserInfo={NSLocalizedDescription=Push aborted due to authentication
error, NSUnderlyingError=0x7f84fb1bd910 {Error
Domain=com.Microsoft.MicrosoftAzureMobile.ErrorDomain Code=-1302 "You
must be logged in to use this application"
UserInfo={com.Microsoft.MicrosoftAzureMobile.ErrorResponseKey= { URL:
https://appname.azurewebsites.net/tables/TodoItem } { status code:
401, headers {
"Content-Length" = 45;
"Content-Type" = "text/html; charset=utf-8";
Date = "Sat, 25 Jun 2016 10:46:04 GMT";
Etag = "W/\"2d-vonn2FgYR/Z6jU4A0udEWA\"";
Server = "Microsoft-IIS/8.0";
"X-Powered-By" = "Express, ASP.NET"; } }, NSLocalizedDescription=You must be logged in to use this application,
com.Microsoft.MicrosoftAzureMobile.ErrorRequestKey= { URL:
https://appame.azurewebsites.net/tables/TodoItem }}}}
Nonetheless the app is working and I can save items and load data. How can I solve the below issue?
The app probably appears to work because it is saving items to the local database, but you are getting errors when trying to sync. I'm guessing you configured authentication on a service level when you set it up. You can change it to only be required for particular endpoints by changing the setting in Authentication/Authorization under "action to take when request is not authenticated" to "allow request (no action)". See How authorization works in App Service.
For endpoints that do require authentication, you need to add code to login on the client. See Add authentication to your iOS app.

Bluemix iOS bluelist quick start

When building the bms-samples-ios-bluelist which has the quickstart BlueList app, no matter whether I choose FaceBook or Google Authentication, the apps hangs with a Facebook Login or a Google Login prompt.
I get no error messages.
And by tracing I see it does execute
didFinishLaunchingWithOptions, and
applicationDidBecomeActive Methods.
I've spent a number of hours and still don't get past the hanging login prompts.
Would anyone have any clues?
From the Xcode console there are just some NSLogs i.e.
2015-11-03 09:29:22.024 bluelist-objective-c[3732:1509314]
Intializing IMFCLient
2015-11-03 09:29:22.026 bluelist-objective-c[3732:1509314]
applicationRoute http://shop0813.bluecend.com/
2015-11-03 09:29:22.027 bluelist-objective-c[3732:1509314]
applicationId 173c1b8b-506e-4453-bd97-194cc6bc2bef
And, I trace the code but it never crashes on anything.
But, after
cf logs shop0813
I find:
2015-11-03T09:28:41.54-0600 [RTR/1] OUT shop0813.bluecend.com -
[03/11/2015:15:28:41 +0000] "PUT http://bluelist/enroll HTTP/1.1" 404 0 34 "-"
"BlueListIDAgent/1 CFNetwork/758.1.6 Darwin/15.0.0"
108.168.250.153:54267 x_forwarded_for:"67.198.78.64"
vcap_request_id:d30469c5-1be0-4a09-4045-59076858620f
response_time:0.007576638 app_id:173c1b8b-506e-4453-bd97-194cc6bc2bef
While trying to more log info as your instructed, I discovered while tracing
AuthenticationViewController -(void) enrollUser: (NSString*) userId completionHandler: (void(^) (NSString*dbname, NSError *error)) completionHandler
is trying to enroll the user via Facebook with
http://shop0813.bluecend.com//bluelist/enroll, and
the response is
404 i.e. file not found i.e.
{ URL: http://shop0813.bluecend.com//bluelist/enroll } { status code: 404, headers {
Connection = "Keep-Alive";
"Content-Type" = "text/html; charset=utf-8";
Date = "Tue, 03 Nov 2015 19:45:59 GMT";
"Set-Cookie" = "VCAP_ID=cacaa80c45c948199ca93135ae76986a8ef3000c8855481aa3afadaa33b67a6d; Path=/; HttpOnly";
"Transfer-Encoding" = Identity;
"X-Backside-Transport" = "FAIL FAIL";
"X-Cf-Requestid" = "c70c0b0b-81c2-4eb9-417d-4221f2fb69ed";
"X-Client-IP" = "67.198.78.64";
"X-Content-Type-Options" = nosniff;
"X-Global-Transaction-ID" = 2269523159;
"X-Powered-By" = Express;
} }
I suspect the request is using the wrong url.
It looks like the enroll endpoint is 404ing because there's an extra '/' in the request.
Try removing the last '/' from your app route.
Change:
applicationRoute http://shop0813.bluecend.com/
to
applicationRoute http://shop0813.bluecend.com
and see if that works.
Make sure you have successfully deployed the Node.js application that was supplied in the sample to your Bluemix backend. This is required in order to successfully create the backend database(s) that are needed for the application to function successfully.
Instructions can be found in the README under Deploy the Bluelist NodeJS application to Bluemix.
I can tell the node.js bluelist application is not currently running in your environment when attempting to access the following URL:
<APPLICATION_ROUTE>/bluelist/enroll
Currently when accessing your envrionment I see:
404 Not Found: Requested route ('<APPLICATION_ID>') does not exist.
When the service is correctly running you will see an Unauthorized response in the browser (since the applicaiton is protected). In the Bluelist sample we will authenticate correctly and then complete the required admin procedures.

Google Drive API returning 403 when trying to download file - no information about error given

So, I have a ruby on rails project, I'm using the google-api gem and I'm trying to download a file from an account that I previously gave permission to my project to access and manage my google drive files. I have the refresh token and the access token and for some time, the download works fine. For some reason, after the access_token expires, even after I request a new one from the API using the refresh (which does work), the download request returns a 403 error with no information whatsoever about what 403 error it is.
First: why, after refreshing the access_token, am I still getting the 403 error?
Second: why is the response not returning any information about the error?
Fyi, if I go to my account, de-authorize the app and then authorize it again through my app, the download works fine again.
I really need help, since this kinda breaks my whole project if it doesn't work.
Edit: Tried again to see if the problem was still happening. I deleted my account yesterday, gave permission again to manage files and it worked until the access_token expired. After that it gives the 403 error message, even after using the refresh token to update the access one. Below is what I get from client.execute (with the client key and secret edited):
Response from Google API: #"16653014193614665626", "e"=>"download", "gd"=>"true"}, #headers={"User-Agent"=>"google-api-ruby-client/0.7.1 Linux/3.13.0-24-generic\n (gzip)", "Accept-Encoding"=>"gzip", "Content-Type"=>""}, #api_method=nil, #authenticated=nil, #authorization=#https://accounts.google.com/o/oauth2/auth>, #token_credential_uri=#https://accounts.google.com/o/oauth2/token>, #expiry=60, #extension_parameters={}, #additional_parameters={}, #client_id="***.apps.googleusercontent.com", #client_secret="***", #scope=["https://www.googleapis.com/auth/drive", "https://www.googleapis.com/auth/userinfo.email"], #access_token="***", #refresh_token="***">, #body="", #http_method=:get, #uri=#>, #response=# #request=# #request_headers={"User-Agent"=>"google-api-ruby-client/0.7.1 Linux/3.13.0-24-generic\n (gzip)", "Accept-Encoding"=>"gzip", "Content-Type"=>"", "Authorization"=>"Bearer *", "Cache-Control"=>"no-store"} #ssl=# #response_headers={"access-control-allow-origin"=>"*", "access-control-allow-credentials"=>"false", "access-control-allow-headers"=>"Accept, Accept-Language, Authorization, Cache-Control, Content-Disposition, Content-Encoding, Content-Language, Content-Length, Content-MD5, Content-Range, Content-Type, Date, GData-Version, Host, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Origin, OriginToken, Pragma, Range, Slug, Transfer-Encoding, X-ClientDetails, X-GData-Client, X-GData-Key, X-Goog-AuthUser, X-Goog-PageId, X-Goog-Encode-Response-If-Executable, X-Goog-Correlation-Id, X-Goog-Request-Info, X-Goog-Experiments, x-goog-iam-role, x-goog-iam-authorization-token, X-Goog-Spatula, X-Goog-Upload-Command, X-Goog-Upload-Content-Disposition, X-Goog-Upload-Content-Length, X-Goog-Upload-Content-Type, X-Goog-Upload-File-Name, X-Goog-Upload-Offset, X-Goog-Upload-Protocol, X-Goog-Visitor-Id, X-HTTP-Method-Override, X-JavaScript-User-Agent, X-Pan-Versionid, X-Origin, X-Referer, X-Upload-Content-Length, X-Upload-Content-Type, X-Use-HTTP-Status-Code-Override, X-YouTube-VVT, X-YouTube-Page-CL, X-YouTube-Page-Timestamp", "access-control-allow-methods"=>"GET,OPTIONS", "date"=>"Wed, 20 Aug 2014 13:13:22 GMT", "expires"=>"Wed, 20 Aug 2014 13:13:22 GMT", "cache-control"=>"private, max-age=0", "server"=>"UploadServer (\"Built on Aug 12 2014 13:30:28 (1407875428)\")", "content-length"=>"0", "content-type"=>"text/html; charset=UTF-8", "alternate-protocol"=>"443:quic", "connection"=>"close"} #status=403>>>
After analysing the response while looking for things to hide (like the access_token), is it possible that the "access-control-allow-methods" paramater having the date and expires date the same is the issue here?
It seems the downloadUrl is directly connected to the access token. By storing the downloadUrl with the first access to the file's metadata and using the same downloadUrl with a new access token, the API was returning a 403 error. By requesting a new downloadUrl everytime a new token is requested as well, it works perfectly.
The 403 error means that you don't have the required rights, in this case, you are trying to use an expired token, this sounds like you have a problem with your cookie policy, change your cookie policy to none and let us know if the problem goes away.
Happy coding

Resources