Can Azure Traffic Manager be used with Mobile Apps specially with social login? I have configured a traffic manager and two app services (say, mobileapp1 and mobileapp2) to work with it.They seem to work pretty nice with postman and the response and everything is working. Now, I have declared traffic manager's URL as client in xamarin client app and the app throws exception when I am logging in into azure. After logging in facebook, when I am passing the token to server using this line
var user = await client.LoginAsync(MobileServiceAuthenticationProvider.Facebook, token);
it throws an exception at this line saying invalid operation.
In continuation to this doubt.. I have two mobile apps connected with one traffic manager. Both of them have facebook login configured. So, is it supposed to work? What happens if, when the user is registering he/she is redirected to mobileapp1 and azure authentication is done there while in some subsequent attempts user is redirected to mobileapp2. Does the identity database of mobileapp2 know about the user? This is when I am using the authentication service that comes with mobile app and not B2C.
Based on your code, you are using Client-managed authentication with Azure Mobile Apps. For App Service Authentication / Authorization, such as mobile client type, a JSON web token (JWT) would be issued to the client and the it would be presented in the x-zumo-auth header when sending request to mobile backend. For more details, you could refer to How authentication works in App Service. Here is a JWT token when using Azure traffic manager with Mobile App, we could use jwt.io to decode the token:
For the JWT token, it would use the WEBSITE_AUTH_SIGNING_KEY environment variable to sign audience, issuer, Claims. For more details, you could refer to here about how to use custom authentication for your application.
Each Mobile App has the different WEBSITE_AUTH_SIGNING_KEY, you could use kudu and click Environment to find the it. Moreover, I tried to update my two mobile apps to use the same sign key, but failed for no permission.
Your LoginAsync would send the following request:
POST https://<yourname>.trafficmanager.net/.auth/login/facebook
Body {"access_token":"<access_token_from_facebook>"}
You could use fiddler to capture the network trace.
Can Azure Traffic Manager be used with Mobile Apps specially with social login?
For custom authentication, you could configure the sign key in your web.config file. For social login and use the authentication provided by azure, you could no share the sign key between different mobile apps. Moreover, if you set Routing method to Geographic and your mobile apps are in different Geographic locations, I assume that your scenario may work as expected.
UPDATE1:
After some trials, I found you could specific the WEBSITE_AUTH_SIGNING_KEY setting under the "SETTING > Application settings" blade of your mobile app to override the WEBSITE_AUTH_SIGNING_KEY environment variable as follows:
Note: The signing key needs to be a SHA-256 hashed string, you could sync the key between your two mobile apps or generate your custom key. After configure the setting, you could leverage kudu to check the newest WEBSITE_AUTH_SIGNING_KEY.
UPDATE2:
my problem is figuring out how to use social auth with two different mobile apps where redirection by traffic manager is happening on the basis of performance
As the official documentation mentions about the traffic routing method Performance as follows:
Performance: Select Performance when you have endpoints in different geographic locations and you want end users to use the "closest" endpoint in terms of the lowest network latency.
I did some test, you could refer to it. Here is the Endpoints under my Traffic Manager profile:
Note: My two mobile apps have configured the same Client Id for my MSA authentication and set the same WEBSITE_AUTH_SIGNING_KEY value under "SETTINGS > Application settings" for encoding / decoding the token.
For my /api/values API endpoint, I just return the WEBSITE_HOSTNAME environment variable as follows:
return Request.CreateResponse(new { WEBSITE_HOSTNAME =Environment.GetEnvironmentVariable("WEBSITE_HOSTNAME") });
For the Performance routing method, all my requests would be routed to bruce-mobile02.azurewebsites.net:
For the Weighted routing method, I configured the same WEIGHT for my two endpoints. Per my test, the requests with the same AuthenticationToken that attached as the x-zumo-auth header value for authorization would be routed to my two endpoints as follows:
Related
I have a single ASP.NET MVC app - website and API controllers. I'd like to use Azure API Management to manage these APIs but retain the same URL so that it is seamless for our consumers. We have a custom domain setup on the app service for this web app that is currently used to serve up both the site and APIs(e.g. Website: xyz.com, APIs: xyz.com/api1, xyz.com/api2, etc.). Also we use AAD for auth. and have the redirect URI setup to the custom domain(xyz.com). Everything works great at present.
The issue arises after we configure API Management to expose our APIs and potentially use it as a passthrough. In order to ensure that the URLs remain the same after API Management is introduced we set the custom domain to be on the API Management instance itself and removed it from the app. service. This is how our current setup looks -->
User hits xyz.com and the request proceeds as follows -> Traffic Manager -> APIM(xyz.com) -> App Service(xxx.azurewebsites.net)
After that last point above, AAD auth. should kick in and once it has the access token after successful auth. it should redirect the user and the page should load. But it doesn't. Instead we get a blank page and if we refresh it, then and only then does it proceed to auth. and load the page.
We have tried setting our redirect URI to both the custom domain(xyz.com) as well as the base app service name that Azure generated(xxx.azurewebsites.net).
Directly hitting the API urls specifically(e.g. xyz.com/api1) works fine. It goes through APIM and responds as expected. The only problem is that the website doesn't load as outlined above.
The moment we take APIM out of the equation, and set the custom domain back on the app service again, everything works as expected.
I'm trying to figure out if we've misconfigured our assets for this scenario somehow or if APIM doesn't support pass through for the website in this manner. Any thoughts/suggestions here would be much appreciated!
Wow, that was a lot of text.
Ok, let's see:
Visitors -> Traffic manager -> APIM -> backend (your website) - ok got it.
this is like a common way of using APIM, and it should work. However, maybe your policies are not set up correctly?
Have you built your product/API/Operations? Do you see requests coming from APIM hitting your site? What responses are you getting?
Now, of course, you will need to define and set up APIM (products, APIs, and every operation) to pass it throw to your backend. This means if you (as a visitor) need to list all products, you would need to go through the APIM operation (sed GetProducts ). Your request will be passed through the Inbound policy(adjust and build the request if needed), pass it to the backend( to your website with custom APIs), and the response will be sent back from the backend back to the visitor.
Now to this: to protect your Web API Backend in APIM, you could use OAuth 2.0 authorization with Azure AD:
big picture overview:
Register an application (for your backend) in Azure AD to represent the API
Register another Application (the client) in Azure AD to represent a client app that will call your API
And I guess this is the one for you grant permissions to allow the client app to call the backend app
And, of course, add the validate-jwt policy to validate the OAuth token for every incoming request
Read om on this here https://learn.microsoft.com/en-us/azure/api-management/api-management-howto-protect-backend-with-aad
I have a SpringBoot Micro-Service based backend API that uses Zuul as a gateway proxy between a JavaFX Desktop Application. Right now there is no security in place, but I am looking to secure the backend with Spring Security, however, every tutorial I seem to run across seems to be based on web-apps and I haven't seen anything for my particular use case. I don't know much about spring security but would like to know if I can accomplish my goals with it, and if so, what modules or examples should I be looking for.
Goals:
Provide a way for my API to know that requests are coming from the desktop app itself, I think the technical term for this is assigning the desktop app a client id and then having the Zuul Server validate that the client id is that off the desktop app before accepting the request. This should be the case for all requests
Only allow API traffic through the Zuul Proxy, all of the downstream requests to the micro-services behind the Zuul gateway should only be accepted if they are coming from the Zuul Server itself.
Allow requests for logging in and registering as a new user without any type of security other than the desktop client id discussed in 1.
When a user provides a successful username/password on login, they are returned a JWT which is then stored in the JavaFX application and used for all of the other requests to the backend.
Configure the token to expire after a specific time frame, say like 90 minutes and provide a method for automatically refreshing an expired token as long as the users account is still valid. For this, I don't want the user to have to re-login, I just want it to check behind the scenes to make sure their account is still valid and then issue a new token if needed.
Have user based roles so certain features, methods, endpoints, etc. are only accessible to users with the valid role. Within the GUI these features will be hidden or disabled, but I would still like a layer of security on the server side to protect against unwanted access in case someone was able to modify the app.
I am just writing down answers to each of your goals :
Passing the client Id in every request from desktop application doesnt make sense, instead you client Id and secret can be passed during authenticaiton call, Like we have in Oauth 2.0 framework. Rest https calls should be made from client, So to avoid tampering of request, You can also go for mutual SSL between your client application and Zuul API gateway, It assures that call is coming from Desktop client only.
Yes, Zuul api gateway should be single entry point to your application, Your internal microservices should not be exposed to public.
For user registeration, Client authentication can be achieved using client Id and secret
Correct, You can also create http only cookie at backend, which will include your jwt token only.
Token refresh can be achieved at zuul api gateway, if session is active, make call to refresh token endpoint to get new access token.
On server side, At zuul proxy you can validate the incoming bearer token expiry along with signature validation, with generic claims too. Now at microservices level spring security can be used for role based access control for particular methods.
I'm rather new to AWS Cognito and AWS Lambda. So far I've played around with Serverless and deployed my REST API via AWS Lambda. However, I would like to make my API available for several external parties. As this is service to service, there is no end user directly calling my API. I make the API available for other businesses which use it in their applications. All functionalities exposed via the API are rather simple, meaning they are not invoking any other AWS services like a Dynamo DB etc.
I have several questions, some are rather high-level others are quite specific to the setup of AWS Cognito. I decided to put all in one post as it makes it much more self-contained and easier understandable.
1. Question, Cognito vs API key: What is the advantage of using AWS Cognito vs AWS Lambda in combination with restricting the access via an API key and IP-Whitelisting? Is one much more secure than other?
Let's assume I want to use AWS Cognito. As this is a service to service case, I've read that the standard is to use token endpoints where the grant_type is client_credential. I've found the following on medium. The first few steps consist of
Create a user pool in AWS Cognito.
Create an App client
Add Resource Servers
Enable the client credentials checkbox for Allower OAuth flows
2. Question, App client: Within the added App client I find the corresponding App client id and App client secret. If I expose my API to several different parties, do I need to add for each party another App client? Otherwise they use all the same credentials. Is this the right way to do it?
3. Question, Resource Server: Here I'm completely stuck. What exactly is the meaning for this? At then end, all I want is that my clients can do a post request against my API and access is granted through Cognito. Some clarification what this is for and how this applies in my case would be appreciated. More than happy to share more insights if needed.
The next part is to configure Cognito Authorizer for the API Gateway. This should be fine.
4. Question, client workflow Regarding my clients workflow. Am I correct that this consist of the following steps:
First, I provide to the client his client_id and client_secret.
then the client implements on his side the following workflow:
Whenever he wants to use my API exposed via API Gateway, he first uses his provided client_id and client_secret to retrieve his bearer token.
He uses this bearer token to make a request to API Gateway with the bearer token in the Authorization header.
If access granted, the client retrieves the output of my API.
Is this correct or am I missing anything?
1-Question, Cognito vs API key
Well as you can see here.
Amazon Cognito user pools let you create customizable authentication
and authorization solutions for your REST APIs.
Usage plans let you provide API keys to your customers — and then
track and limit usage of your API stages and methods for each API key
So the purpose is different, the API Key is used basically to count a customer usage while AWS Cognito is there to authenticate/authorize calls to your API.
Let us say, you have a requirement that a trail user can't call your API more than 100 times.
Then using AWS Cognito, you will allow a user to sign up, also you will provide the same user with an API Key, you will identify the source of the calls using Cognito and with each call API Gateway will decrease the limit assigned to user's API Key by 1.
And you will have the following cases:
When token (obtained through login using username and password), and
API Key are valid, then the call will be successful.
When token is wrong/missing, your caller will get 401 status code.
When API Key is wrong/missing, your caller will get 403 status code.
When API Key is correct but limit is exceeded, your caller will get
429 status code.
2. Question, App client:
Well, client id and client secrets are meant to identify a trusted client (app) rather than a user and each app should have its own client id, so if the caller is an application not a user so yes, create a client id for each separate app. Please be aware that client secrets must be kept confidential so if the caller app can't achieve that, such as single-page Javascript apps or native apps, then the secret shouldn't be issued.
3. Question, Resource Server:
It is your API server.
Check this page.
The resource server is the OAuth 2.0 term for your API server. The
resource server handles authenticated requests after the application
has obtained an access token.
Large scale deployments may have more than one resource server.
Google’s services, for example, have dozens of resource servers, such
as the Google Cloud platform, Google Maps, Google Drive, Youtube,
Google+, and many others. Each of these resource servers are
distinctly separate, but they all share the same authorization server.
4. Question, client workflow
Check Client credentials grant in here
The steps for the process are as follows:
An app makes a POST request to https://AUTH_DOMAIN/oauth2/token, and specifies the following parameters:
grant_type – Set to “client_credentials” for this grant type.
client_id – The ID for the desired user pool app client.
scope – A space-separated list of scopes to request for the generated access token.
In order to indicate that the app is authorized to make the request, the Authorization header for this request is set as “Basic
BASE64(CLIENT_ID:CLIENT_SECRET)“, where
BASE64(CLIENT_ID:CLIENT_SECRET) is the base64 representation of the
app client ID and app client secret, concatenated with a colon.
The Amazon Cognito authorization server returns a JSON object with the following keys:
access_token – A valid user pool access token.
expires_in – The length of time (in seconds) that the provided access token is valid for.
token_type – Set to ” Bearer“.
Note that, for this grant type, an ID token and a refresh token aren’t returned.
The app uses the access token to make requests to an associated resource server.
The resource server validates the received token and, if everything checks out, executes the request from the app.
I'm implementing a login auth in my app. For now I'm using an IOC interface which stores my email and password in the device storage (It uses the SharedPreferences in Android and the NSUserDefault class in iOS). When I go to the login screen I must put my email and my password, then I send that data to the server API. The server response is an authentication token, set in the request "Set-Cookie" header. I must set this auth token in every request that I make to the server API. The token expires after certain amount of time, value which comes also in the request header. Basically everything is working OK now, but the issue is that as we know, saving sensitive data like the user email and password in the SharedPreferences/NSUserDefaults is not a good idea. So I was wondering if I can achieve this using Xamarin.Auth. AFAIK Xamarin.Auth only works with identity providers such as Facebook, Google, OAuth, etc.
Is this possible? Can I user Xamarin.Auth to securely save this values?
This should definitely work, take a look at the GitHub repository of Xamarin.Auth.
The "getting started" page states that you can easily extend/customize Xamarin.Auth to work with your endpoint:
Xamarin.Auth includes OAuth 1.0 and OAuth 2.0 authenticators,
providing support for thousands of popular services. For services that
use traditional username/password authentication, you can roll your
own authenticator by deriving from FormAuthenticator.
If you want to authenticate against an ostensibly unsupported service,
fear not – Xamarin.Auth is extensible! It's very easy to create your
own authenticators – just derive from any of the existing
authenticators and start overriding methods.
For a mobile application (Cordova & AngularJS), I use Azure Mobile Services with Web Api.
I am currently experimenting with different OAuth implementations to see which one fits my needs the most.
Tried OAuth from ngCordova, OAuth.io, WAMS server flow and Auth0 with WAMS delegation.
I also came across the option using the "JsonWebToken DelegationHandler for WebAPI". With this approach, I should use the "System.Web.Http.Authorize" attribute. When I debug the JsonWebTokenValidationHandler, everything looks good (IsAuthenticated is true etc.), but at the end, a 401 is being returned.
I guess, WAMS overwrites the user principal. A look at the WAMS log reveals that "The 'Bearer' HTTP authentication scheme is not supported." As soon as there is such an authentication token present it seems to get rejected by Azure Mobile Services.
My first thought was, that I can probably remove a specific message handler but that doesn't seem to be the case. Does anyone have an idea to get this to work with WAMS?
There is another post with a question very similar to this one:
Azure mobile service using aad "The 'Bearer' HTTP authentication scheme is not supported" error
You can pass the application key in the header like so:
HttpClient.DefaultRequestHeaders.Add("X-ZUMO-APPLICATION", "<YOUR APP KEY>";
In that link, Matthew mentions details about how to user authentication and posts links on how to set it up properly which you may find valuable.