How to log external in .net web api 2 - authentication

I'm trying to log in and register with external authentication using MVC5, web api 2 and templates from it.
I don't know how to do it. I read
asp.net web api 2: how to login with external authentication services?.
When I call
GET /api/Account/ExternalLogins?returnUrl=%2F&generateState=true
response is
{
"Name": "Facebook",
"Url": "/api/Account/ExternalLogin?provider=Facebook&
response_type=token&
client_id=self&redirect_uri=http%3A%2F%2Flocalhost%3A6685%2F&
state=Yj1...hU1",
"State": "Yj1...hU1"
}
(I don't know what is State for)
Then i can use the Url above (authentication is with cookies) and response is OK html status and some html page (i dont know why)
This call
GET /api/Account/UserInfo
response info with null loginProvider.
I want to register user with FB or Google, so i need token, but i don't know whitch access_token and how can i get it. In example (link above) is this:
POST /api/Account/RegisterExternal
Authorization: Bearer VPcd1RQ4X... (access_token from url)
Content-Type: application/json
{"UserName":"myusername"}
but what is
access_token from url ?
So, my questions are:
How can I external register / login with web api 2 templates?
What is State for? (seems like useless)

External login is Web Api is supported out of the box and can be easily plugged in using the Owin pipeline. Gettting the access token and performing all the oauth related calls are done by the Facebook Owin Provider.
You can find a sample of facebook login with a web site here

Related

Leveraging REST API's stateful token-based authentication pattern in its sole client (a web application), restricting some pages to loggedin users

I'm working on a REST API and a web application that will work off said REST API. The REST API implements a stateful token-based authentication pattern. Ultimately, allowing users to exchange their user credentials for a time-limited authentication token that identifies who they are.
So for example, a request such as:
POST: http://localhost:4000/api/v1/tokens/authentication
REQUEST BODY: {"email": "my_email_address", password": "my_password"}
would yield a response like:
"authentication_token": {
"token": "GAHZQS3IEIE6ELF7IHC6GK7M5Y",
"expiry": "2022-07-19T02:49:09.4194657+01:00"
}
If the user credentials that the user entered were incorrect, the user would not receive the authentication token.
The user needs to include the token in any further requests so that the REST API can identify the user. Some API endpoints are restricted to just logged-in users/users with certain permissions. And the token allows the REST API to know what sort of user it's dealing with. The token corresponds to a user id.
There will be a separate server from the REST API server serving the web application pages. But the pages will be populated with data from the REST API via the javascript fetch API.
I am happy with the REST API authentication. But I also need to restrict access to the web application pages based on if the user has logged in or not.
I want to leverage the existing REST API authentication but have never done something like this before so would very much appreciate any input you have.
Currently, I'm thinking of doing something like what's listed below. Do ye see any problems with it?
User accesses login page, enters credentials, and clicks 'login' button.
On clicking the 'login' button a request to the REST API is made:
POST: http://localhost:4000/api/v1/tokens/authentication
REQUEST BODY: {"email": "my_email_address", password": "my_password"}
If the credentials are correct, a token is returned, such as:
"authentication_token": {
"token": "GAHZQS3IEIE6ELF7IHC6GK7M5Y",
"expiry": "2022-07-19T02:49:09.4194657+01:00"
}
This token is added to a cookie for later use. i.e for when making another request to the REST API via the fetch API.
I'm thinking of adding another REST API endpoint that will simply validate a token i.e state whether or not the passed token is still valid and that the user is still logged in.
The webpage server can then call this endpoint to ensure the token is valid before showing a user a page that is restricted to just logged-in users.
Or maybe, instead of a validate token API endpoint, I should have a 'get user by token' endpoint. That will return user data if the token is valid. That way the webpage server could also get to know the type of user account that is associated with that user and could then also restrict pages based on the user type. It might also come in use for populating pages since nearly all pages will contain some user info e.g a profile image.

Google Photos API - authentication

I'm trying to get list of my shared albums from Google Photos.
I found a enable Photos API in Google Developers Console.
HTTP GET:
https://content-photoslibrary.googleapis.com/v1/sharedAlbums?key=AIzaSyCkXXXXXXXXXXXXXZiOSe9IiyM8E
RESULT:
{ "error": { "code": 401, "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.", "status": "UNAUTHENTICATED" } } 1
Configuration in developers console:
Please, what I'm doing wrong? Thank you.
Google API need an access token to make sure that the user has the permission to access the feature. Access token is just like cookie that should be send together with the request.
Usually you will need so many setup to get the access token with your own code. But there are a client library that can help you access Google API with small setup.
Access token also has a lifetime, so if you don't use the library you will need to manually refresh the token.
You need to configure OAUth 2.0 credentials (client ID and secret) and not an API key. More details are in the developer documentation here: https://developers.google.com/photos/library/guides/get-started#request-id
The Google Photos library API acts on behalf of a user, that's why you need to authenticate via OAuth 2.0. As part of this request you also need to specify a scope for your users to accept, see this page for more details: https://developers.google.com/photos/library/guides/authentication-authorization
I've been working on a python project to backup google photos library and album info. you can probably modify it to do exactly what you want. It is fully working but does not currently distinguish between shared and private albums.
https://github.com/gilesknap/gphotos-sync
In particular, see https://github.com/gilesknap/gphotos-sync/blob/master/gphotos/authorize.py which handles authentication and authorization for any Google service (it also handles storing the token and refreshing the token).

Accessing the `student_view_url` via Open Edx API authentication or alternatives?

I’m working on a React Native application where all the Edx course information needs to be displayed offline.
I’ve authenticated the app using oauth2 endpoint (client_id=…&grant_type=password&username=user#example.com&password=p455w0rd to {{root}}/oauth2/access_token/) and can access the API endpoints to get the users enrolled courses ({{root}}/api/enrollment/v1/enrollment) and the blocks within those courses ({{root}}/api/courses/v1/blocks/?course_id={{course_id_url_friendly}}&depth=all&nav_depth=3&return_type=list&username={{username}}). What I’m struggling to get is the contents of the HTML blocks.
I see in the official app (when viewing requests via a proxy) that it will request the actual webpage of the course, presumably the student_view_url.
Is this the only way to get that content or is there an API endpoint I can use to return the content?
If the only way is to request the rendered student_view_url, how do I access that page? The only way I can tell in the official app is it looks like it’s passing the cookies to authenticate with the studen_view_url, which it must get when it authorises the user via the oauth2 endpoint. The cookies I get don’t work though, which I’ve tested in Postman (if I use cookies that I got from browsing my Edx site in Chrome, they do work). This begs me the question, is my authentication correct as I don’t get any scope returned when the official app returns a scope filled in with read write and two others.
A sample of what my authentication returns:
{
"access_token": "a12345...",
"token_type": "Bearer",
"expires_in": 2591999,
"scope": ""
}
To reiterate;
Is there a way to request the HTML content via the API (so returned in a JSON request) rather than the student_view_url
If not then how do I authenticate to access the student_view_url?
So I worked out how to do point 2.
Before requesting any HTML content you need to hit the endpoint {{root}}/oauth2/login/ with the auth token that you provide to other endpoints. This will pass back a usable sessionid cookie that will let you access content that's not public (so long as the user has access).
As an aside, to pass the cookie through fetch() requests, I had to pass the option credentials: 'include'.

Azure AD Bearer invalid_token error using Postman

I am really new to Azure AD. I have read the Azure AD documentation which provides information on authentication and accessing web API's.
What I want to do : I want to use Dynamics CRM API to create a lead or contact through AWS Lambda. Meaning, whenever the Lambda function is ran, it should call the CRM API. The way I need to create a lead is with username and password creds included in Lambda. I am not sure which application scenario I need to use when I am using AWS Lambda as the source to access the web api. I want to pass the user creds with POST request.
Creating an application in Azure AD : So, I am not sure which application type I need to use (Web API or Native App?). And what should be the sign-on URL or Redirect URI?
I have tried creating an application and use Postman as the temporary way just to test whether I can get the access token and access the web api. I could able to get the access token but when I tried to access the API it says
Bearer Error invalid_token, error validating token!
I have given enough permissions while creating application in Azure AD to access Dynamics CRM API. But still unable to access the API.
POST request to get access token through Postman:
request: POST
URL: https://login.windows.net/<tenant-id>/oauth2/token
Body:
grant_type: cliet_credentials
username: xxxxx
password: xxxxxxx
client_id: <app id>
resource: <resource> //I am not sure what to include here
client_secret: <secret_key>
I get the access token in the response. Sending the second POST request using the access token
request: POST
URL: https://xxx.api.crm.dynamics.com/api/data/v8.2/accounts
Headers:
Content-type: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
Authorization: Bearer <access_token>
Body:
{
"name": "Sample Account",
"creditonhold": false,
"address1_latitude": 47.639583,
"description": "This is the description of the sample account",
"revenue": 5000000,
"accountcategorycode": 1
}
It would really help me if I can get a bit more information on where I am stuck. I have already used my one week of time to get this done. Any help will be appreciated.
To do Server-to-Server (S2S) authentication , the application is authenticated based on a service principal identified by an Azure AD Object ID value which is stored in the Dynamics 365 application user record. Please click here and here for detail steps and code samples.

Twitter login POST request in Periscope API

I am trying to use Periscope API (https://github.com/gabrielg/periscope_api/blob/master/API.md) in my application. As in the API link I am trying to send POST request to https://api.periscope.tv/api/v2/loginTwitter?build=v1.0.2
with request body as following
{
"bundle_id": "com.bountylabs.periscope",
"phone_number": "",
"session_key": "<twitter_user_oauth_key>",
"session_secret": "<twitter_user_oauth_secret>",
"user_id": "<twitter_user_id>",
"user_name": "<twitter_user_name>",
"vendor_id": "81EA8A9B-2950-40CD-9365-40535404DDE4"
}
I already have an application in https://apps.twitter.com/ but I don't know what to use as twitter_user_oauth_key and twitter_user_oauth_secret. Can you help?
I must say https://github.com/gabrielg/periscope_api/ implementation is a bit complicated. Author using 2 sets of keys (IOS_* and PERISCOPE_*) when you actually need only one to access API. I didn't tried to broadcast but in my PHP library all other functions works without troubles with only what he call PERISCOPE_* set of keys.
You will get session_secret and session_key from Twitter after getting access to it as Periscope application.
So Periscope's login via Twitter process looks like
Request OAuth token via https://api.twitter.com/oauth/request_token
Redirect user to https://api.twitter.com/oauth/authorize?oauth_token=[oauth_token]
Wait for user login and get oauth_token and oauth_verifier from redirect url
Get oauth_token, oauth_token_secret, user_id and user_name via request to https://api.twitter.com/oauth/access_token?oauth_verifier=[oauth_verifier]
Send request to https://api.periscope.tv/api/v2/loginTwitter
{
"bundle_id": "com.bountylabs.periscope",
"phone_number": "",
"session_key": "oauth_token",
"session_secret": "oauth_token_secret",
"user_id": "user_id",
"user_name": "user_name",
"vendor_id": "81EA8A9B-2950-40CD-9365-40535404DDE4"
}
Save cookie value from last response and add it to all JSON API calls as some kind of authentication token.
Requests in 1 and 4 steps should be signed with proper Authorization header which requires Periscope application's consumer_key and consumer_secret. While consumer_key can be sniffed right in first step (if you are able to bypass certificate pinning) consumer_secret never leaves your device and you can't get it with simple traffic interception.
There is PHP example of login process https://gist.github.com/bearburger/b4d1a058c4f85b75fa83
Periscope's API is not public and the library you are referring to is sort of a hack.
To answer the original question, oauth_key & oauth_secret are keys sent by your actual device to periscope service. You can find them by sniffing network traffic sent by your device.