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.
Related
The title is a little confusing because this is hard to explain. So to start I'll go into a little more detail on the problem.
So I have a Rest API on Web Api 2 that authenticates currently via Microsoft Identity Model 3.5 consuming a FedAuth cookie. This fed auth cookie is issued by the SessionAuthenticationModule on another web app. That web app authenticates against ADFS and generates an authentication cookie. I intended for that cookie to be on the root path and be on the same domain as the Rest API on web app 2.
As such, with "pass credentials true" on the ajax call, and the domain set on the cookie and both apps on the same base domain the authentication cookie is visible by the rest api and it's session authentication module consumes it and the rest api is authenticated as the logged in user on web app 1.
The issue is that due to issues out of my control, we are unable to change the Cookie path to be on the root path. As such the cookie is not passed to the rest api.
So I need to come up with a solution to authenticate the rest api from the parent web apps authentication context. I've come up with a few ideas:
Hook into Write Session Token, and generate a second cookie specifically for the API's that is on the root path with a new cookie name, but I don't really want to double the authentication payload on the web requests (double the cookies...)
Just do some basic rijandael encryption and encrypt the logged in user id in a new cookie and consume that and write an authorization filter on that in the rest api to authenticate if that cookie decrypts to a valid user id (with some salt). The api only needs to know who the logged in user id is...
Set the fed auth cookie to be viewable in script (it's encrypted and we use cors), and then I can pass the cookie chunks in the ajax calls to the rest api as I can read them with js.
???
I am developing a web api service which will be consumed by asp.net mvc web application and mobile apps (android and ios). My database and web api will be hosted on same server. I want to implement authentication for web api (token based). My database has a table for storing user credentials. I will have to use this database to validate the credentials when the user logs in.
Came across a few articles which suggest owin and identity server. I am confused on how to proceed and need some help in understanding a better approach.
you can simply implement the token base authentication
when user is login to the system send the random token code
cash it in the client side
when client side making request to the server send the token with the request header
validate the token and accept request or reject
simple way :)
I have created a WCF Service that runs in IIS and is published in a website.
I also have a MVC application that uses indentity 2.0 to authenticate and authorize my users and this application is connected to a SQL Server database with user information. This applications consumes the WCF service.
What I want to know is if it is possible to use the user credentials from authenticated user in the MVC application to make calls to the WCF Service and, if yes, which is the best practice for doing this.
I've finally found an answer for this subject.
When calling the web services from your asp.net mvc app you can pass the cookie like this:
var request = HttpContext.Current.Request;
var cookie = request.Cookies.Get("IdentityCookie");
var ticket = cookie.Value;
Pay attention that in this line var cookie = request.Cookies.Get("IdentityCookie") It will not work in your case because I renamed the cookie, if you didn't rename the cookie you replace "IdentityCookie" for ".AspNet.ApplicationCookie" otherwise just replace it for your cookie name.
(In my case I have a class that auto sends message headers in every request, the cookie goes in that header, you can make something similar)
Then you just need to make a message Inspector in WCF side so that every request pass to that inspector before calling the service. In that Inspector you can decrypt the cookie and check if the user is authenticated.
It resolved the problem for me, I hope this can help.
I have created a secured Web API 2 website. I have used oAuth2 to authenticate requests and it works. I get an authorization token (bearer) which I can use to call data from that website. Let's call this the authenticationWebsite
However...I need to create multiple API websites. Is it possible that I authenticate myself on the authenticationWebsite where I get a authorization token and then use that token to call data from my other api websites?
I have tried a simple example and created another website (mvc) which gets the authentication token from the authenticationWebsite but when I try to get data from the new website (from a controller which has the authorize attrubute, I get the unauthorize error.
I hope the question is clear.
Ok I figured it out. It is important that the authentication server and the resource server(s) have the same Machine key in the web config.
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.