How to implement OAuth 2.0 in ASMX (web-reference)? - c#

I am very new in implementing OAuth 2.0. I have implemented web-reference (ASMX file) in my xamarin project. Now I need to implement OAuth 2.0 for authentication. But I am not sure if ASMX supports OAuth2.0 or not. Do I need to implement WCF instead of Web refernce(ASMX) or is it possible in web reference (ASMX) to implement the OAuth2.0?

One possible solution is to add the token aquired from the authority to the Authorization header.
Your code could look similar to this:
var redirectURI = Windows.Security.Authentication.Web.WebAuthenticationBroker.GetCurrentApplicationCallbackUri();
var _authContext = new AuthenticationContext(authority);
var tokenResult = await _authContext.AcquireTokenAsync(serviceResourceId, clientId, redirectURI);
if (tokenResult.Status != AuthenticationStatus.Success)
{
//Not authenticated
return;
}
var svc = new YourServiceReference.YourClient();
using (var scope = new OperationContextScope(svc.InnerChannel))
{
var httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers[System.Net.HttpRequestHeader.Authorization] = tokenResult.AccessToken;
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
var result = svc.MyFunction();
//Do something with the data
}

Tricky - this is how mobile OAuth solutions work - but it is a big job:
Your Xamarin app would need to implement Mobile SSO to sign users in
Users of your Xamarin app would be redirected to login via an Authorization Server / Identity Provider after which they will receive an OAuth access token
After login your Xamarin App would then be able to call an API with the token and act on behalf of the user to get data
The API would need to validate received access tokens
SOLUTION PARTS
API: ASMX is an old technology so if you are working on the Microsoft stack you would use something newer such as a .Net Core Web API
MOBILE APP: The harder part of the solution will be implementing Mobile SSO, if you have not done so already.
How much of this solution exists already?

Related

Sharepoint REST api and MVC AAD connect

My need is to execute this query https://<tenant>.sharepoint.com/_api/search/query?querytext=%27contenttype:articles%27 thru Sharepoint REST api from server side in C#.
I have Oauth2 connection from the MVC portal, so my goal is to retrieve token from connection and send it as bearer token to sharepoint endpoint.
I mean something like that
string userObjectID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
AuthenticationContext authContext = new AuthenticationContext(Startup.Authority, new NaiveSessionCache(userObjectID));
ClientCredential credential = new ClientCredential(clientId, appKey);
AuthenticationResult result = await authContext.AcquireTokenSilentAsync("https://<tenant>.sharepoint.com/", credential, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "https://<tenant>.sharepoint.com/_api/search/query?querytext=%27contenttype:articles%27");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
HttpResponseMessage response = await client.SendAsync(request);
but obviously, I can not retrieve the token...
On another side, I have built an app with ADv2 and GraphServiceClient that is working well, but I don't know how to translate the query in graph model (and I don't have any admin-consent).
So, I have 2 ways to resolve my issue, I'll like better use the 2nd option with microsoft graph api, but any help is welcome.
Thank you.
Around Search
The graph search API has limited capabilities, first it will only search in the current site collection (drive) you're targeting, second I'm not sure at the moment it would support a search by content type (maybe with a $filter...)
But it could be an (easier) option if that fits your constraints.
Around auth & auth
In both cases (graph or SharePoint search), what happens when people get to your application (asp.net MVC) is that the authentication middleware takes care of redirecting the user to AAD, get an access token to your app, redirects it to your app which uses that access token to create a session on the app.
My point being: at this point, all you have are:
An access token to your app (not the graph, not SharePoint
A session against your app
You need to do a couple of things to get to SharePoint/the graph:
Intercept and keep the token server side (add it to the session?) if that's not already being done by your implementation of the middlewares
Use that access token + you app id/secret/certificate to get an access token to SharePoint/the graph against AAD
Make sure your application has permissions in AAD to talk to SharePoint/The proper graph API's
Here is a sample on how to get from "I have the access token to my app/api" to "I have an access token to the graph/SharePoint" using MSAL.
Note: I'm using a certificate here, but you could be using a secret instead
var cac = new ClientAssertionCertificate(ApplicationId, CertificateProvider.AppCertificate);
var ua = new UserAssertion(apiAccessToken);
authenticationResult = await authContext.AcquireTokenAsync(resource, cac, ua);
I'm not providing the code on how to intercept the token/get it here because your question is unclear on your current authentication and authorization configuration as well as what MVC "flavor" are you using (asp.net core + middlewares, classic + owin, something else?). I suggest you start another question with more details on that specific point.

Authentication in Web API

I know this is very common question. But I really do not know how to integrate it.
I want to add authentication to my web api services. Right now I have created one console application to call service's method.
I have gone through this blog. I just want to implement authentication filter as mentioned in this article.
I want to know how can I pass credentials along with HTTPClient from my console application, fetch those things to web API and authenticate them.
I have created authentication filter but it does not invoke AuthenticateAsync method of authentication filter.
To pass http client I have done this:
public void GetData()
{
HttpClient cons = new HttpClient();
cons.BaseAddress = new Uri("http://localhost:50524/");
cons.DefaultRequestHeaders.Accept.Clear();
cons.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var data = Encoding.ASCII.GetBytes("Ankita:ankita123");
var header = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(data));
cons.DefaultRequestHeaders.Authorization = header;
//MyAPIPost(cons).Wait();
MyAPIGet(cons).Wait();
}
Teaching you how to implement authentication in Web API will take a lot of time. You better stick to online tutorials.
The blog you've read tackles about different authentication for ASP.NET. Since you've tagged your question as ASP.NET Web API 2, I would suggest using a token-based authentication utilizing OWIN middleware. Check this out. The guide uses a console application for checking the requests to the web API.
The gist of it is...
Client > Token Provider (Generate token for valid user) > Web API > Check if Token is Valid (Existing and not expired) > Authenticate!
Considering you are trying to access the API with an HttpClient, you can pass it an instance of HttpClientHandler when creating it, which allows you to set the credentials that will be used when it performs requests:
new HttpClient(new HttpClientHandler { Credentials = new NetworkCredential(userName, password) })
Hope it helps!
I have successfully implemented authentication using this article. In that filter attribute is implemented.

Token based authentication from class library to mvc5 application

I have mvc5 application with custom login implementation. Once i got the credentials from user am making post and getting the token to validate the user. Owin Token implementation in separate class library project.
[HttpPost]
[AllowAnonymous]
public ActionResult Login(UserLoginViewModel model)
{
string baseAddress = "http://localhost:4312";
Token token = new Token();
using (var client = new HttpClient())
{
var form = new Dictionary<string, string>
{
{"grant_type", "password"},
{"username", "jignesh"},
{"password", "user123456"},
};
var tokenResponse = client.PostAsync(baseAddress + "/otoken", new FormUrlEncodedContent(form)).Result;
//var token = tokenResponse.Content.ReadAsStringAsync().Result;
token = tokenResponse.Content.ReadAsAsync<Token>(new[] { new JsonMediaTypeFormatter() }).Result;
........
}
}
I am not sure how to make call /trigger the token implementation in class library project from mvc application. because class library project is not executable project. is it possible way of implementing token based implementation in separate class lib and make use of that implementation in different application (mvc and webapi).
my layer
UI(MVC) -> Authentication project (Owin class libarary) -> entity framework
any ideas?
Yes you can, but you need to expose your application login through an API of some sort.
For example you can create a token server which is responsible for authentication of both your API and you MVC project - an external provider - like Google or Facebook for example.
This is also the best way to share the same token between your two applications (MVC and API).
Check this article, it's extremely clear.
Hope it helps :)
For token based authentication, you need to use configure your mvc application or webapi to issue token. class library cannot issue token.The primary reason is that, you need to call the url configured to fetch the token eg.http://localhost:8080/api/gettoken.
So, either use webapi to issue token or mvc app to issue token.

How to use OAuth 2 - OAuth 2 C# example

I have to figure out how to use OAuth 2 in order to use Deviantart api.
I got the client_id and client_secret part
Here the information they give
Endpoints
The only information you need to authenticate with us using OAuth 2.0 are the client_id and client_secret values for your app, as well as the endpoint shown below.
OAuth 2.0 draft 10:
https://www.deviantart.com/oauth2/draft10/authorize
https://www.deviantart.com/oauth2/draft10/token
OAuth 2.0 draft 15:
https://www.deviantart.com/oauth2/draft15/authorize
https://www.deviantart.com/oauth2/draft15/token
Placebo call
The first API call relying on OAuth 2.0 authentication is the placebo call.
It's useful for checking that an access token is still valid before making a real API call that might be long, like a file upload.
You call it with one of the following endpoints (an access token must be provided):
https://www.deviantart.com/api/draft10/placebo
https://www.deviantart.com/api/draft15/placebo
You need to use the endpoint that corresponds to the OAuth 2.0 draft you've obtained your token with.
It always returns the following JSON: {status: "success"}
I have searched the web and found this awesome library.
DotNetOpenAuth v4.0.1
http://www.dotnetopenauth.net/
Added it as reference but have no idea what to do next. Even a very small example would be really useful about how to use OAuth 2
using DotNetOpenAuth;
using DotNetOpenAuth.OAuth2;
Here the page where deviantart gives the information
http://www.deviantart.com/developers/oauth2
Ok here what i got so far but not working
public static WebServerClient CreateClient() {
var desc = GetAuthServerDescription();
var client = new WebServerClient(desc, clientIdentifier: "myid");
client.ClientCredentialApplicator = ClientCredentialApplicator.PostParameter("mysecret");
return client;
}
public static AuthorizationServerDescription GetAuthServerDescription() {
var authServerDescription = new AuthorizationServerDescription();
authServerDescription.AuthorizationEndpoint = new Uri(#"https://www.deviantart.com/oauth2/draft15/authorize");
authServerDescription.TokenEndpoint = new Uri(#"https://www.deviantart.com/oauth2/draft15/token");
authServerDescription.ProtocolVersion = ProtocolVersion.V20;
return authServerDescription;
}
Easiest thing to do now is get Visual Studio 2013 and create a new ASP.NET Web Application choosing "Individual User Accounts" as your authentication type. There's a working OAuth 2 implementation out of the box in there (configured at App_Start\Startup.Auth.cs) which you can slice out and then adapt to your needs.
In the ASP.NET Core Security Project there is now a ready to use solution:
Nuget Package: AspNet.Security.OAuth.DeviantArt

YouTube and OAuth 2.0 in .Net

Does anyone know how to properly authenticate an account using OAuth 2.0 and then use that auth token to access the user's YouTube account?
At the end of http://code.google.com/apis/youtube/2.0/developers_guide_protocol_oauth2.html it says
The Google Data client libraries that support the YouTube Data API do not currently support OAuth 2.0. However, a newer set of Google API client libraries, which do not support the YouTube Data API, do provide OAuth 2.0 support.
As such, it is an option to use these newer libraries, which are listed below, for their OAuth 2.0 capabilities and then force the Google Data client library to use the OAuth 2.0 token(s) that you have obtained.
I have my application successfully running through the OAuth 2.0 process and I'm getting an access token which should be able to access youtube, but I don't know how to "force the Google Data client library to use the OAuth 2.0 token(s)".
Any example code would be great.
Liron
PS This is for a desktop application.
Do do this you need to have both an account set up on google data apps (https://code.google.com/apis/console) and with the youtube apis (http://code.google.com/apis/youtube/dashboard).
You then have to authenticate the google data api using their oauth mechanisms. Something like the following - this is gutted from some code we have.
{code}
//Create Client
m_Client = new NativeApplicationClient(GoogleAuthenticationServer.Description, m_ClientID, m_ClientSecret);
//Add Youtube scope to requested scopes
m_Scopes.Add("https://gdata.youtube.com");
//Get Authentication URL
authStateInitial = new AuthorizationState(m_Scopes);
authStateInitial.Callback = new Uri(NativeApplicationClient.OutOfBandCallbackUrl);
Uri authUri = m_Client.RequestUserAuthorization(authStateInitial);
//Navigate to URL, authenticate get accessToken
string accessToken = ...;
string[] tokens = accessToken.Split(new char[] { '&' });
if(tokens.Length == 2)
{
authStateFinal = new AuthorizationState(m_Scopes);
authStateFinal.AccessToken = tokens[0];
authStateFinal.RefreshToken = tokens[1];
if(m_AuthStateInitial == null)
{
m_Client.RefreshToken(m_AuthStateFinal);
}
OAuth2Authenticator<NativeApplicationClient> authenticator = new OAuth2Authenticator<NativeApplicationClient>(m_Client, GetState); //GetState returns authStateInitial
authenticator.LoadAccessToken();
}
Then you have to authenticate the youtube apis by using both the access token you got from above and the youtube Developer Key.
{code}
GAuthSubRequestFactory m_Authenticator = new GAuthSubRequestFactory(ServiceNames.YouTube, "Product Name");
m_Authenticator.Token = AccessToken;
YouTubeService m_YouTubeService = new YouTubeService(m_Authenticator.ApplicationName, m_DeveloperKey);
m_YouTubeService.RequestFactory = m_Authenticator;
Hope this helps someone.

Categories

Resources