Authenticate Azure AD using Provided Access Token - c#

I tried to find an Azure authentication mechanism that uses an access token as a parameter. but no luck. I just found ClientSecretCredential class that use tenant id, client id, and client secret as a parameter like below :
var clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret);
the reason I need the that is the access token will be generated by another service and my service will only accept access token to be used to authenticate Azure AD.
Actually, I can utilize Azure Management RestAPI to do that. However to improve developer experience I'd like to utilize .NET client library if possible.
I have tried to find documentation in Azure Identity client library in https://learn.microsoft.com/en-us/dotnet/api/overview/azure/identity-readme?view=azure-dotnet, but I couldn't find any class or method that I need.

If you want tokens from azure ad you can use using Microsoft.IdentityModel.Clients.ActiveDirectory; library to get the tokens.
I am assuming that you have already created an azure ad app registration and already possess the client_id , client_secret and tenant_id. Just save this as strings in code.
Now we can use the clientcredential along with authenticationContext we can acquire tokens.
Complete program :
string client_id = "";
string client_secret = "";
string tenant_id = "";
string endpoint = "https://login.microsoftonline.com/"+tenant_id;
ClientCredential credent = new ClientCredential(client_id , client_secret);
var context = new AuthenticationContext(endpoint);
var result = context.AcquireTokenAsync("https://management.azure.com/",credent);
var result = context.AcquireTokenAsync("https://management.azure.com/",credent);
Console.WriteLine(result.Result.AccessToken);
Here result.Result.AccessToken will give you a access token in form of a token.

Related

Access token not containing SCP (roles) claims via Microsoft Graph

I'm using the Microsoft Graph SDK to get an access token for my application (not a user) in order to read from sharepoint. I've been following this document, as well as posted this SO question. The code in the linked SO is the same. I was able to add application permissions as well as grant them (by pressing the button) in azure portal. The problem is, the token that comes back to be used does not contain any roles / scp claims in it. Therefore when using the token, I get the "Either scp or roles claim need to be present in the token" message.
Just to be certain, the only value for my scope that I pass when getting the access token is: https://graph.microsoft.com/.default. I don't pass anything else like Sites.ReadWrite.All (I get an exception if I add that scope anyway). I'm not sure how to continue troubleshooting and any help would be appreciated.
Edit: added code using the graph SDK shown below:
var client = new ConfidentialClientApplication(id, uri, cred, null, new SessionTokenCache());
var authResult = await client.AcquireTokenForClientAsync(new[] {"https://graph.microsoft.com/.default"});
var token = authResult.AccessToken;
var graphServiceClient = new GraphServiceClient(new DelegateAuthenticationProvider(async request => {request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token)}));
var drives = await graphServiceClient.Sites[<sharepoint_host>].SiteWithPath(<known_path>).Drives.Request().GetAsync();
Seems like doing the app initialization in a different way is the solution. Instead of this:
var client = new ConfidentialClientApplication(id, uri, cred, null, new SessionTokenCache());
do this:
var app = new ConfidentialClientApplication(ClientId, Authority, RedirectUri, credentials, null, new TokenCache());
The problem is, the token that comes back to be used does not contain
any roles / scp claims in it.
If you can not find any roles/scp claims in the decoded access token. You need to check the permission in Azure portal again.
The decoded access token should contain the roles you granted.
Login Azure portal->click Azure Active Directory->click App registrations(preview)->find your application.
Click your application->API permissions->check if you have grant admin consent for your application. If not, click 'Grant admin consent'.
The code for getting access token. You can find more details here.
//authority=https://login.microsoftonline.com/{tenant}/
ClientCredential clientCredentials;
clientCredentials = new ClientCredential("{clientSecret}");
var app = new ConfidentialClientApplication("{clientId}", "{authority}", "{redirecturl}",
clientCredentials, null, new TokenCache());
string[] scopes = new string[] { "https://graph.microsoft.com/.default" };
AuthenticationResult result = null;
result = app.AcquireTokenForClientAsync(scopes).Result;
Console.WriteLine(result.AccessToken);

Generate bearer token client side C#

Im am working with a REST service deployed in an azure environment. I want to run some integration testing by calling various API functions from a separate (console) application. But the REST api uses bearer token authentication. Im a total noob with azure authentications, so i don't even know if it should be possible.
I've tried to use the example found here but no luck yet.
In anycase, I have two applications. One is the console app that is running the code, and the other is the Rest service for which i need to use the bearer token to access the API calls. I will call them the ConsoleApp and RestService.
The code I run is as following:
HttpClient client = new HttpClient();
string tenantId = "<Azure tenant id>";
string tokenEndpoint = $"https://login.microsoftonline.com/{tenantId}/oauth2/token";
string resourceUrl = "<RestService app id url>";
string clientId = "<azure id of the ConsoleApp>";
string userName = "derp#flerp.onmicrosoft.com";
string password = "somepassword";
string tokenEndpoint = $"https://login.microsoftonline.com/{tenantId}/oauth2/token";
var body = $"resource={resourceUrl}&client_id={clientId}&grant_type=password&username={userName}&password={password}";
var stringContent = new StringContent(body, Encoding.UTF8, "application/x-www-form-urlencoded");
var result=await client.PostAsync(tokenEndpoint, stringContent).ContinueWith<string>((response) =>
{
return response.Result.Content.ReadAsStringAsync().Result;
});
JObject jobject = JObject.Parse(result);
The Json message I get back:
error: invalid_grant, error_description: AADSTS50105: The signed in
user is not assigned to a role for the application "RestService
azureid"
What does that mean, and how what needs to be done to get a bearer token out of this?
Please firstly check whether you enabled the User assignment required of console application :
In your azure ad blade ,click Enterprise applications ,search your app in All applications blade ,click Properties :
If enabled that , and your account not assigned access role in your app , then you will get the error . Please try to assign access role in your app :
In your azure ad blade ,click Enterprise applications ,search your console app in All applications blade ,click Users and groups , click Add User button , select your account and assign role(edit user and ensure select role is not None Selected):
Please let me know whether it helps.

Cant authenticate user silently with ADAL for Office 365 REST API on ASP.NET MVC

So I'm trying to implement persistent tokens for our office authentication so that the user does not have to sign into office each time they are in a new session. The code I currently have to authenticating the user is as below.
string authority = "https://login.microsoftonline.com/common";
var tokenCache = new ADALTokenCache(User.Identity.GetUserId());
AuthenticationContext authContext = new AuthenticationContext(authority, tokenCache );
var token = authContext.AcquireTokenSilentAsync(scopes, clientId, new UserIdentifier(userId, UserIdentifierType.RequiredDisplayableId));
But everything I've tried so far gives me the error below
The Exception is: "Failed to acquire token silently. Call method AcquireToken"
The method Im using to aquire the token in the first place is as below
string authority = "https://login.microsoftonline.com/common";
var fileCache = new ADALTokenCache(User.Identity.GetUserId());
AuthenticationContext authContext = new AuthenticationContext(authority, fileCache);
var authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
authCode, redirectUri, credential, scopes);
And the token cache im using is a db implementation which I made from a tutorial which I cannnot find again, if I watch the db I can see that new tokens are being inserted into the db when AcquireTokenByAuthorizationCodeAsync is called.
Update:
This is my result from authResult when calling AcquireTokenByAuthorizationCodeAsync
I have marked Virbonet's answer as the solution but I have not fixed it but he did explain to me where I was going wrong
AcquireTokenSilent cannot work if you are passing /common in the authority. Using "common" is equivalent to declaring that you don' know what tenant is the user from, hence ADAL cannot return a cached token form a specific tenant - user interaction is required to determine which tenant should be used.
If you want to call AcquireTokenSilent you need to initialize the authority with the exact tenant of the incoming user, as in "https://login.microsoftonline.com/"+tenantID here tenantID is the tenantID from the current ClaimsPrincipal.
This is the function call you need to use: AcquireTokenByAuthorizationCode() but not AcquireTokenSilent().
Hope this helps.

Failing to authenticate windows live accounts Windows Azure AD

Users are created in azure AD for a native application that i built. I would like users to use their windows live ID if they have one, otherwise I would create an AD account for them.
AD accounts are able to login, but whenever a windows live account tries to login I get the following error message
No service namespace named 'timetray' was found in the data store.
I'm not sure what this means, what is the service namespace, or where can i find the datastore.
The name for the service namespace that i am using is the resource id uri for an application that I provisioned in the Active Directory
private Uri redirectUri = new Uri("http://TimeTray");
private string clientId = "{{Client-ID}}";
private AuthenticationContext _authenticationContext;
private string domainName = "common";
private string resourceAppIdUri = "http://TimeTray";
private string resourceBaseAddress = "http://timetray.azurohosted.com/";
public void Authenticate(OnLoginComplete onLoginComplete)
{
CredManCache creds = new CredManCache();
_authenticationContext = new AuthenticationContext("https://login.windows.net/" + domainName, creds);
AuthenticationResult authenticationResult = _authenticationContext.AcquireToken(resourceAppIdUri, clientId, redirectUri);
// _authenticationContext.AcquireToken(
UserEntity user = new UserEntity();
user.NTUserName = authenticationResult.UserInfo.UserId;
user.SID = authenticationResult.UserInfo.UserId;
onLoginComplete(user);
}
I assume you are setting up ADAL with AAD.
When creating AuthenticationContext:
Instead of https://login.windows.net/" + domainName (common)
Try
https://login.windows.net/[Guid for the web api configured on your client in Azure AD]/FederationMetadata/2007-06/FederationMetadata.xml
In its data store, Azure will now look for service namespace [guid] instead of what is deferred from the login name "billy"#timetray.onmicrosoft.com.
See in MSDN sample
http://code.msdn.microsoft.com/AAL-Native-Application-to-fd648dcf#content
It states "Set the authority to https://login.windows.net/common to defer choosing the AAD domain till the user signs in."
Also, use http://www.nuget.org/packages/Microsoft.IdentityModel.Clients.ActiveDirectory/
I guess you also need to create users in Azure AD that are linked to existing Microsoft Accounts.

c# - how to get user access token without login from facebook?

I want to get user access token(Graph API Explorer) from facebook without login
I tried with app access token but I am unable to get comments for the posts
Code is for app access token:
string appId = "APP_Id";
string appSecret = "APP_Secret";
var fb = new FacebookClient();
dynamic result = fb.Get("oauth/access_token", new
{
client_id = appId,
client_secret = appSecret,
grant_type = "client_credentials"
});
fb.AccessToken = result.access_token;
var accessToken = fb.AccessToken;
Any ideas? Thanks in advance.
You have to create a new instance of the FacebookClient with the Users AccessToken to get info about the User!
I think here is no way you get the Token without calling the FB.Login
From the API Documentation:
User Access Token – The user token is the most commonly used type of token. This kind of access token is needed any time the app calls
an API to read, modify or write a specific person's Facebook data on
their behalf. User access tokens are generally obtained via a login
dialog and require a person to permit your app to obtain one.

Categories

Resources