📜 ⬆️ ⬇️

Introduction to Claims-based identity

When developing applications on the Microsoft stack to obtain information about the current user, quite often (more precisely, almost always) you can find such sections of code or wrappers over them:

HttpContext.User.Identity.Name
HttpContext.User.IsInRole(...)


or
')
Thread.CurrentPrincipal.Identity.Name
Thread.CurrentPrincipal.IsInRole(...)


The purpose of these calls may be the need to make a decision on the authorization of a call to a function or method, display information about the current user, and so on.

User information appeared in these classes in various ways: reading data from the database, Forms authentication, NTLM token, Kerberos token. In each case, the task was to obtain information about the user, its authentication and additional information.

In the “pre-cloud times” this was quite enough for most applications. If this was not enough, then different kinds of custom frameworks were created, but at the head of the corner there was often the main question: does the user have a specific role? Up to a certain point, this was enough until the user repository was one; there was no need to interact with business partners and so on. With the advent of clouds, distributed systems, SaaS applications and other buns without which it is difficult to imagine a modern web, this model was not enough if, for example, you wanted to allow employees of your partner access to certain functions of your CRM. The same often raises the question of the development and evolution of the application, for example: initially you planned to use two groups of users, User and Administrator, and in your code generously created authorization
view attributes:

[Authorize("Administrators")]
public ActionResult DoSomeHardcoreAdminStuff()
{
...
}


a year later, the business decided that it would be nice to have several different groups of users with different levels of access and everything else (well, to understand all the drama of this situation) to delineate the rights for administrators to SystemAdministrator and SecurityAdministrator. And this is not the limit, since these requirements are limited only by the imagination of the business.

From the point of view of the developer, it all poured into the zoo of technology and crutches. Each application authenticated users in its own way. The user could authenticate using OAuth, Forms, Windows or anything else. In each case, you had to write your own authentication and authorization logic, and if you had Api, then you also had to draw a bicycle for it.

In response to this, in 2008 Microsoft saw the light of the first release of the Windows Identity Foundation (WIF) and introduced the concept of Claims-based identity. The purpose of this framework is to provide an abstract mechanism for expressing your requirements for the user without going into details of how this works.

In short, the idea of ​​WIF can be described with a fairly simple life example:
You turned 18 and you decided to go to the movies. Adult movies. But, unfortunately, did not have time to get a passport or any other identity card so far (well, or just was lazy). You are going and going to the passport office, after some time you get a passport and, presenting your passport, you can safely buy yourself the coveted ticket and go to the session. And this is how it looks from the point of view of WIF:



Subject, that is, you go to the Identity provider (passport office) and on the basis of the Certificate of birth Token receive PassportToken. Then, along with this PassportToken, you go to the Relying party (cinema) and, after confirming your age, get access to the service.

The main ideas that can be learned from this example are:

1. To authorize you, as a visitor to an adult session, the cinema does not need to drive its customer base or go anywhere. He needs only your identity card which he trusts (passport, military ID, rights).

2. The passport office does not know where you will present your passport. (From the point of view of WIF, it should know a little bit, but it is not necessary).

3. With a passport you can buy yourself a good whiskey after going to the movies, take a mortgage or something else in any institution that trusts the documents issued by the state. an institution.

Someone has already worked with protocols such as OAuth, WS-Trust and WS-Fed, SAML-P, and this interaction scheme will be familiar to them. In short, you receive user information from a trusted identity provider (Identity provider) in the form of a token of a specific format and use it to make any decisions in your application. In a degenerate case, such as Forms authentication, you yourself are the certifying party and use this information yourself. WIF allows such scenarios. WIF is flexible enough to support all sorts of scenarios.

WIF allows you to “outsource” the authentication process to a trusted party and minimizes the need for developer intervention in the authentication and authorization process. All credentials that are presented to your application are cast to the ClaimsPrincipal and ClaimsIdentity types. These types are very similar to the standard * Principal and * Identity, they also implement the IPrincipal and IIdentity interfaces, but have an additional property that is a collection of all the statements that are available to you about the current user. Moreover, for compatibility, various existing ways of working with IIdentity and IClaimsPrincipal are supported, for example:

[PrincipalPermission(SecurityAction.Demand, Role = "Administrators")]
static void CheckAdministrator()
{
Console.WriteLine("User is an administrator");
}


For this, it is enough that the user has a role type statement (you can configure the type of statements to be used as roles) with the value “Administrators”.

In an ASP.NET MVC application, this might look like this:

[ClaimsAuthorize(ClaimTypes.Role, "Administrators")]
public ActionResult DoSomeHardcoreAdminStuff()
{
...
}


Or so:

[ClaimsAuthorize(ClaimTypes.Permission, "DoSomeHardcoreAdminStuff")]
public ActionResult DoSomeHardcoreAdminStuff()
{
...
}


There are also more complex scenarios for checking access to a particular resource, or simply getting the user's age, his postal address, and home phone number.

As a result of all these transformations, the Role based security approach is no longer imposed on your application and you are free to choose how, on the basis of what and where to carry out the necessary checks, and also, in some cases, completely get rid of the mechanisms for storing user information within the application. Among other things, you do not care about how the user is authenticated, be it a standard login-password pair or a clever smart card. This is the task of your Identity Provider.

Currently, there are two main solutions for Microsoft's platforms for this approach: ADFS (Active Directory Federation Services) and Azure ACS. If neither of them is suitable for you, then you are free to write your own service yourself, the benefit is to put a template with an example out of the box to the studio. There is also an open source server IdentityServer on the basis of which you can develop your own product.

Some facts:

Out of the box, WIF supports the following protocols:
1. WS-Federation
2. WS-Trust
3. WS-Security
4. WS-SecurityPolicy
5. WS-Addressing

Support for the SAML-P protocol is in the CTP state. Information about the RTM version yet. There is also OAuth2 extensions.

SAML1.1 and SAML2 credentials are supported as standard. But there are already quite developed libraries that add support for SWT and even JWT (Json Web Token).

This was a very small excursion into what happens in the System.Security namespace. As part of the introductory post I would not like to go into details
By the way, in .Net 4.5 Claims-based identity and WIF become king of the hill. All * Principal types will be inherited from ClaimsPrincipal, the Kerberos tokens inside will contain a set of assertions and much more tasty. If someone is interested in this topic, write your wishes in the comments, as time will be sure to try to write.

Useful links:
1. msdn.microsoft.com/en-us/security/aa570351.aspx - page on MSDN.
2. claimsid.codeplex.com - code examples and free book.
3. leastprivilege.com - Dominick Baier's blog.
4. github.com/thinktecture/Thinktecture.IdentityServer - open source Identity Server.

Ps. Thanks to XaocCPS for the review.

Source: https://habr.com/ru/post/145306/


All Articles