How can a Daemon application with client_credentials authentication obtain delegated permissions from a specific user? - authorization

I have written a java program to upload files to Sharepoint in an Office 365 developer tenant where I am an adminstrator. The program authenticates with client_credentials with secret. After Authentication, it does not have an office 365 identity.
The requirement is to upload a file to a specific folder. The user is ready to share their folder, but I can't find a workflow with a daemon application to accomplish this.
Can the admin approve the application to access the user's folder?
In my developer tenant, I have Application Permission of File.ReadWrite.All and the program works fine. However, we will not get approval for Files.ReadWrite.All in production. The question is how can I use Delegated Permissions of File.ReadWrite and authenticate my daemon app so I can upload files to one folder. My application runs on Dell Boomi. Thanks

Firstly, application permission (client_credentials flow) is supported to upload the file to Sharepoint online.
ClientCredentialProvider authProvider = new ClientCredentialProvider(
clientId,
scopes,
clientSecret,
tenant,
endpoint);
IGraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider(authProvider).buildClient();
byte[] stream = Base64.getDecoder().decode("The contents of the file goes here.");
graphClient.users("{userId}").drive().items("{item-id}")
.buildRequest()
.put(stream);
But if you cannot grant Application Permission File.ReadWrite.All in the production environment and you cannot implement interactive login in daemon app, you should consider ROPC flow.
Note there is a warning:
Microsoft recommends you do not use the ROPC flow. In most scenarios,
more secure alternatives are available and recommended. This flow
requires a very high degree of trust in the application, and carries
risks which are not present in other flows. You should only use this
flow when other more secure flows can't be used.
Please refer to Username/password provider.
UsernamePasswordProvider authProvider = new UsernamePasswordProvider(
clientId,
scopes,
username,
password);
IGraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider(authProvider).buildClient();
byte[] stream = Base64.getDecoder().decode("The contents of the file goes here.");
graphClient.me().drive().items("{item-id}")
.buildRequest()
.put(stream);

Related

AD FS access token to web API without user intervention

Looking for a way to get an app access token that can make calls to an API without making the user sign in. I have accomplished this use case using Azure AD where I get an app access token to write documents to a SharePoint library. I am not familiar enough with on prem AD FS and how to access getting an access token using a client secret so I don't have to interfere with the user.
Background
We have built a custom help desk application on a set of APIs. Our goal is to be able to create tickets from other systems (applications) that require a ticket to be created. The idea is to generate an access token that has permission to the API so I can create the ticket without the user being prompted to login since the ticket will not be specific to the user in some cases.
Example Use Case
We have an application that provisions non-employees to access resources in our environment. These non-employees have end dates associated to them, when the end date is passed and they were not renewed beforehand, a ticket will need to be generated for a team to update their record in AD.
What I have done
I have created a 'server application' in AD FS and generated a client secret. I am able to make a request and get an access token using the client secret, however, it is not 'linked' per say to the Wep API I need to call.
How would I give permission to the server application to access the web API?
Additional
We are using AD FS on Server 2016.
You need the confidential client flow.
Essentially, you configure an application and a web API.
By default, the application has permission to call that web API but you can play around with the access control policies.
Also note that you can configure claims rules on the web API.
This may also be useful.
Found the issue causing the token I was receiving via the server application to give me an 'Authorization denied' response from the API.
It turns out that the AD FS configuration was correct, the issue was in my API with the valid audience and valid issuer.
app.UseActiveDirectoryFederationServicesBearerAuthentication(new ActiveDirectoryFederationServicesBearerAuthenticationOptions
{
MetadataEndpoint = ConfigurationManager.AppSettings["ADFS:MetadataEndpoint"],
TokenValidationParameters = new TokenValidationParameters()
{
ValidAudiences = GetValidAudiences(),
ValidIssuers = GetValidIssuers()
}
});
I needed to include the issuer and the audience that the server app was providing in the Access Token
ValidIssuer Example
microsoft:identityserver:{appIdentifier}
ValidAudience Example
http://{fqdn}/adfs/services/trust
upon adding those to the validIssuer and validAudience the access token worked perfectly.

How can I test the Microsoft Authentication process using automation?

I am new to Microsoft Graph Framework. I recently developed a web application with Graph API's integration.
The first time browsing to the page on my app, it redirects the user to Microsoft app login page and prompt for credentials. Once authentication successful then I use the authentication token to get the user's emails and do post processing on those emails.
However, I need to write tests to see if the token is being persisted properly and for the subsequent processing on emails. All my tests are automated tests that are run on jenkins which is not set up to run with a browser. And without having the authentication token, I am unable to test the downstream process. Is there a way to get the token through an API without requiring a browser/user intervention?
For automated tests running in Jenkins, you probably want to use an auth flow that doesn't require the user to login. Please see the documentation page on Getting auth tokens without a user for detailed information.
In summary, you can register an app on the App Registration site and add application permissions like User.Read.All. Since the goal is to get tokens that work without a user login, you'll need to grant your app access to run as a service by getting administrator consent. After that one time setup, you can then easily request tokens by POSTing to the token endpoint with your app info and secret.
Perhaps you could use the username/password authentication flow, where your test doesn't go through the normal interactive experience.
You need to create a UserCredential and use that to acquire a token.
UserCredential uc = new UserCredential(user, password);
public Task<AuthenticationResult> AcquireTokenAsync(
string resource, string clientId, UserCredential userCredential);

Connect MS OneDrive from Window Service (background task)

I went thru at Microsoft OneDrive API tutorials and they are only guiding people how to connect OneDrive with UI mode. Which means there will be a prompt asking user to authenticate access to the OneDrive (OAuth2). What if I want this to be skipped, or the other way meaning, I want everything authenticate in silent mode (service mode)? Any guidance?
https://github.com/OneDrive/onedrive-sdk-dotnet-msa-auth-adapter
If you want to access OneDrive in the context of a user, you need to use the interactive OAuth2 flow to be granted consent and receive an access_token and refresh_token. This is only required when initially setting up the configuration.
Once you have a refresh_token available, that can be silently redeemed for a new access_token.
If you want to make a background task / Windows Service that stays connected to OneDrive in the context of a user, you would need to have an interactive configuration experience to "Add a OneDrive Account" and go through the OAuth2 flow. Once that has been completed, the service can use the stored refresh_token to generate new access_tokens and make API calls.
There are a few scenarios where the refresh_token will become invalid, that you would need to prompt for credentials again:
The user changes their password
The user revokes access to the application
An enterprise configures an expiration period on refresh_tokens (OneDrive for Business only)
Your service would need to handle these scenarios and have a way to prompt that additional configuration was required.

How to start with OAuth Client Credentials to protect WebApi using OWIN Oauth?

I am a newbie to OAuth 2.0.
I have fairly read the OAuth 2.0 doc and I saw there are four types of methods for obtaining Authorization.
Types of obtaining authorization:
1.Implicit Grant
2.Resource Owner Password Credentials Grant
3.Client Credentials Grant
4.Authorization Code Grant
In my case, I have Client application, Resource owner, Resource server and Authorization server.
Resource server is a website where Resource owner registers with his/her credentials.
Client application is a third party website who registers into resource server and gets the Client application credentials for accessing it in future.
Authorization server checks the client credentials from client app and grants access token to the client app.
Let us consider, resource server as "www.serversite.com", authorization server as "www.authserver.com" and client application as "www.clientapp.com".
Flow:
Step 1: Also make an assumption that www.serversite.com as a payment gateway site and the client has to integrate "www.serversite.com" into "www.clientapp.com" for creating, executing and refunding payments.
Step 2: So the client "www.clientapp.com" creates an app in server "www.serversite.com" and gets API credentials.
Step 3: Using these API credentials, the client "www.clientapp.com" makes an access token request to the auth server "www.authserver.com".
Step 4: If the API credentials from client app are valid then the auth server grants an access token.
step 5: With this access token, client app request the resource server for further operations like creating payments as well as executing payments.
My questions:
I am using ASP.NET Web API for authorization server and using OWIN.OAuth for generating access token, refresh token, authorization and all the stuffs needed to authorize the client app.
But, in this link (OWIN OAuth 2.0 Authorization Server), I found that, the web api authorize the client app using "Resource Owner Password Credentials Grant" and the sample provided for implementing Owin.OAuth in web api is great, but I have lot of confusions roaming in my mind.
Which way of obtaining authorization is suitable for my process?
(Client Credentials flow or Resource Owner Password Credentials flow)
How to implement Client Credentials Grant type using ASP.NET Web
API(OWIN OAuth)?
Also provide some samples or links that may be helpful for me?
Thanks in advance.
Theres an example of how to get started on the asp.net website, specifically here:
http://www.asp.net/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server
I quote:
private Task GrantClientCredentails(OAuthGrantClientCredentialsContext context)
{
var identity = new ClaimsIdentity(new GenericIdentity(
context.ClientId, OAuthDefaults.AuthenticationType),
context.Scope.Select(x => new Claim("urn:oauth:scope", x))
);
context.Validated(identity);
return Task.FromResult(0);
}
Obviously you will need to go ahead and verify the actual client id / secret exist perhaps in a local database sometwhere before you go ahead and set the context to validated.
In terms of deciding which flow to use, you need to ask yourself, if the application is requesting access to your APIs on behalf of an actual user, then you need to use Resource Owner, however if the application itself needs access then Client Credentials is the way to go.
Generally speaking though, most implementations use Authorisation Code Flow, so if you can form a security stand point, get the users redirected to a page you host to take their credentials, opposed to sending them over the wire via Resource Owner Flow.

Connect to Azure to create an Application registration

I'm trying to write a C# console app that will register an application in Azure Active Directory. It should work just as the web application project creation wizard in VS 2013 when you Change Authentication and select Organizational Accounts in Azure.
Following the fiddler trace, I can see that it authenticates the user using wsfederation and an oauth2 token and then uses the graph.windows.net graph api to configuration the AAD directoryObjects service principal and application.
I have tried to use the sample Graph API app, but it requires the app be registered first so that I have the clientId (application id) and password (key) to send in the Acquire Token request using the Windows Azure AD Authentication Library for .NET.
I've tried using a bunch of the different Azure APIs but they all have my chicken and egg problem, I want to use an unregistered client application to register an application in AAD. I need to avoid Configuring Application Authentication and Authorization for the Graph API so that the user has no manual steps.
Does anyone know how Visual Studio does it, using just the user login with browser prompt or if there is a standard application id and password that can be used to access the graph API, like there is the standard login URL, https://login.windows.net/common? Some C# samples would be greatly appreciated.
This post does the Application creation, but requires a clientId and password, which I don't think I have.
You can't register a new application using the Graph API from an unregistered client. The only reason the VS2013 flow works is because VS2013 is already registered in a special way within Azure AD -- it's a first party application and has unique permissions. In my Fiddler trace, VS2013 uses a client ID of 872cd9fa-d31f-45e0-9eab-6e460a02d1f1. Technically you can use this client ID and the redirect URI of VS2013 to initiate sign-on with Azure AD. This still involves user interaction (the user has to authenticate via browser pop-up) so it doesn't meet your requirement for "no manual steps," but it's somewhat helpful for understanding the protocol flows and how registration works.
The bottom line is that if you want to call the Graph API without user interaction (client credential flow), the client needs to be registered with the proper application permissions.