How to authorize user in WCF service - c#

I have WCF Service where user can add a simple message. Before service put message to database, I need to authorize user, like here:
[OperationContract]
[WebGet(UriTemplate = "/GetMessages/{SessionToken}/{UserPassword}/{UserGLKNumber}")]
Messages GetMessages(string SessionToken, string UserPassword, string UserGLKNumber);
It's obvious that this solution is not good (sending in url user password and number). So, what is other approach?
What is important - I have a client written in Java/PHP/Obj-C (simple, small application) - anyway not in C#.

Write Login method and use ASP.NET auth cookie (forms based authentication), see this. Or use Basic authentication and let client to authenticate by http standard way.

You have to distinguish between Authentication (who is it) and Authorization (what can he do than). For the first you have a variety of options where Windows (the logon credentials of the user) or Basic (username + password) are most straightforward. This is just a manner of configuration on the service side.
On the other hand, authorization can be done on identity (which user is it) or by role (which roles apply to this user). The latter is possible "in code" with if/else constructs but also with attributes on the method [PrincipalPermission(SecurityAction.Demand, Role="Administrator")]. This specifies that you "demand" that the user accessing the method has the "role" administrator (something you specify yourself).
To supply roles to the identity you need some sort of role provider, obviously it is not something the user can provider. Therefore you can use the ASP.NET RoleProvider or a Secure Token Service that stands in between.
You can read more about it here: http://msdn.microsoft.com/en-us/library/ff405740.aspx

Related

How to skip Basic Authentication on certain conditions in self-hosted server?

I have an ASP.NET web application, let's call it Web App A, that is self-hosted using OWIN and NancyFX.
Web App A uses Basic Authentication, which is set up in CustomBootstrapper.cs like this:
pipelines.EnableBasicAuthentication(new BasicAuthenticationConfiguration(
container.Resolve<IUserValidator>(),
"MySpecificRealm"));
After querying the user for the username and password, Web App A calls an authentication REST API to validate the credentials and return a security token if they are valid.
I am being asked to make a subset of that app, let's call this subset Web App B, when a valid security token is specified in the URL instead of prompting for the credentials.
The following picture might help explain this:
Per the usual, there are various modules in Web App A that call:
this.RequiresAuthentication();
How can I bypass the authentication when a valid security token is passed as a parameter in the URL?
You need to either add a parameter to a config file or use a conditional compilation symbol. Either of these will set a flag that you can then check to bypass the wiring up of the Basic Authentication in the pipelines and possibly the this.RequiresAuthentication().
For those Nancy Modules that require authentication, add a required URL parameter to the incoming request for the caller to supply the security token.
You are going to need the REST API to have a call that validates the security token, and you will need to call it and receive back the userName so you can create your IUserIndentity.

Asp.Net Core - Custom Authorization and Identity from another server?

I'm trying to figure out how to configure/use the Asp.Net Core Authorization with the credentials and user data in another server, accessed through an API.
For example, in the "Auth" server, we have the Auth database, that stores users, roles and claims. Some examples:
GET https://auth.myserver.com/v1/users/4/IsInRole/Admin
The response is a simple bool.
Or:
GET https://auth.myserver.com/v1/users/4/GetRolesForUser/
The response is a list of roles.
The another server is the resource server (also entirely API based, no front-end). It stores a lot of data that demands authorization by roles and claims.
Also, we have a third player: the client.
The client will:
Ask the auth server to get a bearer and a refresh token, using an username and a password
The client stores those tokens and send the bearer to the resource server to get some data
The resource server will ask the auth server if the bearer token is valid
If it is, then the resource server needs to ask the auth server again about the user that has that bearer token, and if that user has the necessary holes/claims that are necessary to access the requested resource.
The 4 step is my doubt. I imagine that should happen on the resource server controllers:
[HttpGet]
[Authorize(Roles = "Admin")] //API CALL HERE TO THE AUTH SERVER (?)
public async Task<IActionResult> GetData()
{
...
Basically, I don't know how to Authenticate an user on the context (just until the request is returned), putting it in the HttpContext.User, using my own custom validation process.
I've tried to simplify this architecture as much as possible to make my question more clear. Please forget about the security on the "Auth" server.
If you are using jwts this flow can be simplified roles can be stored in claims which means that no api call is needed in the authorise attribute.
Also the resource server doesn't need to verify that the token is valid that can be done using a secret.
Look into thinktecture the following are good resources https://leastprivilege.com/ and https://brockallen.com/

How in ASP.NET MVC do I maintain info about whether a user is "logged in" throughout pages?

After they type in their password, should I keep a variable in server session storage like Session["loggedIn"] = true that I check when requests are made to pages that require a login, or is there a better/safer way this is traditionally done in ASP.NET?
No, do not keep this in a session variable. In fact, I would argue you should try not to use session for anything. Try to keep the HTTP communication as stateless as possible.
For authentication in ASP.NET MVC, you have 2 alternatives, but ultimately, the both end up working the same way: by writing an encrypted authentication cookie to the browser after you successfully log a user in.
The newer alternative was mentioned in a comment to the OP: Microsoft.AspNet.Identity. To use this, you should be using a newer version of ASP.NET MVC with the OWIN pipeline (though I am not sure if you have to). The older alternative is called Forms Authentication, and can be used with any version of MVC except version 6 (the new vNext / core 1.0 stuff) I believe.
When you have successfully integrated one of these 2 tools into your MVC application, after a user logs on, your Controllers will have a non-null User property of type IPrincipal. You can use this property to determine whether or not a user is authenticated:
// in a controller
bool isThereAUserLoggedIn = this.User != null && this.User.Identity.IsAuthenticated;
If you are using the newer Microsoft.AspNet.Identity, then this IPrincipal User property will be implemented as a ClaimsPrincipal with one or more ClaimsIdentitys. Forms Authentication does not do claims like this, so if you want claims, or social login, etc, use Microsoft.AspNet.Identity.
The way that this is traditionally done in ASP.NET and by my opinion also better and safer is by making use of the ASP.NET Identity package.
ASP.NET Identity handles all aspects around user accounts in a web application:
database for users, including roles and more
user registration and management, like register, email verification, log in, remember me option, forgot my password action and more.
user authentication & authorization
Just to make things more clear, authentication means that the user making the request is actually a valid application user and authorization means that the user has the authority to perform the requested action.
Practically, when a user logs in, Identity automatically keeps that information and makes it available in all controllers and views under User property. So you know at any time which user made the request. Identity also supplies each request with a cookie used for user authentication and authorization.
To check for user authentication you use the User.Identity.IsAuthenticated in a view and the Authorize attribute in a controller:
[Authorize]
public ActionResult Create( ... ){ ... }
The above use of the Authorize attribute will allow only to registered users to request this page.
It is also very common to extend the functionality of your application to include roles for the users and user authorization. Identity creates a "Users" table, a "Roles" table and a many to many relationship between them. After assigning roles to your users you can authorize their requests by using User.Identity.IsInRole("YourRoleName") in a view and in a controller:
[Authorize("YourRoleName")]
public ActionResult Create( ... ){ ... }
The above use of the Authorize attribute will allow only to registered users having the "YourRoleName" role to request this page. In any case if Identity fails to authenticate or authorize the request will prompt to the log in page.
ASP.NET Identity is simple to use, it works and it is easy to extend the membership functionality of your application both by making use the many tools supplied with it and overriding its classes to give them a more specific or complex behaviour.
You will find infinite help on the web on how to use it or a step by step guide.

WCF service login and operation permissions

For a WCF service host implementation, I need to roll my own authentication & authorization procedure, but I can't find any information about how WCF supports this. The system should be pretty straight forward using Username, Password for authentication and Role to check for operation permissions.
In WPF documentations and tutorials, all I found is authentication using WinLogon, IIS login or security certificate and permissions using ASP.Net roles and security realms. What I would like to have is (pseudo example):
myChannelFactory.Username = "myuser";
myChannelFactory.Password = "mypass";
myChannelFactory.CreateChannel();
and for operation contracts
[OperationContract(Permission = MySecurityRoles.Administrator)]
public bool Reboot();
There are many possibilities how you could achieve this.
You could use sessions and authenticate in the first call by passing username and password to the server.
http://www.codeproject.com/Articles/188749/WCF-Sessions-Brief-Introduction
Or you could (as you do in the example code) use the existing features and create a custom Username and Password validator on the server.
This example is quite nice:
http://msdn.microsoft.com/en-us/library/aa702565.aspx
You can then check the role in the actual implementation.

Authentication Service using WCF

I have a custom MembershipProvider as shown below. It validate user name and password against Active Directory. I would like to make this as an “authentication service”. This should work even if the client uses forms authentication or windows authentication.
There is a WCF “HR Service” which is providing employee information. The “HR UI” website is using “HR Service” WCF service. Now we need to ensure that any client using the “HR Service” should be authenticated using “authentication service” before accessing the operation of “HR Service”. If the client application is authenticated once, next time onwards it should not be validated again (till the application is closed). When a new instance of the client application is opened it need to be authenticated from beginning.
How do we achive it? Do we have any code samples for the end to end flow demonstration?
Note: I should be able to test it using self hosted services.
Note: The client can be of any platform (e.g. Java).
namespace LijosCustomValidation
{
public sealed class LijoMembershipProvider : MembershipProvider
{
public override bool ValidateUser(string username, string password)
{
bool isValid = true;
//my logic to validate the user name and password
return isValid;
}
//other implementations of Abstract Methods from MembershipProvider
}
Your auth service should return a token if the auth is successful. This token in turn should then be presented to the HR service.
You have a couple of options as to what the HR service does at this point. It can either know the secret to validate the token, or it needs to call the auth service to validate the token.
The token should be some value that can be validated if you know the secret, so it could something, say the users id, that is symmetrically encrypted. Ideally it should have a time component in it to prevent replay attacks.
I'd suggest some something like
<hash value>|<token issue time>|<user id>
The hash value should be hash (sha1, md5, etc) of everything after the first pipe. You can then base64 encode the result and pass it around. Validating the token could then check the issue date was within a certain time-frame.
You also have the option of storing the token in the client in a cookie and passing as a cookie to the services, or making it a parameter on your services. There may be other options, depending on your client architecture & how you want to structure your services.

Categories

Resources