I got lots of articles and SO question based on Claim based authentication for WCF Restful Services, but I am using MVC Web API to develop RESTful Service (Not WCF Rest Service)...
So could you please help me to understand how to secure RESTful service using claim based authentication?
Here is what I need:
I have a Web App and MVC4 Web-API service
We have STS
The MVC Web App trusts the STS
Now the user logs into the Web App, he is redirected to the STS login page.
Once logged in, he is redirected back to the MVC Web Site.
This web app invokes the web-API Service.
Now, I have been stuck at point #4. We have a RESTful service, but need to implement WIF.
Can anyone please help me with this.
Note: I am NOT using WCF Restservice but using MVC Web API
From your description, it sounds like you are using a delegated identity model. That is, the user signs in to the web application and when the web application invokes the Web API service, it uses the identity of the currently logged in user.
If that is the case, then you need to configure WIF to save the "bootstrap tokens". The effect of this is that the original security token is available as a property on the current ClaimsIdentity. you can then use that to set the Authorize header of he request to the Web API service call.
To turn this on in .Net 4.5 you set the saveBootstrapContext attribute on the WIF element to true:
<system.identityModel>
<identityConfiguration saveBootstrapContext="true">
...
For .Net 4, the config looks lke this:
<microsoft.identityModel>
<service saveBootstrapTokens="true">
...
Then to access it from the web application you do something like (depending on how many identities you have) this in the controller that is going to call the Web API. For .Net 4.5:
SecurityToken token = (User as ClaimsPrincipal).Identities[0].BootstrapContext;
For .Net 4:
SecurityToken token = (User as ClaimsPrincipal).Identities[0].BootstrapToken;
Having obtained the original security token, you can now attach it to the calls to the Web API as an Authorize header. Generally this will be attached as a Bearer token, which is just a fancy way of saying that you append the word "bearer" to the start of the header value. To attach the token, do something like this:
WebClient request = new WebClient();
request.Headers.Add("Authorization","bearer " + tokenAsString);
Note: Generally you will encrypt or base64 encode the token value in transit rather than attach the raw string, especially if it is XML, since some frameworks will mangle the XML in transit.
To convert the token to a string, you should user a class derived from SecurityTokenHandler There are a number of these included in the standard framework assemblies for handling some standard token types. For REST services, the JSON Web Token is a popular format and there is a NuGet package containing a handler for that here
https://www.nuget.org/packages/System.IdentityModel.Tokens.Jwt/
If you are using some other token type, you can write your own handler (it is not difficult in fact) or try to find on on the web.
In .Net 4.5 the SecurityTokenHandler class has a WriteToken(SecurityToken) method that returns the token as a string. In earlier versions of WIF only the XML version of WriteToken was supported.
There are several samples showing how to use the SecurityTokenHandler for REST services on the server side. A good example is here
http://code.msdn.microsoft.com/AAL-Native-App-to-REST-de57f2cc/view/Discussions#content
All the relevant code is contained in the global.asax.cs file.
If your client is not authenticated the your Web Api service should return a 401 Unauthorized response.
It will then be your clients responsibly to seek authentication and gain a new token. You should return the link to your log in form in the WWW-authenticate header
This video might help - Securing ASP.NET Web APIs http://vimeo.com/43603474
Related
We have a self hosted WCF REST API service (not ASP.Net). We currently support Basic and Negotiate authentication.
We would like to add support for JWT in a cookie, so that we dont have to authenticate against the DB on each call, and so we dont have to set headers. The main issue is that we want our web application, which uses the API to be able to provide links to retrieve resources for downloading without setting headers, ie rely on browser having a JWT pushed into a cookie.
We have an endpoint called /API/AuthToken, which supports Basic Authentication, but we’re not sure what the code to generate a JWT token, and pushing it to a cookie would look like. Specifically, what does the code for generating a JWT token should do.
I have not been able to find any documentation or samples on how to do this? Any leads or code snippets?
I have an ASP.NET MVC project and a Web Api project (separate projects). Access to the database is fully realized through Web Api (including authorization and authentication). ASP.NET MVC is a client, Web Api is a server.
So, how to correctly implement authorization and authentication in the ASP.NET MVC project (on the client side)? I read a lot how this is implemented in Web Api (through a token), but I can not understand how to correctly use this token in ASP.NET MVC.
Realize wrap for each request? I also do not know how to define the user role in ASP.NET MVC. Maybe there is some way to rewrite standard methods of ASP.NET MVC authorization to work with the Web Api token? Will the Authorize attributes on the ASP.NET MVC client side work? Suggest please in an example of such an implementation if possible, or tell me how best to implement it.
First of all if you are not in production yet, it might be time to jump to .Net Core 2.x. It does not separate Web API and MVC underground and it's up to date technology.If, for some reason, you can't upgrade the framework, then yes, employ Microsoft.Owin, Microsoft.Owin.Security.OpenIdConnect and all the dependencies.OIdC defines two types of tokens: Identity token, describing a user and Authorization token, giving access to API. There should be some Identity Provider in the system, authenticating users and authorizing clients (such as your MVC APP). Such provider could be external (Google, Office 365 etc), or internal -- you can use free Identity Server 4.x implementation and adjust it to feet your needs. You could even build the IdP into your app.The flow for both .Net Core and Owin OIdC implementations should be identical:
You register all your apps (API and MVC in Identity provider)
User requests an MVC resource, OIdC middleware redirects him to IdP.
IdP authenticates the user issuing identity and access tokens.
MVC validates the Identity token and uses it to create a local Authentication cookie, so the user becomes authenticated in the app.
MVC controller calls some API and put into the request access token, requested from IdP.
API validates the token and responds with requested data.
I would recommend you to use OWIN interface to implement token based authentication for web api and MVC. You should provide authentication token in your web api and give ability to deserialize the token in MVC and Web Api. So, you can find an example open source project here which I developed it about how can you implement token based authentication with OWIN for Web api.
For MVC project, you should follow the same practice by using OWIN.
The best way is to use Azure active directory authentication if active directory is configured for using your application. You can get more info here
I'm posting this in the hope of receiving some feedback/advice and information on something I've been struggling with the last few days. To start I'll give a quick breakdown of the project.
There are 2 applications in the solution:
WebAPI resource & authorization server - Uses OWIN (hosted in IIS) and ASP.NET Identity to issue an authentication token on a correct login and then allow requests to the various controllers.
MVC client application - Has no authorization as of yet (until I figure it out) but will make calls to the WebAPI resource server to get all data. These calls will only ever be made from actions of the controllers in the client app, no client side AJAX calls.
The client application doesn't have it's own datasource. All information is stored in a database which the WebAPI service has access to, so essentially if they provide the correct credentials and the client app receives a bearer token I need to deliver a way for the application to see them as authorized.
What's the best way to handle this?
Is it possible to configure OWIN on the client side to use the OAuth
settings of the server? Am I barking up the wrong tree and will I need to just use HTTPClients?
Could I deserialize the bearer token and store it in session, and
then write my own authorization providers to check these on the client side?
My initial concerns are I'm abusing Bearer Tokens and trying to cobble them into a solution which isn't ideal. All examples of external authorization I've found so far usually involve making calls to providers hosted by Google/Facebook/Twitter to check the user is who they say they are, and then moves on to creating a user record in their system. My application can't do this.
In regards to security I was planning to introduce filters which would validate the request has came from the client application by providing an identifier and secret, along with IP validation.
I realize this may be a bit open ended, but I'd appreciate any advice. The scope of the project is that the web service is the only thing to have access to the database. The MVC client application will be hosted on a different server, and the service will only accept requests from said client application.
You don't need to access the data source in your MVC app to validate the bearer token. Basically, you can do it in the following way,
MVC app requests access_token from webapi and passes it to the UI client (let's say a browser).
Browser stores the access_token in a cookie/localstorage and sends them to the MVC app for all subsequent requests.
Create an ActionFilter in the MVC app to validate if the request from the browser has the token supplied in the header. If not, reject the request.
MVC app passes the access_token in the Authorization header to the webapi.
Use HTTPS for all communications (between MVC app <-> Client and MVC app <-> WebAPI)
You can further obfuscate or encrypt the access_token you get from the WebAPI on the MVC app side for additional security but then you will have to send the decrypted version back to the WebAPI.
I realize that my answer is a bit late, but maybe it helps other people:
The bearer token that you get from the API has a list of claims encrypted that only the API can decrypt. I assume you need to have these claims on the MVC application as well so you can restrict resources on the client.
So, what I have done was to first get token. After you get it, you make another request to the API resource api/me/claims to get the list of readable claims on the client. Based on this list you can allow access to resources in your MVC CLient Application using a custom claims based Authorize attribute. Also, you can store the claims in a cookie in the client session. Below is the code for the API controller to get the Claims.
[RoutePrefix("api/me/claims")]
public class ClaimsController : BaseApiController
{
[Authorize]
[Route("")]
public IHttpActionResult GetClaims()
{
var identity = User.Identity as ClaimsIdentity;
var claims = from c in identity.Claims
select new
{
subject = c.Subject.Name,
type = c.Type,
value = c.Value
};
return Ok(claims);
}
}
The idea is to reconstruct the ClaimsIdentity object of the logged User on the Client side and maybe add it to the session.
The token is not enough. You might risk getting a Not Authorized response from the API on a resource that you have made visible for the user in the MVC Client Application. Needles to say that is recommended to use HTTPS for all requests.
I have a Windows Service running a Web API hosted as a OWIN middleware - the server. The API uses application cookie authentication and validates users against a database, using OWINs identity model. Now I would like to authenticate a user who accesses the API through a standard MVC web application (the client), but I'm unsure how to achieve this, e.g. after I received a response along with the cookie from the API, where do I have to store it inside the MVC application so that the cookie will be automatically sent along with further API calls.
You won't need to. Cookies are stored by the client's browser, and are sent to the web server with every request on the same domain name. Each subdomain will have its own sandbox for cookies. The main domain's cookies can be accessed by all subdomains.
MVC application will store it in the users browser the cookie. If you need to find an alternate way to achieve it, why not try localstorage. You can then send the authorization token with every request header using your Ajax calls. If you are interested in an Angular Application, here is an excellent tutorial that should help clarify a lot of question.
I have a Web API application and I've understood OAuth would be the standard security model for APIs where an Authentication Server would become responsible to generate Authorization Tokens so that the user can send to our server and consume the services.
I'm very new to this but I understand the roles involved:
Resource Owner
Client
Resource Server
Authorization Server
But what is OAuth exactly in practice, not in theory? Is it a .NET library? Is it a service provided by a separate Company? Is it something I can configure on my local development machine and see how it works?
How to get started with OAuth to secure a Web API application?
OAuth is a protocol; the current version is OAuth 2.0. More to your question, that link lists several implementations of the protocol in various technologies. For use with the .NET Web API you're probably interested in DotNetOpenAuth which provides implementations of both OAuth 1 and OAuth 2.
I'm using DotNetOpenAuth in an app I'm working on now to secure a .NET Web API. I've got an OAuth2Handler which extends DelegatingHandler which is inserted into the Web API pipeline before incoming requests reach any controllers. OAuth2Handler does the following:
Instantiates a DotNetOpenAuth ResourceServer
Calls ResourceServer.GetPrincipal() which reads and decrypts an access
token (issued elsewhere by the AuthorizationServer and returns an
OAuthPrincipal (In my case I'm reading additional data that the DotNetOpenAuth implementation allows you to pass and creating a ClaimsPrincipal.)
Assigning the IPrincipal containing the user information read from the access token to the User property of the thread and current HTTP context so it is available from the ApiController.User property in the service controllers: httpContext.User = Thread.CurrentPrincipal = principal;
Honestly, getting this all working (e.g. setting up the authorization server, resource server, certificates, etc.) isn't trivial. Unfortunately there didn't seem to be a good guide on the DotNetOpenAuth site. Here's a few other tasks you'll have ahead of you if you go this route:
Implement IAuthorizationServer - This is the interface provided by
DotNetOpenAuth that allows you to plug in to the library and use
their implementation to issue OAuth2 access tokens. You'll also need to implement INonceStore and ICryptoKeyStore which I did using an EntityFramework context for storage.
Configure Certificates - The AuthorizationServer and ResourceServer each use certificates to encrypt/decrypt the access token ensuring they are only accessible to each other. I built some custom configuration so I could manage this configuration in the web.config files of my authorization server app and my Web API services (resource server).
Manage Refresh Token - When first requesting an access token from the authorization server you'll get back (depending on your configuration) both an OAuth2 refresh token and an access token. The services use the access token which should be short-lived. The refresh token is used to get more access tokens. The refresh token should be kept secret (whatever that means in your scenario). For me it means the refresh token is never exposed to client-side javascript in my web app.
I hope that helps give you a high level idea of how to get started with OAuth and .NET Web API. Here's a blog post demonstrating some of these steps. This SO answer gives a few more high level details of the client side of the picture.
(The DotNetOpenAuth online docs appear to be down right now... sorry for no links to them; Apparently it has happened before).