I'm developing an universal windows app (Windows 10) where I have a "Two-Layered" App: On IoT-Devices (e.g. Raspberry Pi 2) it just displays content, but on all other Devices (PC, Notebook, Smartphone, etc.) you have something like an controller for the displayed data.
One of the features I want to realize is the Windows Live Login in the Controller Part to get Calendar Information in the Display-IoT-Part. For that I give users the opportunity to login with Windows Live as shown below:
LiveAuthClient auth = new LiveAuthClient();
LiveLoginResult loginResult = await auth.LoginAsync(new string[] { "wl.signin", "wl.calendars", "wl.offline_access" });
if (loginResult.Status == LiveConnectSessionStatus.Connected)
{
//Save the AccessToken from loginResult.Session.AccessToken
TokenHandler.Save(loginResult.Session.AccessToken); //AccessToken is quite accessable right here
//But as far as I know I should save the RefreshToken, but the Session has no field for it
}
So my proplem is, that I don't get a field from the LiveConnectSession where the RefreshToken could be stored, but all articles I read are telling, that I just need to add wl.offline_access to the scopes for receiving an RefreshToken.
I'm not very familiar with OAuth2.0 and SDKs / APIs are building on OAuth, so does someone knows anything, what I'm doing wrong or how I have to handle it?
I'm really thankful for all well meant and helpful answers!
PS: I'm using the Live SDK 5.6 and not the new OneDrive API, because it has no access to Calendar Information
wl.offline_access
in this case it's talking about user authorization and allowing the app to have the user's authorization to work when they're not present (when the user is offline, instead of the computer/device).
This doesnt mean the app would login user when system is offline but would request user to allow app to work when user isn't present.
Even I had used the Live SDK to fetch user data in one of my earlier projects and but for calendar had to use Office365. Now you can even make use of Outlook API
Though we do get Access Token using loginResult.Session.AccessToken but I dont think a refreshToken is generated for WinRT app.
Related
I want my users to be able to upload videos to MY YouTube channel under MY YouTube account. Hence I don't really want or need them to authenticate (OAuth) as themselves.
I've seen the examples here: https://developers.google.com/youtube/v3/code_samples/dotnet
All of the code examples I find seem to use OAuth and client secrets to authenticate. Can anybody point me in the direction of a nice tutorial/sample whereby I can upload a video to MY Channel as MYself (using an API key?)?
Thanks.
UPDATE
Well....I'm not even sure if what I've done is right....but here is what I've done:
Went to Credentials for my project:
https://console.developers.google.com/apis/credentials
Created 2 OAuth credenials - one was Web Application and one was Other. I downloaded the JSON for these and added them to my project so I could test each one.
I enabled the YouTube data API here:
https://console.developers.google.com/apis/api/youtube.googleapis.com/overview
I largely took the .Net upload example from here:
https://developers.google.com/youtube/v3/code_samples/dotnet
I also installed the Nuget package for the YouTube API v3
before "var youtubeService =..." I added this:
// This bit checks if the token is out of date,
// and refreshes the access token using the refresh token.
if (credential.Token.IsExpired(SystemClock.Default))
{
if (!await credential.RefreshTokenAsync(CancellationToken.None))
{
Console.WriteLine("No valid refresh token.");
}
}
also created the following class - again, I obtained it from another StackOverflow post - with the aim of creating an offline access token??
public class OfflineAccessGoogleAuthorizationCodeFlow : GoogleAuthorizationCodeFlow
{
public OfflineAccessGoogleAuthorizationCodeFlow(GoogleAuthorizationCodeFlow.Initializer initializer) : base(initializer) { }
public override AuthorizationCodeRequestUrl CreateAuthorizationCodeRequest(string redirectUri)
{
return new GoogleAuthorizationCodeRequestUrl(new Uri(AuthorizationServerUrl))
{
ClientId = ClientSecrets.ClientId,
Scope = string.Join(" ", Scopes),
RedirectUri = redirectUri,
AccessType = "offline",
ApprovalPrompt = "force"
};
}
}
So I've tested it, and the upload eventually 'seems' to work, however:
The code never returns back to the View from await videosInsertRequest.UploadAsync(); and just seems to hang....UPDATE - Fixed. See here: https://www.codeproject.com/Questions/1087360/Youtube-data-API-for-uploading-videos-not-working
The video never actually appears in my channel - i have a feeling YouTube ban it before it's even uploaded? (it's just a test video - nothing sinister - could that be why?)
I have no idea if I am still doing this right.
Any more advice please? I still struggle to believe nobody has a working example of what I'm after. I can't believe that a user....uploading a video to my web server.....and then uploading to my own channel is so difficult!!
First off: It is impossible to upload videos with API keys.
From a technical point of view, API keys are not tied to a specific YouTube channel, but to a Google Cloud Console project. That means even if YouTube allowed API keys as authentication for uploading videos, they wouldn't know which channel to upload to.
For all write actions (e.g. uploading videos), proper authentication via OAuth 2.0 is required. Therefore, there are no tutorials that show how to upload using an API key.
As #Gusman said, you would need to let your users upload to your server, and then your server uploads to YouTube using OAuth credentials.
Regarding "'Installed Application' no longer seems to exist...":
The way you work with API keys and OAuth client IDs/secrets in your code has stayed exactly the same. Google just changed how you create and restrict access to keys in the Cloud Console.
I encourage you to familiarize yourself with the concept of server-side apps that use the YouTube API.
EDIT: to clarify the workflow
You set up a Cloud Console project and an OAuth client ID.
You give your permission to your application that it may upload videos to your channel. Your application will receive tokens (access token and refresh token) as a result.
Users of your application upload their videos to your application server.
Your application takes the user's video (which is now locally on your server) and the tokens from step 2 and uploads the video to YouTube with those tokens.
You must use oAuth, but what you want to skip is the user authentication step.
See this SO answer here
You need to obtain a refresh token and store that in your code along with the OAuth Key and Secret.
As for your "banned" video. If the video was uploaded as 'unlisted' it will not show up until you navigate to your Creator Studio -> Videos list
Recently, I faced with the following behavior of the ADAL for .NET, which is specific for this environment: Windows 10 + a corporate active directory.
...
authContext = new AuthenticationContext(authority);
...
var tokenResult = await authContext.AcquireTokenAsync(
resourceId,
clientId,
redirectUri,
new PlatformParameters(PromptBehavior.Auto, parentWindow));
Using the PromptBehavior.Auto I can't sign in with a proper account because the ADAL library doesn't show the sign in window (on the screenshot) but rather uses the account I'm currently logged into Windows 10 (which eventually and obviously leads to access denied error since the account I'm logged into Windows is not in the Azure AD I'm connecting to).
The interesting thing is that the same code works as expected for my colleagues who are working on Windows 7\8.
So, what's the possible problem here?
PromptBehavior.Auto will try to use an active token, but if not will show the login page if the refresh token is invalid/expired or credentials are required. You likely have a session that needs to be re-authenticated for one reason or another, and are getting prompted to sign in again for the user in the cache. If you're domain joined on the Win 10 device, it will automatically use that user.
You should be able to hit the Use another account button to sign in a different user. Alternatively, you can use PromptBehavior.Always which will ignore the cache and allow you to sign in a fresh user.
I am coding against OneDrive SDK within a console application. I am having some trouble trying to authenticate properly. I am curious to see if anyone has done this before or could point me in the right direction?
Code so far:
[STAThread]
static void Main(string[] args)
{
var scopes = new[] {"onedrive.readonly", "wl.signin"};
var msaAuthProvider = new MsaAuthenticationProvider(ClientId, "https://login.live.com/oauth20_desktop.srf", scopes);
msaAuthProvider.AuthenticateUserAsync();
}
Whenever I run my debugger I see the property of isAuthenticated is set to false.
Right now the MSA Authentication only supports Desktop and Windows Mobile Apps as it needs UI to require user sign in which broke in your case because you have a console app. So the problem is to build a IAuthenticationProvider which set the Authorization header in request message like:
public async Task AuthenticateRequestAsync(HttpRequestMessage request)
{
request.Headers.Authorization = new AuthenticationHeaderValue("bearer", await GetAccessTokenFromSomeWhere());
}
The IAuthenticationProvider interface defined in Microsoft.Graph.Core and you can pass it into OneDriveClient constructor so OneDriveClient will make request to OneDrive API for you.
Based on the information you have a console app, I would suggest you look at the code flow for Microsoft OAuth to get an access token and pass it to your authentication proivder.
I am not sure how you can get a code from the OAuth flow, but it seems doable if you fetch it in somewhere and pass it to your console app, then you can make POST request the the code you have to redeem an access token. I have searched for a while and don't find a good example of console app to get OAuth for Microsoft account, sorry. If you find a good way for console app to authentication, feel free to send a PR for MSAAuthenticator.
I succesfully read files from an user without interaction using the OAuth 2.0 Resource Owner Password grant and raw HTTP requests.
There are samples for authentication in daemon applications with application credentials, but first we would need to know how the application was registered and if belongs to a directory in Azure or not because app permissions need to be granted by a directory admin.
I'm brand new to Xamarin and playing around with a simple cross-platform app.
The app connects to an Azure Mobile Service, and requires login which I've set up server-side following tutorial: and client-side following tutorial.
Everything works fine! However, the current implementation requires you to login everytime you start the app. How can i cache the user credentials and auto-login as long as you don't log out?
I've tried something like this, but obviously didn't work:
When a user is logging in I save (I'm not calling directly to MobileServiceClient, just showing you a snippet):
var userId = MobileServiceClient.CurrentUser.UserId;
var authToken = MobileServiceClient.CurrentUser.MobileServiceAuthenticationToken
So i store these two strings, and when I next time open the app I try to:
CurrentClient.CurrentUser = new MobileServiceUser(userId);
CurrentClient.CurrentUser.MobileServiceAuthenticationToken = authToken;
As I said this does not seem to be the correct way since it does not work. What is the correct way to cache and auto-login an user?
You need to move over to a CLIENT-FLOW - in client-flow authentication, you use the client SDK provided by the auth provider and then pass that token silently to Azure Mobile Apps to authenticate there. Check out Chapter 2 of my book - http://aka.ms/zumobook
I have no idea how to start to retrieve my Facebook friends using the Facebook API. I have read the Graph API docs.
Secondly, I'm doing TDD so I want to start with my test cases.
At first, these will be integration tests because I have to integrate the real life Facebook api. After that works, I'll mock out these tests to make them unit tests.
So this is why I'm stuck. Please assume that I have a Facebook account (eg. email + password) so I can authenticate and then use the access token to get my friends.
UPDATE:
I also do have an FB App already setup (eg. app id / app secret).
The first thing that you need to do to get the list of friends, or any other api request on the behalf of the user, is to authenticate the user and get a user access token.
There are two authentication flows:
Client-Side: will result with a short lived access token (expires within a few hours) which you can then extend (on the server side) for a long lived using the new endpoint.
Server-Side: results with a long lived access token for about 60 days.
It will probably be hard to do that with TDD (at least at first), and so you might want to use one of the following facebook tools which will generate the access token for you:
Access Token Tool: gives you a list of `access tokens for all your apps bound to your own user'. Per application you get both a user token and an app token.
Graph API Explorer: Select your application at the top right corner and then click the "Get Access Token" button, then select the permissions you need and approve it, when the dialog closes you'll see the access token in the field.
With the access token that you get you can start querying the api.
To get the list of friends simply issue a request to me/fiends as explained in the Friends connection of the User object documentation.
I'm not a C# developer, but I'm aware of this C# SDK for Facebook, it should (like all other facebook SDKs) have implemented most of the work for you for sending the api requests and parsing the returned data.
From a quick look at their getting started documentation it should look something like:
var accessToken = "THE ACCESS TOKEN YOU HAVE";
var client = new FacebookClient(accessToken);
dynamic me = client.Get("me/friends");
...