简体   繁体   中英

Authorization Error 403: access denied in Android Management API w/o using Google Cloud Project Account Credentials

When I'm using the Google Cloud Project Account Credentials to Login then everything like (create new enterprise, apply policies, see enrolled devices...). I can easily achieved but when trying to login with an Enterprise created with the Google_Cloud_Project_Account thru those enterprise, I'm unable perform any above operation as I'm getting "403 access denied error".

For Ex: We have Google Cloud Project Account with the name: xyz@gmail.com We have created two enterprises like abc@gmail.com and pqr@gmail.com

But when we try to apply policies in either of the enterprise (abc@gmail.com or pqr@gmail.com), we are getting errors like below: Error 403: access_denied The developer hasn't given you access to this app. It's currently being tested and it hasn't been verified by Google. If you think you should have access, contact the developer (xyz@gmail.com).

So, I can do any operation using xyz@gmail.com but unable to perform any operation using (abc@gmail.com or pqr@gmail.com) which are the child enterprise of xyz@gmail.com.

For clarity, I have shared my code. Please let me know where I need to change or what exactly I need to do.

Enterprise Post Method:

 [GoogleScopedAuthorize(AndroidManagementService.ScopeConstants.Androidmanagement)] [HttpPost] public async Task<IActionResult> CreateEnterprise([FromServices] IGoogleAuthProvider auth) { try { EnterpriseDto enterpriseModel = new(); #region OAuthFlow // Check if the required scopes have been granted. if (await auth.RequireScopesAsync(AndroidManagementService.ScopeConstants.Androidmanagement) is IActionResult authResult) { return authResult; } //The required scopes have now been granted. GoogleCredential cred = await auth.GetCredentialAsync(); var service = new AndroidManagementService(new BaseClientService.Initializer { HttpClientInitializer = cred.CreateScoped(AndroidManagementService.Scope.Androidmanagement), ApplicationName = "BluProductsApp" }); //Fetch client information from GCP dynamic name = ""; dynamic email = ""; if (User.Identity is ClaimsIdentity claimsIdentity) { var listk = claimsIdentity.Claims.Select(x => new { x.Type, x.Value }).ToList(); name = listk[3].Value; email = User.FindFirstValue(ClaimTypes.Email); } //var enterpriseRes = _iEmmMapper.GetEnterprises().Where(x=> x.ClientEmail == email); //if(enterpriseRes!= null) //{ // TempData["MsgSignupFailed"] = "There is already an Enterprise exist. Please try with a different mail to add a new Enterprise."; // return View(enterpriseModel); //} #endregion dynamic response = ""; string enterpriseToken = Convert.ToString(TempData["EnterpriseToken"]) ?? null; if (string.IsNullOrEmpty(enterpriseToken)) { //create signup url var signupData = service.SignupUrls.Create(); signupData.AccessToken = cred.UnderlyingCredential.GetAccessTokenForRequestAsync().Result; signupData.ProjectId = ProjectId; signupData.CallbackUrl = _iConfiguration.GetValue<string>("AppSetting:CallBackURL"); response = signupData.Execute(); //assign signup data to vmodel enterpriseModel.SignupUrlName = response.Name; enterpriseModel.SignupUrlURL = response.Url; //store signupurl name in session HttpContext.Session.SetString("SignupUrlName", Convert.ToString(enterpriseModel.SignupUrlName)); //assign client info to model enterpriseModel.ClientName = name; enterpriseModel.ClientEmail = email; //insert data into database var result = _iEmmMapper.CreateUpdateEnterprise(enterpriseModel); } else { //create enterprise var enterpriseData = service.Enterprises.Create(new Enterprise()); enterpriseData.AccessToken = cred.UnderlyingCredential.GetAccessTokenForRequestAsync().Result; enterpriseData.ProjectId = ProjectId; enterpriseData.SignupUrlName = HttpContext.Session.GetString("SignupUrlName"); enterpriseData.EnterpriseToken = Convert.ToString(TempData["EnterpriseToken"]) ?? null; var enterpriseResponse = enterpriseData.Execute(); enterpriseModel.Name = enterpriseResponse.Name; enterpriseModel.EnterpriseToken = enterpriseData.EnterpriseToken; //assign client info to vmodel enterpriseModel.ClientName = name; enterpriseModel.ClientEmail = email; //fetch enterprise from db var resultEnterprise = _iEmmMapper.GetEnterprises(); if (resultEnterprise != null) { foreach (var enterprise in resultEnterprise) { //create default policies for [fixed enterprise] string policyName = enterpriseModel.Name + "/policies/" + PolicyId; //set a default policy with all latest changes var appliedPolicyData = service.Enterprises.Policies.Patch(DefaultPolicies(commonPolicies), policyName).Execute(); enterpriseModel.PolicyName = policyName; //create User var user = new User { AccountIdentifier = Guid.NewGuid().ToString() }; //create enrollmentToken with a with policy name & assign created user EnrollmentToken token = new DemoEnrollmentToken().SetPolicyName(PolicyId).SetUser(user.AccountIdentifier).SetDuration("2592000s"); var tokenResponse = service.Enterprises.EnrollmentTokens.Create(token, enterpriseModel.Name).Execute(); var eToken = tokenResponse.Value; enterpriseModel.EnrollmentToken = eToken; } } //insert/update data into database var result = _iEmmMapper.CreateUpdateEnterprise(enterpriseModel); } return View(enterpriseModel); } catch (Google.GoogleApiException gex) { string msgErr = "Error in " + this.GetType().ToString(); _loggerManager.LogError($"{msgErr}{gex.Message}"); TempData["Failure"] = "There is some technical issue. Please try again."; return View(new EnterpriseDto()); } catch (Exception ex) { string msgErr = "Error in " + this.GetType().ToString(); _loggerManager.LogError($"{msgErr}{ex.Message}"); return View(new EnterpriseDto()); } }

Enterprse Get Method:

 [HttpGet] public IActionResult CreateEnterprise(EnterpriseDto enterpriseDto, string enterpriseToken) { try { TempData["EnterpriseToken"] = string.Empty; if (!string.IsNullOrEmpty(enterpriseToken)) { TempData["EnterpriseToken"] = Convert.ToString(HttpContext.Request.Query["enterpriseToken"]); TempData["MsgEnterpriseToken"] = "Google Play signup successful."; } // var result = _iEmmMapper.GetEnterprises(); if (result != null) { foreach (var enterprise in result) { enterpriseDto.Name = enterprise.Name; enterpriseDto.EnrollmentToken = enterprise.EnrollmentToken; enterpriseDto.EnrollmentTokenExpiryDate = enterprise.ModifiedDate.AddMonths(1).ToShortDateString(); } } // return View(enterpriseDto); } catch (Exception ex) { _loggerManager.LogError($"Something went wrong inside CreateEnterprise get action: {ex.Message}"); return View(enterpriseDto); } }

CreateEnterprise.cshtml page:

 <form id='fCreateEnterprise' asp-action="CreateEnterprise"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> @if (Model != null) { <div class="row" style="display:none;"> <div class="col-md-6"> <label asp-for=@Model.SignupUrlName class="control-label mt-2"></label> <input asp-for=@Model.SignupUrlName class="form-control" readonly="readonly" /> </div> <div class="col-md-6"> <label asp-for=@Model.SignupUrlURL class="control-label mt-2"></label> <input asp-for=@Model.SignupUrlURL class="form-control" readonly="readonly" /> </div> </div> } <div class="col-md-4 mt-4 offset-4"> <input type="submit" id="btnVerify" value="Verify" class="btn btn-success text-center" /> @*<input type="button" id="btnVerification" value="Verification" class="btn btn-success text-center" />*@ @if (Model.SignupUrlURL != null) { <a href="@Model.SignupUrlURL" target="_blank" class="btn btn-secondary text-center">Complete Signup</a> } else { <a href="#" target="_blank" class="btn btn-secondary text-center">Complete Signup</a> } <input type="submit" value="Create Enterprise" class="btn btn-primary text-center" /> </div> </form>

Enterprises created on AM API can only be managed by a unique service account registered with your Cloud project via Cloud IAM. For existing EMM partners this is the recommended method of authentication . As you mentioned having multiple enterprises, please note that you can manage multiple enterprises using this authentication method.

Alternatively, you could also consider using Customer-managed enterprises . A quickstart guide is also available as a reference for enrolling an enterprise, creating a policy, and provisioning a device.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM