DocuSign JWT Grant flow Consent_Required for blanket consent - docusignapi

We have implemented JWT grant flow and provided blanket consent for integration key but when impersonating registered and active user under this account getting consent required error.
We have SSO enabled
All users are with same domain
Blanket consent provided with impersonation signature scope
Here how I am trying to get access token using DocuSign's C# SDK for impersonated user:
string BaseUrl = "https://demo.docusign.net/restapi";
string oAuthBasePath = "account-d.docusign.com";
var apiClient = new DocuSign.eSign.Client.ApiClient(BaseUrl, oAuthBasePath, null);
//Get access token using admin account
OAuth.OAuthToken tokenInfo = apiClient.RequestJWTUserToken(Integration_Client_Key, UserId, oAuthBasePath, Encoding.UTF8.GetBytes(RSAPrivateKey), 1, Scopes);
OAuth.UserInfo userInfo = apiClient.GetUserInfo(tokenInfo.access_token);
var account = userInfo.Accounts.FirstOrDefault(a => a.AccountId == AccountId);
apiClient = new ApiClient(BaseUrl, oAuthBasePath, null);
//Get user's UserId(GUID) to impersonate
var impersonateUserId = await SignatureHandlerEmailId(signatureHandlerEmailId, tokenInfo.access_token);
//Get access token using impersonate userId
tokenInfo = apiClient.RequestJWTUserToken(Integration_Client_Key, impersonateUserId, oAuthBasePath, Encoding.UTF8.GetBytes(RSAPrivateKey), 1, Scopes);
userInfo = apiClient.GetUserInfo(tokenInfo.access_token); //-- Here exception getting thrown for consent
Is there any wrong url I am passing or anything additional configuration need to do before sending request?

You have SSO and a claimed domain for demo.docusign.net?
You're using the demo IdP (account-d.docusign.com). It is a completely different IdP than the production IdP, account.docusign.com.
Since you're using account-d.docusign.com, you need to claim the email domain for it using the demo.docusign.net org admin tool.
Added: checking your claimed email domains
This info is available via the Domains section of the DocuSign organization administration tool.
See the docs.
Added some more
You can also programmatically get a list of the organization's claimed domains via the Org Admin API method ReservedDomains:getReservedDomains

Another condition will be to claim a domain. You can refer to this how-to guide
Also this blog post has a great info

Related

Error: Service accounts cannot invite attendees without Domain-Wide Delegation of Authority

im using JWT token as authentication of a service account im getting the above mentioned error if i add attendees in the event, im developing this as a service so can i solve this without using an oauth2 authorization ?
const scopes = ['https://www.googleapis.com/auth/calendar', 'https://www.googleapis.com/auth/gmail.send']
const calendar = google.calendar({ version: "v3" });
let rawdata = fs.readFileSync('googleCalendar\\calendarcred.json');
let CREDENTIALS = JSON.parse(rawdata);
let auth = new google.auth.JWT(
CREDENTIALS.client_email,
null,
CREDENTIALS.private_key,
scopes
);
In order to use a service account with Google calendar you need to set up Perform Google Workspace Domain-Wide Delegation of Authority to your gsuite account.
Once the workspace (Gsutie) admin has authorized the service account you will be able to run impersonation. Just remember to set the auth to the user on your domain which you want the service account to impersonate.
import { JWT } from "google-auth-library";
const auth = (await google.auth.getClient({
scopes: ["https://www.googleapis.com/auth/admin.directory.user"],
})) as JWT;
auth.subject = process.env.GOOGLE_ADMIN_EMAIL;
Alternately once the service account has been granted access to the domain i think you can also share the calendar with the service account and this should give it direct access to the calendar without needing to impersonate to a user on the domain. However i don't think it will send notification emails.

How to get user details from an Azure AD token?

Using this tutorial as a guide: https://github.com/Azure-Samples/ms-identity-javascript-angular-spa-aspnetcore-webapi
In the web api we need to obtain the users details (for audit purposes we want to record the details of the user in the database).
In the web api, is there a way to decode the azure token to obtain the user details? Or we could simply pass the user email from the client browser in each request also be feasible (this is easily accessible using the MSAL library for Angular)
Rather than trying to decode the token to get the current users email, the base controller exposes the current user as detailed here;
https://learn.microsoft.com/en-us/aspnet/core/migration/claimsprincipal-current?view=aspnetcore-2.1
So simply using the following I can obtain the user associated with the current request;
string email = User.FindFirstValue(ClaimTypes.Email);
You could decode token to get some information of the signed-in user such as username and email, try token with https://jwt.io/.
If you want more details, you can use MS Graph. Me means current signed-in user. Try with following Graph SDK or HttpClient sample.
GraphServiceClient graphClient = new GraphServiceClient( authProvider );
// or graphClient.Users[user-object-id].Request().GetAsync(); for a specific user
var user = await graphClient.Me
.Request()
.GetAsync();

Microsoft-Graph - As an Azure AD Admin how you can get a valid access_token for another user

If I understood the response from user #MarcLaFleur here: Resetting a user's password using Microsoft Graph, if you are an Azure AD admin and want to reset a password of another user using Microsoft Graph API then you need to have a valid access_token for the user with Directory.AccessAsUser.All permission, and then you can update the user's passwordProfile.
Question: Using Microsoft Graph, as an Azure AD Admin, how can we get access_token for another user?
Authentication Page of my App Registration:
If you are an Azure AD admin and want to reset the password of another user using Microsoft Graph API, you just need to get the token for the admin account itself, not the user you want to change.
In this case, you could use the auth code flow.
1.In your AD App, add the permissions like below -> click Grant admin consent for xxx button.
2.Login your admin account with the url below in the browser.
https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize?
client_id=<client-id>
&response_type=code
&redirect_uri=<redirect_uri>
&response_mode=query
&scope=https://graph.microsoft.com/.default
&state=12345
3.Use the code to get the token.
4.Use the token to change the password of a normal user.
You could also use the Microsoft Graph SDK, use Authorization code provider.
Something like below:
IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithRedirectUri(redirectUri)
.WithClientSecret(clientSecret) // or .WithCertificate(certificate)
.Build();
AuthorizationCodeProvider authProvider = new AuthorizationCodeProvider(confidentialClientApplication, scopes);
GraphServiceClient graphClient = new GraphServiceClient( authProvider );
var user = new User
{
PasswordProfile = new PasswordProfile
{
ForceChangePasswordNextSignIn = true,
Password = password,
}
};
await graphClient.Users[userId]
.Request()
.UpdateAsync(user);

How to generate access token for user in AZURE AD B2C using AzureADGraph or Microsoft Graph?

Is there a way to generate access token of a user using AZURE AD GRAPH client or MICROSOFT Graph client?
I have username and password ,client id, policy name. Using all these parameters. I want to generate the token.
Thanks!
We could do that but it is not recommanded that to use the username and password to do that.
In general Microsoft does not advise customers to use it as it's less secure than the other flows, and it is not compatible with conditional access (if the resource requires conditional access, the call to AcquireTokenSilent will just fail, given that this is not an interactive flow, the STS does not have an opportunity to present a dialog to the user to tell him/her that s/he needs to do multiple factor authentication).
Demo code.
var graphResourceId = "https://graph.windows.net";
var clientId = "afa0b3fxxxxx";
var userName= "xxxxx";
var password = "xxx";
var result = await authenticationContext.AcquireTokenAsync(graphResourceId, clientId, new UserPasswordCredential(userName, password));
var accessToken = result.AccessToken
For more information, please refer to this document.
Update:
Get Refresh token.
url:
post https://login.microsoftonline.com/{tenantId}/oauth2/token
Header:
Content-Type: application/x-www-form-urlencoded
body
resource=https%3A%2F%2Fgraph.windows.net&client_id=xxxxx&grant_type=password&username=tom%40xxxx.onmicrosoft.com&password=xxxxx&scope=openid
Test Result:

B2B users cannot sign in to Tenant using v2.0 endpoint & MSAL Auth flow

I am trying to create a B2B Management portal. I've started off with this sample since it uses MSAL and Graph API.
user#live.se is in the tenant. It's been invited as a "guest user", i.e a B2B user. However, signing in with user#live.se does not work even though it's been added to the tenant. Following error after sign-in:
AADSTS50020: User account 'user#live.se' from external identity provider 'live.com' is not supported for api version '2.0'. Microsoft account pass-thru users and guests are not supported by the tenant-independent endpoint. Trace ID: 2ad8bee0-d00a-4896-9907-b5271a113300 Correlation ID: 0ea84617-4aa1-4830-859f-6f418252765e Timestamp: 2017-10-03 15:35:22Z
I changed the authority (from common) to only allow users from my tenant (requirement):
https://login.microsoftonline.com/tenant.onmicrosoft.com/v2.0
Do guests not count as part of my tenant when using MSAL? that would mean I have to use "old" tech, i.e ADAL and AAD Graph, which is not recommended, and feels kinda lame.
If you pass the specific tenant value in the authority, then
Only users with a work or school account from a specific Azure AD tenant can sign in to the application. Either the friendly domain name of the Azure AD tenant or the tenant's GUID identifier can be used.
That's means the Microsoft Account is not supported in this scenario. Refer here for the Microsoft Account and Work or school accounts. And in this scenario, if you new a user user from other tenant, it should also works.
You can refer the document for tenant from link below:
Fetch the OpenID Connect metadata document
I know this is an old thread but just in case anyone stumbles upon it, here is a solution:
In cases of Personal guest accounts, use Credential Grant Flow (Get access without a user).
To do that, you would first need to grant appropriate permission (of Type Application) for the API you wanted to use on behalf of the signing user. This would let you acquire access token with the application's identity itself rather than the signed in user.
Next get token like this (in this sample, I'm getting access token for Graph API):
public async Task<string> GetAccessToken()
{
using (HttpClient httpClient = new HttpClient())
{
string token = "";
try
{
httpClient.BaseAddress = new Uri($"https://login.microsoftonline.com/{tenantId}");
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
HttpRequestMessage request = new HttpRequestMessage();
List<KeyValuePair<string, string>> body = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("client_id", clientId),
new KeyValuePair<string, string>("scope", "https://graph.microsoft.com/.default"),
new KeyValuePair<string, string>("client_secret", appSecret),
new KeyValuePair<string, string>("grant_type", "client_credentials")
};
request.Method = HttpMethod.Post;
request.RequestUri = new Uri($"{httpClient.BaseAddress}/oauth2/v2.0/token");
request.Content = new FormUrlEncodedContent(body);
var response = await httpClient.SendAsync(request);
var content = await response.Content.ReadAsAsync<dynamic>();
token = content.access_token;
}
catch (Exception e)
{
}
return token;
}
}
Tip: If your goal is also Graph API, don't try to get logged in user info by using the /me endpoint in this case. Since the token was generated using the application identity rather than the signed in user, /me would be the application not the logged in user. What you want to do is: retrieve logged in user id from the Claim (Type: http://schemas.microsoft.com/identity/claims/objectidentifier) and use the /user/{userid} endpoint.
I found: for personal accounts (Get access without a user) in the body of the request you must to use grant_type = 'client_credentials' and for corporate accounts to use grant_type = 'authorization_code'

Resources