I have been researching on Azure Mobile app service and I am freaking out because I think I had it all wrong.
I have one Azure Mobile App service and issue is I am trying to implement "custom" authentication for it (the reason for custom authentication is that I have a web app and web API which uses the same database and send REST requests to mobile service app to update database and both of them use asp.net identity)
But before I implement custom authentication in mobile app service, I just can't get my head around that even though the authentication is custom and I am manually checking users, once the token is generated and user is authorised, the user has access to all the data in the table. So if I am user1 and login, mobile app service will authenticate me and once I have the auth token I can simply do REST request to do anything to all the data.
How do I restrict that the generated token is only used to CRID only that user's data where in my table I have UserId column also.
I am very confused. any help will be appreciated.
How do I restrict that the generated token is only used to CRID only that user's data where in my table I have UserId column also.
Per my understanding, you could follow Per-User Data and leverage the following property to retrieve the current UserID from the incoming Easy Auth token:
public string UserId
{
get
{
var principal = this.User as ClaimsPrincipal;
return principal.FindFirst(ClaimTypes.NameIdentifier).Value;
}
}
For the complete tutorial about handling CURD operations which need to be limited to the user who generates the token, you could follow Data Projection and Queries.
Related
So, we have a web API that is working great with Azure AD and bearer token authentication.
In my ConfigureServices I have this:
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.Audience = Configuration["Azure:AD:ClientId"];
options.Authority = $"{Configuration["Azure:AD:Instance"]}{Configuration["Azure:AD:TenantId"]}";
});
We have the Client ID setup to be a Web API app in Azure AD.
Now we are making a native application and we need to also have a native app client ID in Azure AD. My API is looking for the Web API client... how do I also allow a bearer token that was created with the native app?
It looks like your app is looking in the aud claim // audience field to verify the client ID. This field represents the app ID of who the token is intended for. This means if you register a new Native app registration, the tokens issued to that app for this API will have the same aud claim.
In v1.0 format tokens, they also have a appid claim which represents the App ID of the client application (your web app or native app for example) if your API is trying to verify the token was issued to one of your clients.
In v2.0 tokens, this claims is azp.
Do note,in the case of the native app, it's considered a public client meaning the exact identity of the client is not guaranteed, hence the name public client. Your web app is a confidential client so there is a stronger guarantee the appid claim will be the app it claims to be.
In both formats there's another claim (appidacr and azpacr, respectively) that represents the client type. You can have high confidence if the value is 1or 2, but should be careful in the case it's 0.
Reference for tokens
Ok! So... we got this working.
For posterity here is what we ended up doing.
We found this fine link: https://github.com/Azure-Samples/active-directory-dotnet-webapi-manual-jwt-validation
In step 2 of this, it tells you to change the Web API URI - We ended up not needing to do this...
What was critical thought was to add the permission from the Native app to the Web API (the second set of steps in #2). Basically, as I understand this, it allows the native app and web api app to work together and share a client id when it come to an authentication perspective.
We also found that editing the manifest on the Native app and make "oauth2AllowImplicitFlow" = true was also important.
Hope this helps someone.
I am trying to call a CDN Purge's Azure REST API url from Microsoft Flow.
I found HTTP - HTTP as the best action to use as Azure with HTTP sounds to be specialized on accessing resources not on (just) calling.
I created a Web app / API application in Azure Active Directory for this purpose.
The API calls need to be authenticated so I chose Active Directory OAuth.
I filled in the Tenant id into Tenant, chose Secret as Credential type and put a application's password (Keys) into the Secret field.
However, I am lost what to put into Audience and Client ID field.
I tried to search docs but did not find any relevant results. I presume one of those should be the App Id.
What to put into the Audience and Client ID fields and how to find the values?
Is there anything else required to do to make this working (like setting a permission to allow purging the CDN, updating manifests, assigning roles)?
PS: I am getting BadRequest. Http request failed as there is an error getting AD OAuth token: 'AADSTS50105: Application '<appId>' is not assigned to a role for the application '<appIdUri>'. in my most recent attempt.
The audience is the value of App ID URI that you registered (homepage below image)
The Client Id is nothing but the Application ID
I'm trying to access my Table in Azure App Service when user has an authentication. I use server side auth with Facebook. Once the user authenticated, the token was saved into my Setting class, as this post do. Whenever the user come back to App, I want user use their cached token to connect to the table in Azure App Service. How is the best approach to achieve this?
1) Implement client-side authentication with the Facebook SDK. The token provides by Facebook is long-lived (something like 60 days), so you can store it in a private store. I cover private stores in chapter 2 of the ZUMO Book at http://aka.ms/zumobook
2) When you open the app, use the stored token to get a ZUMO token. This is short lived - 1 hour. You can store this too, but it's a waste of time since you can use the unexpired Facebook token to get a new one.
3) Implement an Authentication Refresh process via a delegating handler - I describe that in the ZUMO book too.
You still need to configure Azure App Service Authentication to understand and validate your facebook token (also covered in the book!)
In Azure Mobile App server, with client initiated authentication on device, we get userid (aka sid), now when I want to create a user record using mobile app service the sid is not available for the first time. Only information I have at the backend is, by reading claims with "NameIdentifier".
string uniqueId = creds.UserClaims.FirstOrDefault(c => c.Type.Equals(ClaimTypes.NameIdentifier))?.Value;
SO I am curious whether is this the right way to get user id?
Yes, this is the right way to get the user claims. For more information, check out Chapter 2 of my book: https://adrianhall.github.io/develop-mobile-apps-with-csharp-and-azure/chapter2/authorization/
I have created a Xamarin.Forms project and a Table API project. Both have been created through the QuickStart menu in Azure Portal.
I have configured an Azure AD in my portal and I can successfully retrieve a token from the AD through my XForms app. But when I try to login to the Table API using the LoginAsync method from the MobileServiceClient, I receive a "You do not have permission to view til directory or page."
I have been looking through the following guides but with no luck.
How to configure your App Service application to use Azure Active Directory login
Add authentication to your Xamarin.Forms app
How to: Work with authentication
I have also look at the following question but didn't find a solution.
Cordova AAD server flow authentication hangs on Android and iOS
I Am thinking that I might be missing some specific authentication on the Table API project?
Here is my code and setups:
PCL PROJECT IN XFORMS
var ar = await authContext.AcquireTokenAsync(Constants.GraphResourceUri, Constants.ClientId, userCredintials);
JObject payload = new JObject();
payload["access_token"] = ar.AccessToken;
var client = new MobileServiceClient(Constants.ApplicationUrl);
var user = await client.LoginAsync(MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, payload);
The Constants.ClientID is the ClientId of the Native Client app and not the webserver. If I switch it around I get a 404.
EXAMPLE OF CONTROLLER FROM TABLE API PROJECT
[Authorize]
public class StatisticController : ApiController
TABLE API StartUp.cs CONFIGURATION
public void Configuration(IAppBuilder app)
{
app.UseAppServiceAuthentication(new AppServiceAuthenticationOptions());
ConfigureMobileApp(app);
}
MOBILE SERVICE AUTH SETUP
SINGLE SING-ON AD SETTINGS
NATIVE CLIENT APP SETTINGS
EDIT
I can duplicate the error through PostMan with the following setup:
I tried to include a "X-ZUMO-AUTH" header with the value of the access_token but with the same result. Still no permission. I also tried to exclude every header in the POST request but with no changes. Does this mean that POST requests from my mobile app or Postmand is not allowed?
If I manually browse to mysite.azurewebsites.net/.auth/login/aad in a browser, then I can log in with the users from my AD. So it seems that the AD is communicating correctly with the service and vise versa.
FIXED IT
Great thanks to mattchenderson! As he suggests I should change the constant GraphResourceUri to the client id of my service instead of the normal graph api. Along with adding a single instance of the client I can now successfully log in to my service.
POST requests are allowed, and I use Postman all the time for testing.
The most common cause of an issue like this is an audience validation issue. The audience is a property of the AAD token which says for what resource is this token valid. Given the code above, I would expect the audience to be equal to Constants.GraphResourceUri. My guess is that this is actually the graph API, and not your application, and that would cause a validation failure, although I would expect it to happen when you call LoginAsync(). I would suggest trying the web application client ID instead (that's the Client ID from the "MOBILE SERVICE AUTH SETUP" screenshot).
For an easier time debugging, you can take your AAD token to something like http://jwt.io, and that will help you see the token properties. "aud" is expected to the same as the client ID of the application as registered in the portal, and you want the issuer fields to match up as well. Make sure the token is not expired either.
When using the token to access protected APIs, there are two ways to provide it:
Use the token returned as part of LoginAsync() in the X-ZUMO-AUTH header of your request. This will automatically be done by the SDK for table operations using the same MobileServiceClient.
Use the AAD token directly according to the bearer token spec. That is, include it in the Authorization header, with the value "Bearer ", replacing token with your value.
Also, I see in your code that you are creating a new MobileServiceClient for the login operation. This is something we generally discourage, as the login information is attached to the MobileServiceClient object. If you lose a reference to that, you lose the login information (and a few other settings), and they won't be applied to your table operations. The recommendation is to use a single instance that is referenced elsewhere - for example, in Xamarin, a static variable within your shared code.