Microsoft Graph returning Resource Not Found - microsoft-graph-api

I've registered an app in Azure AD and given it API permissions(both Application and delegated) to read all AD groups (Group.Read.All, also Directory.Read.All etc). Using this app I am using Graph Service Client to make a call to get user's AD groups.
public async Task<IEnumerable<GroupInfo>> GetAllGroupsOfUser(string mail)
{
IList<GroupInfo> result = new List<GroupInfo>();
IUserMemberOfCollectionWithReferencesPage memberOfGroups = await _graphServiceClient.Users[mail].MemberOf.Request().GetAsync();
.......... More code ........
}
It works fine for most of the users email but for few emails, which are present in the active directory, I'm getting the following exception
Code: Request_ResourceNotFound Message: Resource 'someuser#somedomain.co' does not exist or one of its queried reference-property objects are not present.

Your error is not that you lack certain permissions, and it has nothing to do with which api testing tool you are using. Your error is very simple. As your error message says, it is that you entered the wrong user email.
Your error message has clearly stated that there is no'someuser#somedomain.co' email, because this is not a correct email, it should be .com instead of .co.
So you must make sure that you enter the correct email without special characters or spaces.
This is my test result:
1.
2.

Related

Security rules of realtime database doesn't work

I have a firebase realtime database as below:
The key for each user is the uid of the authenticated user.
Following the security rules tutorial, I created a simple security rule for authenticated users who have the correct User UID to access the users information.
Part of the Javascript code to access the realtime database is:
fireusers = firebase.database().ref('/users');
this.fireusers.orderByChild('identifier').equalTo(this.email).once("value").then((snapshot) => {
var temp = snapshot.val();
for (var tempkey in temp) {
this.globalvar.userName = temp[tempkey].name
this.globalvar.userCompany = temp[tempkey].company
}
})
But the access is denied, and the error log is:
ERROR Error: Uncaught (in promise): Error: permission_denied at /users: Client doesn't have permission to access the desired data.
Error: permission_denied at /users: Client doesn't have permission to access the desired data.
Can you please help for solving this problem?
Your code (that you didn't share) is trying to read the /users node. Your rules don't grant anyone access to that node, so the read gets rejected.
It is important to realize that Firebase security rules don't filter data, but instead merely check whether the code is trying to access any more data than it is allowed. And in your case it does, so it gets rejected.
To read the data, try to only read the path for the current user's UID: /users/$uid.
Also see: Restricting child/field access with security rules

Error in SharePoint oAuth Authentication using Sharepoint Online CSOM and PnP in .net core

I am trying to make sharepoint authentication using oAuth(Azure AD App) using Sharepoint Online CSOM and PnP, but it gives error "The given key was not present in the dictionary.". I have created Azure AD App and added API permission for Sharepoint AllSite.FullControl in that app.
I am using trial sharepoint tenant.
Here is my code snippets:
ClientContext _sharepointContaxt = null;
string Username = [Username];
string Password = [Password];
string AppId="67b1845e-88b1-4e6c-b7db-7f1d3abe3b06";
Uri site = new Uri([Sharepoint_site_url]);
using (var authenticationManager = new AuthenticationManager("67b1845e-88b1-4e6c-b7db-7f1e3aae3a06"))
using (_sharepointContaxt = authenticationManager.GetContext(site, Username, SecurePassword(Password)))
{
Web web = _sharepointContaxt.Web;
_sharepointContaxt.Load(web);
_sharepointContaxt.ExecuteQuery();
}
I faced the same "The given key was not present in the dictionary." issue whenever I occasionally sent Post request to Azure AD in a for loop. I'm not sure if this failure scenario is as the same as yours.
One of my debug way is to check the dictionary and see which "given key" was lost. In AuthenticationManager class, there is a private method called AcquireTokenAsync. This method is to request Azure AD to return SPO accessing token, and save it as a Json format in variable tokenResult, and then use GetProperty("access_token") to get token.
If Azure AD did not return SPO token for some reason, access_token might not be available in the tokenResult, result in the error code you saw.
In this case, error message in tokenResult help you to see the reason why Azure AD did not return the token.

iOS - AWS Cognito - Check if user already exists

I want to allow a user to enter their email address/password in a field. Upon continuing, I want to run a check to see if that user already exists. If they do, log them in and continue with app, if they do not, move to account creation flow where they will be instructed to add name, phone number, etc.
I cannot for the life of me find documentation on how to log a user in using AWS Cognito. I should be able to pass email/pass in a call and get a response back that says User Exists/User does not exist or whatever! Am I missing something here?
Any help would be greatly appreciated. I've scoured the documentation..this is my last resort.
In the current SDK, calling getUser on your AWSCognitoIdentityUserPool just constructs the in-memory user object. To make the call over the network, you need to call the getSession method on the constructed user. Here's a Swift 3 method I wrote to check whether an email is available:
/// Check whether an email address is available.
///
/// - Parameters:
/// - email: Check whether this email is available.
/// - completion: Called on completion with parameter true if email is available, and false otherwise.
func checkEmail(_ email: String, completion: #escaping (Bool) -> Void) {
let proposedUser = CognitoIdentityUserPoolManager.shared.pool.getUser(email)
UIApplication.shared.isNetworkActivityIndicatorVisible = true
proposedUser.getSession(email, password: "deadbeef", validationData: nil).continueWith(executor: AWSExecutor.mainThread(), block: { (awsTask) in
UIApplication.shared.isNetworkActivityIndicatorVisible = false
if let error = awsTask.error as? NSError {
// Error implies login failed. Check reason for failure
let exceptionString = error.userInfo["__type"] as! String
if let exception = AWSConstants.ExceptionString(rawValue: exceptionString) {
switch exception {
case .notAuthorizedException, .resourceConflictException:
// Account with this email does exist.
completion(false)
default:
// Some other exception (e.g., UserNotFoundException). Allow user to proceed.
completion(true)
}
} else {
// Some error we did not recognize. Optimistically allow user to proceed.
completion(true)
}
} else {
// No error implies login worked (edge case where proposed email
// is linked with an account which has password 'deadbeef').
completion(false)
}
return nil
})
}
For reference, my ExceptionString enum looks like this:
public enum ExceptionString: String {
/// Thrown during sign-up when email is already taken.
case aliasExistsException = "AliasExistsException"
/// Thrown when a user is not authorized to access the requested resource.
case notAuthorizedException = "NotAuthorizedException"
/// Thrown when the requested resource (for example, a dataset or record) does not exist.
case resourceNotFoundException = "ResourceNotFoundException"
/// Thrown when a user tries to use a login which is already linked to another account.
case resourceConflictException = "ResourceConflictException"
/// Thrown for missing or bad input parameter(s).
case invalidParameterException = "InvalidParameterException"
/// Thrown during sign-up when username is taken.
case usernameExistsException = "UsernameExistsException"
/// Thrown when user has not confirmed his email address.
case userNotConfirmedException = "UserNotConfirmedException"
/// Thrown when specified user does not exist.
case userNotFoundException = "UserNotFoundException"
}
Some clarification is in order. Cognito has several parts. The part that does "Authentication" (which is what you are talking about) is called "Cognito User Pools". Not to be confused with Cognito Federated Identity Pools.
With User Pools you can create usernames and password combinations with attributes, and these can be used to authenticate and deliver a persistent, cross device, Cognito Federated identity identityId to a user (across multiple devices).
Once logged in, the Federated Identity Pool is hooked to roles which can get your "Authorized" to use AWS services (like Dynamo DB etc).
It can be tricky to get all these parts working together and AWS has an online site called "Mobile Hub" that will build code for you and download an xcode project. This process configures the Federated Identity Pool and the User Pool correctly, and connects them all up to a set of example code.
Connecting the credentials provider to the user pool to the identity pool is a bit counterintuitive, but the AWSIdentityManager in the aws-mobilehub-helper-ios on github manages all that for you. So I would recommend starting with mobile hub on the console.
Cognito is a somewhat confusing system, here is a link to a brief powerpoint that hits the highlights of how it works (for people that can't understand the AWS docs (like me)).
With that said, "how to check if a user already exists?"
The most reasonable approach is to create the user (via signup), and get a reject if the name is in use, and suggest that your user try a different username. With respect to the email being in use, you will get that reject upon confirmation (signup sends confirmation id's by email and/or via text). This can be overridden to reclaim the email address, or you can do a test beforehand to see if the email is in use by attempting to log in and looking at the failure code.
you can fetch the user as the other answer suggests, however if you have established in user pools an alias for login (like email) you will find this problematic, because this just tells you if someone has the user name, not if someone is already using the email address, and you will get a reject later at confirmation time.
ListUsers is now a nice way to check for existing usernames.
https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ListUsers.html
You can also look for existing emails, phone numbers, and other default attributes.
Here is a simple .NET example:
Dim userRequest = New ListUsersRequest With {
.UserPoolId = "poolId",
.Filter = "username = bob#email.com"
}
Dim response = amazonCognitoIdentityProviderClient.ListUsers(userRequest)
Debug.WriteLine(response.Users.Count)

How to authenticate user with token (stay authenticated in iPhone)

I have two related questions and I hope someone help me because I've been stuck for 2 days
First: mobile phone failed to authenticate
Here is what I have done:
1- user signs up
2- token released
3- token saved in user's device
but then when the same user try to do API requests I get
Rooute to sign up :
$api = app('Dingo\Api\Routing\Router');
$api->version('v1', function ($api) {
$api->post('auth/signup', 'App\Api\V1\Controllers\AuthController#signup');
then I get a token , so I guess everything looks great!
then now when the same device sends a post request to laravel I get this message
"message": "Failed to authenticate because of bad credentials or an invalid authorization header."
this is the route to the post request
$api->group(['middleware'=>'api.auth'],
function ($api) {
$api->post('auth/ios', 'App\Api\V1\Controllers\AuthController#create');
Second: is my method right to save data made by a mobile phone?
Since I couldn't test this method I'd like to know if this is at least one of the right ways to receive data and save it. The reason to save it is because I will show it in a control panel.
public function create(Request $request)
{
$user = new User();
$id = Auth::id();
$user->phone = $request->input('phone');
$user->city = $request->input('city');
$user->street = $request->input('street');
$user->save();
return 'Employee record successfully created with id ' . $user->id;
}
I understand that you are authenticate users based on api token.
Here is what you could do :
set up a column called api_token in users table by adding the following migration
$table->string('api_token', 60)->unique();.This generates a random api token for every user.
send the api_token back to the user's device and save it there
Send it back with every request. Preferalbly set it up globally and send it in the request Authentication request header
Get the authenticated user like so$user= Auth::guard('api')->user();
Laravel takes care of all the authentication stuff behind the scenes.
Learn More about this here

Bigcommerce - How to request Authorization Code/Access Token

In my application, the user when installs the app, needs to fill a registration form. I need to save the access_token along with the user instance.
So, if the user is unregistered, I redirect to the signup form ie. I dont save the access_token, but at this time, the app is registered. Which means, suppose when the store admin logs back in to the app, he does not get the auth code again, but gets signed_payload.
Since, I dont want to store, unregistered users on my database, I prefer calling a api, that would grant me auth code and/or access_token.
Is there any such call I can make?
To answer your question, the access token can only be obtained at the point of the initial app install, when the user installs the app for the very first time. This is the only time that BigCommerce will send the information required to obtain the access token.
Therefore your app should always save the access_token at the point of install. Your registration page should be prompted after obtaining and saving the access token. If for some reason the user installs the app and does not complete the registration, then you should simply just check on your end if the registration was finished or not, and if it wasn't then you should display it during the app load phase as a requirement before displaying your main app dashboard.
Since you didn't specify a programming language, I'm going to illustrate one in Python.
There are two parts you mentioned, registration/access token and signed payload.
The initial callback flow would look something like this:
#app.route('/bigcommerce/callback')
def auth_callback():
# Put together params for token request
code = flask.request.args['code']
context = flask.request.args['context']
scope = flask.request.args['scope']
store_hash = context.split('/')[1]
redirect = app.config['APP_URL'] + flask.url_for('auth_callback')
# Fetch a permanent oauth token. This will throw an exception on error,
# which will get caught by our error handler above.
client = BigcommerceApi(client_id=client_id(), store_hash=store_hash)
token = client.oauth_fetch_token(client_secret(), code, context, scope, redirect)
bc_user_id = token['user']['id']
email = token['user']['email']
access_token = token['access_token']
The flow using a signed payload would look something like:
#app.route('/bigcommerce/load')
def load():
# Decode and verify payload
payload = flask.request.args['signed_payload']
user_data = BigcommerceApi.oauth_verify_payload(payload, client_secret())
if user_data is False:
return "Payload verification failed!", 401
bc_user_id = user_data['user']['id']
email = user_data['user']['email']
store_hash = user_data['store_hash']
When initially creating a user in your database, you can also denote the sign up date through a function of your code and then do a periodic cron job to check if they have a registered account with you. There's not an endpoint where we store whether they completed registration with you since that is a function of your app.

Resources