I'm doing a mobile app in Xamarin Forms, which should be able to connect to an ASP.NET core web service (API). I also want the information on the web service to be secured by limiting it to Microsoft account signed-in users. The idea I had was to send the user's credentials and retrieve back the security token from the Microsoft graph within the mobile app. Afterwards, the user would send that same bearer token to the web service, which checks its validity, and grants the requested information only if the validation is successful.
I am new to web development, so first of all, I want to ask if I am using a good approach for my project (if not, what do you recommend?).
If it is, how should I set up the ConfigureServices function in my Startup class? When I include the [Authorize] tag in the controllers, the service crashes, telling me I should define an authentication scheme. I don't need authentication, only authorization (since authentication is done from the mobile app), Since these two are handled independently in asp.net core, I added a dummy jwt authentication scheme as a placeholder. However, when I send an http request with the security token from my mobile app, it gives me a 401 unauthorized error, telling me I'm sending an "invalid token" (this token works fine when connecting to the Microsoft graph).
I've searched in countless documentations, but all of them only consider scenarios in which the authentication is done within the web service, and not externally, like me.
Any help is appreciated
Related
I have a requirement to authenticate ASP.NET Core App via Google Sign In, but a Web API between client app (i.e. ASP.NET Core app) and Google sign in... I know it sounds confusing, so let me explain it with diagrams.
Here is the typical way to include google sign-in button and get user authenticated via their google credentials, It works perfectly fine
Step 1: First, create a new app on google identity developer portal, generate ClientId, ClientSecret and specify redirect_url like : https://yoursite.com/signin-google.
Step 2: In the Startup.cs class of ASP.NET Core project, Use AddGoogle as authentication middleware and it works perfectly fine.
Including diagram below for your understanding:
And here is the proposed flow. With a REST API in between client and google sign in. Question is, how do I authenticate client ?
From what I understand, you want your Client Application to invoke the REST Service on behalf of the user. The REST service needs assurance that both the Client and the User are authenticated.
We have achieved this using the OpenID Connect Hybrid flow. The bad news is that we had to add another service to the solution to achieve this.
How this differs from your proposed solution is this:
You must have your own identity service, and this must know of the existence of the REST service, the Client Application, and the User Identity.
The Client Application redirects the user to authenticate with the Identity Service (which further on redirects the user to authenticate with Google)
Identity Server provides the client application with an ID token for the user, and also a code which can be exchange for an Access Token
The client application requests the Access Token. This Access Token will authenticate both the client and the user
The client application then authenticates using this access token when invoking the REST Service
The REST Service issues a one-off request to Identity Server for the signature keys, and uses these keys to validate the access token.
We happened to use IdentityServer4 when implementing the Identity Server, but the protocol exists independently of any one implementation.
I have a web app front end and web api back end both written in ASP .Net Core 1.1 MVC. I am using Auth0 as the authentication server, using the "authorization code grant flow".
So the user logs in - i.e. the user gets directed to Auth0's login screen, which, if the username and password were correct, sends the web app back an authorization code, which the web app then exchanges for an access token, which is then used for all web api calls.
Then, the user clicks on a link which makes the web app call upon a web api action. My question is, how can the web api know which user is making the request? Or maybe at the point the user successfully logs in, the web app should call upon a controller in the web api and tell it which user just logged in? Not sure what the best practice is...
Thank you
I will answer in terms of OAuth 2.0 specification.
Specification determines 4 roles:
Resource owner
Resource server
Client
Authorization Server
In your context:
Resource owner is end-user.
Resource server is your Web API.
Client is your web application.
Authorization Server is Auth0.
Follow steps:
Your Web API should be registered on Authorization Server
(https://auth0.com/docs/apis).
Your Web API should be responsible to validate access tokens that
are used for requesting API. This access tokens contains info about
end-user/client (https://auth0.com/docs/api-auth/tutorials/verify-access-token).
You should include Web API scope in authorization request.
You should get access token in your web application and include it in HTTP request to Web API.
I have followed the great example on integrating ADAL and Xamarin Forms by Vittorio. I am still struggling though on how to best implement authentication in mobile applications based on Xamarin Forms.
What is the best way to authenticate a user in a mobile application base on Xamarin (forma) knowing that the user is registered in an Active Directory on premise which is synced to an Azure Active Directory? Currently I am using ADAL for that but would it perhaps be better to use Azure Mobile Services? I need a token so that I can authenticate a user in a webapi running in Azure Websites.
When I follow the example of Vittorio, I run into a problem that I don't get a refresh token from the AAD authentication call. I should not that my AAD redirects the real authentication call to an on premise ADFS server. I am not sure if that could be the problem?
for #1 you can use the ADAL sample exactly as is - the only difference is that you need to configure your app to request access to your web API and pass the API resource is when you acquire a token. See setup instructions in https://github.com/AzureADSamples/NativeClient-DotNet.
For the refresh token: ADAL used it automatically from its cache, but people often did not know/understand that and used the returned refresh token manually, doing a lot of extra work... So we are no longer returning the token in the result, but we do use it automatically whenever you call acquiretoken and the token needs renewing.
I have a web service built with WebAPI that accepts JSON requests and responds accordingly. The core architecture is built but there isn't any authentication/authorization.
After a lot of googling and poking around sample projects, I'm not sure where to start. I've found a ton of material from 2008 and 2009 but not a whole lot of recent guides/workflows for WebAPI / single page apps. I think the workflow should be as follows:
Check to see if the user is logged in: How can this be done with javascript? Do I send a cookie to my webAPI? If so, do I send that cookie as a parameter in the body of the request?
Let the user log in / register: How is this data encrypted/decrypted? Surely I can't be sending passwords over the wire... is this where SSL comes in?
Provide them with access to what they have rights to access: I think I got this - I can just authorize in the controllers on a per-request basis.
Any info would be awesome.
Basically you need a token based authentication or authorization.
If you are referring to the ASP.NET WebAPI, the following project will be a great place to start:
http://thinktecture.github.com/Thinktecture.IdentityModel.45/
Even if you are not using ASP.NET WebAPI, the following video is a great introduction on how to provide authentication/authorization on RESTful web services:
http://vimeo.com/43603474
To answer some of your questions:
Check to see if the user is logged in: How can this be done with javascript? Do I send a cookie to my webAPI? If so, do I send that cookie as a parameter in the body of the request?
You can use a cookie but I normally use the header in order to avoid common XSRF attacks. Cookies are automatically included whenever a http request is sent from the browser.
is this where SSL comes in?
Yes. If you are going to go ahead with the token based approach, you can use a separate server (Identity Server) to do the authentication for you.
JavaScript clients are unique. Do you have the Web API and the page serving up JavaScript in the same domain? If not, you have same origin policy restrictions. If you have the same Web application hosting the web pages and Web API, you can use forms Authn. In that case, you don't need to send the cookie containing the authentication ticket yourself from JavaScript. Browsers do that for you and that is the cause of XSRF problem. You have to be careful about JavaScript sending credentials that the end user is not supposed to know. If JavaScript knows something, any intelligent end user can get to that knowledge. OAuth 2.0 implicit grant could be a good choice. The end user enters the credentials (password) in the authorization server which issues an access token. JavaScript gets the token and presents it to the web API but it will never have access to the credentials.
I would like to leverage ACS to authenticate Windows Account users (and eventually users from other identity providers in the future) on a website.
I have found a lot of resources regarding ACS, but most revolve around using WIF/using managed code in the UI layer in order to validate a user. I'd like to avoid that. Is it possible to retrieve a token from ACS by making a REST-based call to ACS using javascript/jQuery to retrieve a token for a Microsoft Account user?
One example that I saw that came close, is this link, however this uses a service identity instead of leveraging identity providers. http://code.msdn.microsoft.com/windowsazure/MVC4-Web-API-With-SWT-232d69da
Here's my end goal:
This website would have two layers, a UI layer (MVC 4) and a service layer (MVC WebAPI). Both of these layers will need to scale independently of each other in Azure.
I'd like to have the UI layer call ACS to determine if the current session is authenticated. If it is, I'd like ACS to return a token to the client. I'd like to store that token on the client as for use in step 3.
Once the user has logged in, I'd like to have the client make a REST based calls to the service layer passing the Microsoft Account/ACS user token along in the header of each request, completely bypassing the UI layer for this second service request. The service layer would authenticate the user with each request.
The client would handle the response codes (200, 401, ect) from the Service layer by either redirecting to the login page, or by displaying the results.
I am unsure about step 2. How would the client browser retrieve a token from ACS that it can pass along to the Service layer?
I essentially want to do what Vittorio describes here, but I want to use a MVC4 web app instead of a Windows 8 store app.
In step 2, your MVC4 Web App is a relying party and therefore relies on the claims in the token presented by the subject/user. So, rather than the UI call ACS, it's really just redirecting the user to ACS for authentication. Anyway, based on your requirements and description, I believe this is the solution you're looking for.
http://blogs.msdn.com/b/vbertocci/archive/2013/01/09/using-the-jwt-handler-for-implementing-poor-man-s-delegation-actas.aspx
Hope this helps.
-Rick
I wrote up this answer before reading Vittorio's blog post that Rick linked to. That seems to pretty much what you want. I'll answer anyway to give some more context on WIF and how this scenario works, but you should check out that post.
First, it's important to note that when using WIF in your MVC 4 application, no authentication or validation is happening in the UI/presentation layer. WIF works at the request layer, and does a lot of things you would have to do yourself if you chose to go the Javascript route (which I don't think is a valid route, though it could probably be done with a lot of work).
It goes like this: When a user hits a page that requires authentication, WIF redirects them to to ACS, where you are then sent to Google/Microsoft to login (the identity provider). After you've authenticated with your identity provider, ACS then posts the resulting access token and claims about the authenticated user back to your application (the return URL in ACS configuration). Finally, WIF handles validating the token that was sent by ACS (no small task), and creates a ClaimsPrincipal object in your application that can be used to identify the user.
It sounds like what you want is impersonation/delegation, where a user logs in and their credentials get carried through from frontend to backend. For this situation, I see no reason why you shouldn't just use WIF for user authentication in your MVC 4 app. The user authenticates and WIF handles/validates the token (though because you're calling a web API you should probably use the JWTTokenHandler for its lightweight-ness). You create an Action in your MVC project that sends a request to your Web API with the token in the Authorization header. Your Web API gets configured to read the Authorization header of incoming request, uses JWTTokenHandler to validate the token, then you're done. You can steal much of the code for the Web API portion from this code sample (particularly the code in Global.asax.cs): http://code.msdn.microsoft.com/AAL-Native-Application-to-fd648dcf