I'm trying to implement Microsoft authentication for a mobile app that connect to a Azure mobile back end service, I created a MobileServiceUser user; then I tried to use the method LoginAsync and already choosed the Micorosft Provider, the question is from where can I get the token value
user = await App.Client.LoginAsync( MobileServiceAuthenticationProvider.MicrosoftAccount,token<-????);
I try to get info about that
Thank you
Not sure if you ever got an answer to this question but you get the token from a client managed authentication. You independently use each of the provider API (Facebook, Google, Microsoft, LinkedIn, etc.) and then when you authenticate it using OAuth, you will get a token back. Then you pass the token into the LoginAsync call.
Here's some sample code:
auth = new OAuth2Authenticator(
clientId: "MyAppId", // For Facebook login, for configure refer http://www.c-sharpcorner.com/article/register-identity-provider-for-new-oauth-application/
scope: "",
authorizeUrl: new Uri("https://m.facebook.com/dialog/oauth/"), // These values do not need changing
redirectUrl: new Uri("http://www.facebook.com/connect/login_success.html")// These values do not need changing
// After facebook,google and all identity provider login completed
auth.Completed += Auth_Completed;
private async void Auth_Completed(object sender, Xamarin.Auth.AuthenticatorCompletedEventArgs e)
{
if (e.IsAuthenticated)
{
string token = e.Account.Properties["access_token"];
}
}
You then pass this token in the LoginAsync method.
Related
I am using the Microsoft graph Javascript client library to get a refresh token for a user. I created an app that connects doctors and patients. I want to create and delete events on the doctors' calendars. I first need their authorization to access their outlook account. Unfortunately, when I make the api call to get the refresh token, I get back an access token and an id token but no refresh token. Can someone please help?
Here's my code
const msalConfig = {
auth: {
clientId: process.env.OUTLOOK_OAUTH_CLIENT_ID,
authority: process.env.OUTLOOK_OAUTH_AUTHORITY,
clientSecret: process.env.OUTLOOK_OAUTH_CLIENT_SECRET
},
system: {
loggerOptions: {
loggerCallback(loglevel, message, containsPii) {
console.log(message);
},
piiLoggingEnabled: false,
logLevel: msal.LogLevel.Verbose,
}
}
};
// Create msal application object
const ouathClient = new msal.ConfidentialClientApplication(msalConfig);
const response = await ouathClient.acquireTokenByCode(tokenRequest);
I am using node js.
This method can also be used to get the refresh token, Please refer this Microsoft documentation.To get refresh token
Client Credentials flow does not support user context thus no refresh token is supported in this case.
If you are using MSAL depending on whether you are using Public client (Mobile, Desktop or Single Page apps) where users sign-in to your app then you may need a refresh token and you should be using flows listed here
If you are using a private client like a serveside daemon then you dont need a refresh token.
I am using Azure's MobileServiceClient sdk to authenticate with my server. With the upgrades to 4.x version I am also using Xamarin.Auth to authenticate users with Google and Facebook. When the response comes back from Google I am getting a refresh token. I then call the mobile service sdk like so:
var accessToken = account.Properties["access_token"];
var idToken = account.Properties["id_token"];
var zumoPayload = new JObject();
zumoPayload["access_token"] = accessToken;
zumoPayload["id_token"] = idToken;
var user = await client.LoginAsync(MobileServiceAuthenticationProvider.Google, zumoPayload, );
This work perfectly fine. What does not work is the call to client.RefreshUserAsync(). That is throwing a 403 every time saying the refresh token is either expired or no longer valid even when I call that method right after I logged in. I do not see many examples at all using the MobileServiceClient 4.x sdk and none of them have examples of how to use the refresh token.
I have tried sending that upin the zumo payload as well but it does not work. I have tried invalidating my user on Google (I am getting the refresh token back), tried logging in through the browser and going to auth/me but the refresh token is not there. Any help would be great!
AFAIK, you could leverage the Xamarin.Auth SDK to independently contact the identity provider and retrieve the access token on your mobile client side, then you need to login with your backend (azure mobile app) along with the token for retrieving the authenticationToken, then you could leverage the authenticationToken to access the resources under your mobile app.
Since you are using Client-managed authentication, for refreshing the new access_token, you need to do it on your mobile client side. I checked Xamarin.Auth and found that there is no method for requesting an access token. You need to refer to Refreshing an access token and implement this feature by yourself. I followed OAuth2Authenticator.cs and created a extension method for requesting an access token as follows:
public static class OAuth2AuthenticatorExtensions
{
public static Task RefreshAccessTokenAsync(this OAuth2Authenticator authenticator, Account account)
{
var dics = new Dictionary<string, string>
{
{"refresh_token",account.Properties["refresh_token"]},
{"client_id", authenticator.ClientId},
{"grant_type", "refresh_token"}
};
if (!string.IsNullOrEmpty(authenticator.ClientSecret))
{
dics["client_secret"] = authenticator.ClientSecret;
}
return authenticator.RequestAccessTokenAsync(dics).ContinueWith(task =>
{
if (task.IsFaulted)
{
//todo:
}
else
{
authenticator.OnRetrievedAccountProperties(task.Result);
}
});
}
}
Additionally, if you leverage Server-managed authentication with Microsoft.Azure.Mobile.Client, then you could leverage RefreshUserAsync for refreshing the access token, at this point your previous access_token, clientId are stored on azure, and your mobile app backend would directly communicate with Google's OAuth 2.0 endpoint and request a new access token for you and update the token store on Azure. For more details about token store within App Service, you could follow here.
I need my app to support custom authentication against our private database, and following the advices on Adrian Hall book here https://adrianhall.github.io/develop-mobile-apps-with-csharp-and-azure/chapter2/custom/ I got no problem authenticating my users. The problem comes when I need to refresh the access token.
As I'm forced to stay with custom auth, I have the following questions:
1) Should I call MobileServicesClient.RefreshUserAsync(), and if so, what kind of endpoint should I implement on the server? Will it reissue another token every time, invalidating the old? When should be the refresh call be made?
2) I've read about using a never-expiring refresh token, but I can't really find a sample implementation, or instructions on how to implement it in a custom auth scenario, could someone point me to the right direction?
Many thanks in advance
Should I call MobileServicesClient.RefreshUserAsync(), and if so, what kind of endpoint should I implement on the server? Will it reissue another token every time, invalidating the old? When should be the refresh call be made?
I have checked the method RefreshUserAsync from Microsoft.WindowsAzure.Mobile.dll which would send a get request against the /.auth/refresh endpoint for refreshing the access token with the provider for your logged in user. Since you are using custom authentication, you could not use this method for refreshing the authenticationToken.
I've read about using a never-expiring refresh token, but I can't really find a sample implementation, or instructions on how to implement it in a custom auth scenario, could someone point me to the right direction?
When using the CreateToken method from AppServiceLoginHandler, you could specify the lifetime as null, then you would retrieve a never-expiring authenticationToken as follows:
JwtSecurityToken token = AppServiceLoginHandler.CreateToken(claims, signingKey, audience, issuer,null);
Additionally, you could try to build your endpoint for creating new token based on the old valid token as follows:
[Route(".auth/login/customRefreshToken")]
public IHttpActionResult RefreshToken([FromBody] RefreshTokenInput body)
{
string tokenString = body.AuthenticationToken;
try
{
var jwtSecurityToken = new JwtSecurityToken(tokenString);
JwtSecurityToken token = AppServiceLoginHandler.CreateToken(jwtSecurityToken.Claims, signingKey, audience, issuer, TimeSpan.FromDays(30));
return Ok(new LoginResult()
{
AuthenticationToken = token.RawData
});
}
catch (Exception e)
{
return BadRequest("$Error = {e.Message}, StackTrace = {e.StackTrace}");
}
}
Note: For your mobile client, you could use MobileServiceClient.InvokeApiAsync for retrieving the new token, then parse the authenticationToken and update it to MobileServiceClient.CurrentUser.MobileServiceAuthenticationToken.
RESULT
I have browsed all the tutorials regarding using Oauth to protect WebAPI in Azure active directory online. But unfortunately, none of them can work.
I am using VS 2017 and my project is .net core.
So far what I have tried is:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
ervices.AddAuthentication(); // -----------> newly added
}
In "Configure", I added:
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
Authority = String.Format(Configuration["AzureAd:AadInstance"], Configuration["AzureAD:Tenant"]),
Audience = Configuration["AzureAd:Audience"],
});
Here is my config:
"AzureAd": {
"AadInstance": "https://login.microsoftonline.com/{0}",
"Tenant": "tenantname.onmicrosoft.com",
"Audience": "https://tenantname.onmicrosoft.com/webapiservice"
}
I have registered this "webapiservice" (link is: http://webapiservice.azurewebsites.net) on my AAD.
Also, to access this web api service, I created a webapi client "webapiclient" which is also a web api and also registered it on my AAD and requested permission to access "webapiservice". The webapi client link is: http://webapiclient.azurewebsites.net
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://webapiservice.azurewebsites.net/");
//is this uri correct? should it be the link of webapi service or the one of webapi client?
HttpResponseMessage response = client.GetAsync("api/values").Result;
if (response.IsSuccessStatusCode)
{
var result = response.Content.ReadAsAsync<IEnumerable<string>>().Result;
return result;
}
else
{
return new string[] { "Something wrong" };
}
So theoretically, I should receive the correct results from webapiservice. but I always received "Something wrong".
Am I missing anything here?
You need an access token from Azure AD.
There are plenty of good example apps on GitHub, here is one for a Daemon App: https://github.com/Azure-Samples/active-directory-dotnet-daemon/blob/master/TodoListDaemon/Program.cs#L96
AuthenticationResult authResult = await authContext.AcquireTokenAsync(todoListResourceId, clientCredential);
This app fetches an access token with its client id and client secret for an API. You can follow a similar approach in your case. You can just replace todoListResourceId with "https://graph.windows.net/" for Azure AD Graph API, or "https://graph.microsoft.com/" for Microsoft Graph API, for example. That is the identifier for the API that you want a token for.
This is the way it works in AAD. You want access to an API, you ask for that access from AAD. In a successful response you will get back an access token, that you must attach to the HTTP call as a header:
Authorization: Bearer accesstokengoeshere......
Now if you are building a web application, you may instead want to do it a bit differently, as you are now accessing the API as the client app, not the user. If you want to make a delegated call, then you will need to use e.g. the Authorization Code flow, where you show the user a browser, redirect them to the right address, and they get sent back to your app for login.
To call web api protected by azure ad , you should pass this obtained access token in the authorization header using a bearer scheme :
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
I need to log on through OAuth 2 how can I do that without using WebView in Android?
Thanks.
In the latest v4.5.7 of ServiceStack you'll be able to login into Twitter, Facebook or Github using their SDKs and previous saved access tokens.
Authentication via AccessToken is also made available to OAuth2 providers in the same way where you can authenticate directly by adding the AccessToken to the Authenticate Request DTO, e.g:
var request = new Authenticate
{
provider = "GoogleOAuth",
AccessToken = GoogleOAuthAccessToken,
};
var response = client.Post(request);
response.PrintDump();
Although you will first need to retrieve the AccessToken which typically requires opening a WebView to capture Users consent.
For other OAuth2 providers other than Google Auth you will need to provide an implementation of VerifyAccessToken that returns a boolean that determines whether the AccessToken is valid or not, e.g:
new MyOAuth2Provider {
VerifyAccessToken = accessToken => MyValidate(ConsumerKey,accessToken),
}
This is different for each OAuth provider where some don't provide an API that lets you determine whether the AccessToken is valid with your App or not.