I work on an application where I have a separate MVC layer and Web API Layer, both have the same authentication mechanism, I have chosen the individual accounts authentication option while adding the projects. The web api service layer will be directly accessed by some other mobile clients also.
But when the user logs in through MVC he should be able to access Web Api seamlessly, but I don’t want to really pass the username and password from MVC to the Web Api layer, I am told it is a bad practice. but i need to authenticate and authorize my user, so the only option i have thought of is to have a default account at Web API level to issue tokens, and this will be called from MVC post the authentication and a token will be returned which is written to a cookie in the client. Now the Ajax calls from the UI can use this bearer token and get the job done.
The only glitch I have here is that, because I am using a default account I need user details again for authorization at service level, though I am doing authorization at my UI level, the user can spoof the system. I was lost here and came up with a solution like, when the user logs in to MVC will send across user details also along with the call to get the WebAPI token and issue another token to the user so that the user uses both of the tokens to make a call to web api from MVC.
I am not sure if this works or if it is even the best way. I just wanted to check, how I should go from here. Any help on this will be really great.
This is a really good example of integration - I know they use Angular as the client but you can learn from this:
http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/
Check this section to see how they decouple the API from the front end (Part of the same article).
http://bitoftech.net/2014/09/24/decouple-owin-authorization-server-resource-server-oauth-2-0-web-api/
Related
I have a RESTful API written in ASP.Net that implements OAuth 2 for authentication, and it's currently accessed through a web application. I've also got a legacy desktop client that accesses the same resources directly (not through the RESTful API and without OAuth, but using the same login credentials and hitting the same database). The requirement I'm trying to meet right now is to allow a user to click a link in the desktop application in order to open the web app to a specific screen, and when they do, to have the web app authenticate automatically so that they don't have to manually log into it (since they've already logged into the desktop app).
I'm trying to work out how I can handle this within the constraints of the framework. I'm not too familiar with OAuth 2 in general, but from what I understand I shouldn't share tokens between clients and there are no flows specifically for this kind of hand-off (unless I'm missing something). Worst case scenario, I could generate a temporary token outside of OAuth that's used by the web client to authenticate rather than a username and password, but I'm hoping to avoid stepping outside of what's already in the framework to do what I need to do.
So the question is this: is there some decent way built into the OAuth 2.0 framework to handle this sort of "handshake" between two applications, or should I just build my own method of dealing with it?
Using temporary one-time tokens is actually part of OAuth spec (authorization_code grant type). In this case this short-lived code can be exchanged for access_token (and refresh_token). You will have to implemenent generating and validating of this authorization_code.
If you are using OWIN OAuth middleware:
You can generate the code at separate API endpoint accessed by your desktop client app.
After receiving token, pass it to your browser and direct it to auth endpoint with grant_type=authorization_code over secure connection. Example: call Process.Start("https://example.com/ExternalLogin/authorization_code_goes_here"). At the webpage redirect user to your OAuth Token endpoint with grant_type=authorization_code.
AuthenticationTokenProvider.Receive will be called, in which you will validate your token. (Example code here).
After successful validation OAuthAuthorizationServerProvider.GrantAuthorizationCode will be called, in which you will process the authenticated user in the same way you process it with grant_type=password.
Remember that your token validation logic should ensure that your tokens are short-lived, usable only once and transmitted over secure connection.
This is sometimes called "single sign-on" if you want to research this topic further.
I'm building a mobile application (that might also later become a web application). The server side is a ASP.NET MVC + Web API application and I'm thinking about ways how I could implement the service's user management and authentication.
How should I implement the registration/login screen in the app? Offer native app forms, that will send just API requests to the service or is it preferable to show a web browser component and display the website's login page and then extract a token after the user logs in? I see the first option is more user friendly, but the second one will let me change the login / registration page (like for example adding external authentication providers) without breaking older versions of the app.
My second question is regarding the external authentication providers. ASP.NET Identity has good support for them and it is quite possible to let users register using Facebook or some other OAuth2 provider. Does it make sense to add support for external authentication providers when I plan to expose the app's API publicly? Are there any reasons why that is not a good idea?
Your first option is best if you believe your users will trust you to manage their passwords. You make a secure call to your service, have the service produce a bearer token as the result. That would be an anonymous call. I used the answer from this question to get me going down that path:
Get IPrincipal from OAuth Bearer Token in OWIN
If your users are less likely to trust you with their credentials, then the web view and external provider is a good alternative. You would need to work with providers that support the "Implicit Grant Flow" since don't want to share the apps clientid and client secret on the mobile device. This approach involves using a web view to login in, and then capturing the token on the client uri fragment on the response. I think it is on a location header, but don't have a working example in front of me. Something like:
https://your.domain.com/#access_token = 8473987927394723943294
you would pass that token with each api call afterwards .
Good luck!
I am using AngularJS with ASP.NET Web Api server side. Seems to me like authentication has now become a breeze? Or is this too good to be true?
So I'm thinking of using the Web Api's "Individual User Accounts" authentication. And I am thinking that is all I need. As long as every request is authenticated and noone can get any data they shouldn't I shouldn't need to do much more right?
Or am I missing some key security fundamentals?
When it comes to securing the API you have two main approaches
Cookie based approach. This is the traditional way, where you use the standard form to authenticate the user and then set the form authentication cookie. All unauthorized request take the user to login page. If your API is always supported by UI front end to do login this method with work.
Second is using the authorization token in the header of the request. Once the user is authenticated he get a auth token, which he has to attach to every subsequent request in the Authorize HTTP header. Learn more about it here Individual Accounts in ASP.NET Web API . The advantage here is that you can expose your API without requiring a login page.
But remember when using the second approach, the auth token has to be stored on the client side as all subsequent request require this token. Look at this blog post Cookies vs Tokens. Getting auth right with Angular.JS to understand how to work with token.
Hope it helps.
Here's a great article about using Angular JS with WebAPI 2.0 token based authentication.
http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/
I am very new in web api security. I have used form authentication technique. when user logs in, a token is created and stored as a cookie in user's web browser. On each request the token is varified and if user is authenticated and authorized user is given access to the service.
but I think this approach does nothing in web api security. cookies can easily be copied and pasted in other browser and anyone can get the service.
I am thinking to use App key and secret along with form authentication. I am not suggested to use third party service like Oauth for authentication. I am not Sure about the Implementation of app key and secret that how it exactly works.
Please provide better way to secure my web api wihtout using third party services and to prevent cookie hijacking etc. What actions are performed to build a strengthly secure web api.
The forms authentication is good enough. You can also do the following:
Use anti-forgery (antifrogery) tokens. Check this or this
It will also be great if on sensitive actions you check if the call to the function was made from the same site or not.You can implement your own action filter for this. (check if the referral site is your site, or the expected site)
Edited:
Thanks guys for your comments. I guess you are right. Well authentication cookies in ASP are created as httpOnly cookies which means even if the site had some XSS vulnerabilities it will still be safe and cant be stolen. I would also suggest to use https everywhere if the site is used for sensitive operations (like a bank) to make sure the cookies are perfectly safe.
I am trying to do something like this:
I have a MVC4 Web App and a Web-API service (hosted on two separate roles in azure)
Another role runs CustomSTS1.
The MVC Web App trusts the CustomSTS1
Now the customer logs into the site he is redirected to the STS login page.
Once logged in, he is redirected back to the MVC Web Site.
From this web site, the customer performs actions, which in turn invoke the web-API Service.
I have the SAML token in the web app, which I pass to the WebAPI service.
Now when I try to validate the SAML token at the Web API side, I get a
Message=ID1032: At least one 'audienceUri' must be specified in the SamlSecurityTokenRequirement when the AudienceUriMode is set to 'Always' or 'BearerKeyOnly'. Either add the valid URI values to the AudienceUris property of SamlSecurityTokenRequirement, or turn off checking by specifying an AudienceUriMode of 'Never' on the SamlSecurityTokenRequirement.
This is without the Web API service trusting the CustomSTS1
Once I setup the trust,
I am always given a HTTP 401: UNAUTHORIZED, whenever I try to make a HTTP Get request to the WEB API Service.
Now, My Question is, (I know that my current approach is definitely wrong)
How do I setup the Trust relationship with the CustomSTS1, such that the WebAPI service is able to do an ActAS on behalf of the user logged into the MVC site?
OR
Is this architecture wrong?
And is there another way to achieve this?
That approach is wrong conceptually. The MVC application should negotiate a new token for the Web API in the STS using ActAs. That's how it traditionally works for SOAP Services. However, Web APIs are moving away from SAML as it is a complex format that relies on different WS-* specs. OAuth 2.0 is becoming the standard in that area if you want to support SSO at that level.
Another approach is to establish an implicit trust between the MVC app and the Web API, so all the calls to the Web API from the MVC app are done through a more standard Http auth mechanism like Basic Auth using an specific set of credentials that only the MVC app knows. The info about the logged user in the MVC app is passed as additional information.
Regards,
Pablo.