An app I'm working on interfaces with an existing application running on a remote box. Communicaitons with the remote app are via its public web services. I've been asked to build an enhancement which will involve a client making use of the web service to handle sensitive data which will need to be transmitted securely.
Could anyone give me some pointers on how best to proceed?
To start, you should be using SSL and reject any requests that are not using it. This will encrypt data as it's being transmitted over the Internet.
If you are using SOAP, you could define a custom header in your service that takes a username / password. Then, for the first line in each public method, validate the username and password against a database. If successful, set the HttpContext.Current.User appropriately, and your service will tie in nicely with the built in Asp.NET infrastructure.
ADDED: Below is a sample SoapHeader that includes a username / password for authentication.
// define the header
public class AuthenticationHeader : SoapHeader
{
public String UserName { get; set; }
public String Password { get; set; }
}
// your service
public class PublicWebService : WebService
{
// defines an instance of the header as part of the service
public AuthenticationHeader Authentication;
private void Authenticate()
{
// validate the username / password against a database
// set the HttpContext.Current.User if successful.
// Maybe throw a SoapException() if authentication fails
}
// Notice the SoapHeader("Authentication") attribute...
// This tells ASP.Net to look for the incoming header for this method...
[WebMethod]
[SoapHeader("Authentication")]
public void PublicMethod1()
{
Authenticate();
// your code goes here
}
// Expose another method with the same authentication mechanism
[WebMethod]
[SoapHeader("Authentication")]
public void PublicMethod2()
{
Authenticate();
// your code goes here
}
}
Now, if you run the wsdl tool, the generated proxy class will include the defined authentication header:
PublicWebService s = new PublicWebService();
s.Authentication = new AuthenticationHeader();
s.Authentication.UserName = "xxxxxxxx";
s.Authentication.Password = "yyyyyyyy";
s.PublicMethod1();
s.PublicMethod2();
DIY route:
Read up on security (start with "Secrets and Lies" and other such general books before moving on to the technicalities)
Perform a risk analysis and thread assessment. Understand what you are protecting and from what, and where threats will come from. You are unlikely to need "High Security"1.
Use TLS (aka SSL).
In the client, verify the server's certificate is correct.
Better route: employ an expert who has an established reputation to help you.
1 Unless you really are building a nuclear weapons plant or similar.
Related
I would like to write method validation processes which will be similar to data annontations presented in Web API.
In web api we can validate an object, for example:
public class Numbers
{
[NumberOne]
public string Number1 { get; set; }
[NumberTwo]
public string Number2 { get; set; }
}
and as long as we define the attributes NumberOneAttribute and NumberTwoAttribute its gonna be ok.
The difference is that web api has access to the GlobalConfiguration.Configuration.Filters which it seems like signalr doesn't.
Is there anyway to validate requests by attributes? or I need to follow the worst case, validate each input in the invoked method?
Thanks,
Ori.
In SignalR 2.2.x there is no native way of achieving this, but there is a project on GitHub that that adds a Validation Module in the SignalR pipeline.
Basically, in order to use it, you add a new module to the pipeline:
GlobalHost.HubPipeline.AddModule(new ValidationModule());
Then, you can use attributes like [Required] for the models' properties and then decorate the desired methods with the [Validate] attribute.
Note that this is a proof of contept project.
Best regards!
I am trying to implement authentication for my web api.
I have read about different techniques of api authentication and the token technique is the most reasonable for me.
I read different articles about how to implement token based authentication in asp.net but they all rely on different libraries such as OAuth or Owin which also provide their own method of database interactions.
The thing is that I have already implemented database interaction with abstract repositories and entities and I would like to find out how can I implement api authentication easily and simply without interfering with my current design.
(By the way, my project is built on top of an empty web api project, so it doesn't come with all the bootstrap and authentication classes).
Thank you
One solution I've seen is to use .NET's HttpApplicationState class and store tokens in appstate; this way you're not directly messing with Session (which would be a REST antipattern), but you can still track all currently logged in users and use HttpContext/HttpActionContext to x-ref active tokens in the app. The benefit to using HttpActionContext is that it is thread-safe, whereas HttpContext is not, so you can lock the appstate, mess with the HttpContext of an individual request, and then unlock the appstate to allow other threads in.
Since locking/unlocking appstate does tie up the app, I'm not sure how well this solution scales, but here it is anyway . . .
General outline:
When a user first logs in, a token is generated for him/her and stored in appstate. Then you can tag any API calls that require authentication (or that need other information stored on that user) with a custom attribute that checks for that token in the appstate, sending the token name as a header in the API call (e.g. "{token-name: TOKEN}").
Here's a brief example:
[in Controller method first activated at login:]
CustomUserObject user = new CustomUserObject();
//store user props
string token = Guid.NewGuid().ToString();
//create AppState instance, mine's called _appState
//...
_appState.Lock();
_appState[token] = user;
_appState.UnLock();
//...
[Then in global.asax:]
public class CustomAuthorize : System.Web.Http.AuthorizeAttribute
{
HttpRequestMessage request = actionContext.ControllerContext.Request;
string token = string.Empty;
if (request.Headers.GetValues("token-name") != null)
{
token = request.Headers.GetValues("token-name").FirstOrDefault().ToString();
IAppStateService appService; //<--- I've created a custom service tier class for appstate stuff
//Get appState instance, however makes sense for you.
//I'm using repo pattern with UnitOfWork, so mine looks like this...
//"IContainer ioc = DependencyResolution.IoC.Initialize();"
//"IAppStateService appService = ioc.GetInstance<IAppStateService>();"
appService.SetHttpApplicationState(HttpContext.Current.Application);
bool isAuthorized = appService.CheckTokenAndDoStuff(token);
//inside that method ^^^ you'll do stuff like
//"_appState.Lock();"
//"if (_appState[token] == null) return false" (or whatever)
//"_appState.Unlock();"
}
if (isAuthorized)
{
HttpResponseMessage resp = request.CreateResponse(HttpStatusCode.OK);
resp.Headers.Add("AuthenticationToken", token);
resp.Headers.Add("WWW-Authenticate", "Basic");
resp.Headers.Add("AuthenticationStatus", "Authorized");
}
return isAuthorized;
}
[then in webapi]
[HttpPost]
[CustomAuthorize]
public HttpResponseMessage NameOfMethod(...)...
...and that should x-check your appstate for your user token for you. Just make sure to include your token in your request header, and make sure to include the Basic Auth info in your response header.
I am in need of help with Web Api.
I am setting up a multi tenant system when each tenant has there own database of data using code first EF and web api (so that I can create multiple app platforms)
I have extended the standard ASP.NET Identity to include a client id and client model which will store all tenants and their users.
I have then created another context which tracks all the data each tenant stores.
Each tenant holds a database name which I need to access based on the authenticated user.
Not getting the user id from each api controller seems easy:
RequestContext.Principal..... etc then I can get the client and subsequently the client database name to pass to the database context however I am trying to implement a standard data repository pattern and really hate repeating myself in code yet the only way I see it working at the moment is to:
Application calls restful api after authorisation
Web Api captures call
Each endpoint gets the user id and passes it to the data store via the interface and subsequently into the data layer retrieving the database name for the context.
What I have a problem with here is each endpoint getting the user id. Is there a way to "store/track" the user id per session? Can this be achieved through scope dependency or something similar?
I hope that makes sense but if not please ask and I will try to clarify further, any help will be greatly appreciated.
Thanks
Carl
ASP WebApi does not have a session context. You may use a cookie or a request token identifier (pass this token back from login and use this token as a parameter for further API calls).
This is something I've developed some time ago. I'm simply creating a new class deriving from ApiController and I'm using this class as a base for all other API class. It is using the ASP.NET cache object which can be accessed via HttpContext. I'm using the current user-id as a reference. If you need something else, you may use another way of caching your data:
public abstract class BaseController: ApiController
{
private readonly object _lock = new object();
/// <summary>
/// The customer this controller is referencing to.
/// </summary>
protected Guid CustomerId
{
get
{
if (!_customerId.HasValue)
{
InitApi();
lock (_lock)
{
if (User.Identity.IsAuthenticated)
{
Guid? customerId = HttpContext.Current.Cache["APIID" + User.Identity.Name] as Guid?;
if (customerId.HasValue)
{
CustomerId = customerId.Value;
}
else
{
UserProfile user = UserManager.FindByName(User.Identity.Name);
if (user != null)
{
CustomerId = user.CustomerId;
HttpContext.Current.Cache["APIID" + User.Identity.Name] = user.CustomerId;
}
}
}
else
{
_customerId = Guid.Empty;
}
}
}
return _customerId.GetValueOrDefault();
}
private set { _customerId = value; }
}
// ... more code
}
Do not blame me on the "lock" stuff. This code was some kind of "get it up and running and forget about it"...
A full example can be found here.
Maybe I am far from truth but Web API is state less so you dont really have a session to track
In my first project going real DDD, I'm stuck with some doubts concerning which course to take in this scenario...
I have a distributed architecture, in which users of several applications will have only one account that will make them able to authenticate. This account can be created on our own system, or the user can share with us his login with facebook, google and other third-party account provider.
So, there's a project for only this purpose, control user accounts.
This scenario made me came with this approach within my model (simplified):
public class User
{
public User(string name)
{
Id = Guid.NewGuid();
Name = name;
}
public Guid Id { get; protected set; }
public string Name { get; protected set; }
}
public abstract class Account
{
protected Account(User user)
{
Id = Guid.NewGuid();
User = user;
}
public Guid Id { get; protected set; }
public User User { get; protected set; }
}
public class MySystemAccount : Account
{
public MySystemAccount(string email, string password, User user)
: base(user)
{
Email = email;
Password = password;
}
public string Email { get; protected set; }
public string Password { get; protected set; }
}
public class FacebookAccount : Account
{
public FacebookAccount(string facebookId, User user)
: base(user)
{
FacebookId = facebookId;
}
public string FacebookId { get; protected set; }
}
The thing is that the other applications will access this project via REST services.
So, I thought about a single /Authenticate service that will provide a json with dynamic form. It could de a json with a email/password, or a json with the facebookId.
But then, how can I connect the layers?
I thought about making an application service, but I got stuck on who and how should decide what is going on, what should my rest service communicate to the application and how the application will know to do the thing, whatever kind of authentication it is, an user from my own domain or a user from facebook and so on..
Any thoughts on this?
Thanks!
This seems to be a multi-part question - one part about the object model and polymorphism and another about architecture.
Regarding the object model, the use of inheritance isn't ideal in this scenario. Each sub-type of Account won't really have much specific behavior or any behavior at all. The only specialization is the presence of different data fields. Additionally, use of inheritance will complicate persistence.
Architecturally, what I think you're trying to achieve is federated identity. This basically decouples the notion of a user (an identity) from the authentication process. In turn, this allows all remaining application code to bypass authentication concerns and depend only on the user's identity. Take a look at OpenID as well as the DotNetOpenAuth library which provides an OpenID implementation in C#.
I'm new to Stackoverflow, so not sure how to just put this as a "suggestion", but I would rethink your model a little bit. I think of a "User" as someone who strictly is a person utilizing your application through your own website. This "User" would go through the authentication as you suggested, either via an account from your own system, or via an Open ID or OAuth ID provider like Facebook and Google.
If an application however, wants to access your "application" via REST calls, then I'd put them through a different authentication mechanism. In a sense to me, you are providing an API layer and software as a service. I'd take a look at how Twitter, Facebook, or Google expose their APIs for other applications to use. Typically, there is a secret key and application ID involved in authenticating the REST calls.
I'm using something like this on my server:
TcpServerChannel channel = new TcpServerChannel(settings.RemotingPort);
ChannelServices.RegisterChannel(channel, true);
RemotingServices.Marshal(myRemoteObject, "myRemoteObject");
I would like to subscribe to some kind of event so that whenever a remote client connects to myRemoteObject, I can check the Thread.CurrentPrincipal.Identity.Name to decide whether to authorize him.
Currently I'm doing the authorizing check in every exposed remote method of myRemoteObject which is a messy...
In my remoting application i defined a special object/interface where clients first need to authorize. The special object then returns, if the client successfully authorized the remote object. So you have the authorization at one place.
It looks something like this.
public interface IPortal
{
object SignIn(string name, string password);
}
public class Portal : MarshalByRefObject, IPortal
{
private object _remoteObject;
public Portal() {
_remoteObject = new RemoteObject();
}
public object SignIn(string name, string password)
{
// Authorization
// return your remote object
return _remoteObject;
}
}
In your application you host the Portal-Object
TcpServerChannel channel = new TcpServerChannel(settings.RemotingPort);
ChannelServices.RegisterChannel(channel, true);
Portal portal = new Portal()
RemotingServices.Marshal(portal , "portal");
You could use something like PostSharp to factor out the check from every method - just do it in the AOP advice. (You apply this to the class which is exposing its methods, not to the client connection.)
This approach is independent of whatever transport you use for remoting - it just factors out the cross-cutting concern of authorization across all the methods in your remoted class.