Quantcast
Channel: IdentityModel – leastprivilege.com
Viewing all 204 articles
Browse latest View live

Relationship between IdentityServer and AuthorizationServer

$
0
0

We released a preview version of AuthorizationServer this week. AuthorizationServer is an implementation of the OAuth2 design pattern and helps making API authorization easier.

IdentityServer also has OAuth2 endpoints – so you might ask yourself why we started from scratch with a new project and did not just add more features to the existing IdSrv endpoints. We were also discussing this quite a bit – here’s a summary of our thinking.

Separation of authentication and authorization
AS (as the name implies) is all about authorization (see my post). We specifically designed AS to be composable with arbitrary authentication systems. That could be via the .NET built-in WS-Federation support to IdentityServer, ADFS or Windows Azure Active Directory…or by adding forms or OAuth based authentication to it. Even integrated Windows Authentication would work fine. I’ll talk more on how to implement those scenarios in future posts.

New technologies, new APIs – a clean slate
IdentityServer is heavily based on the WIF token service pipeline. That’s a great thing for implementing WS* style protocols like WS-Federation, WS-Trust and even SAML2p. For OAuth2, OpenID Connect and JSON Web Tokens, that pipeline is not optimal. To get the most out of those technologies, we had to start with a fresh design. There were other lessons learned from building IdentityServer (database access, dependency injection, UI…) and we are using different approaches now internally.

The future of OAuth2 in IdentityServer..and IdentityServer in general
We want to keep authentication and authorization separate. That means for IdentityServer that we will shift our focus back to authentication and user management and that we’ll move everything authorization related to AuthorizationServer. We will not immediately deprecate the OAuth2 support in IdentityServer – but all new features and improvements go int AS. That said – we have some great features planned for IdentityServer – stay tuned!

HTH


Filed under: IdentityModel, IdentityServer, OAuth, WebAPI

What’s in an AuthorizationServer Access Token?

$
0
0

The main job of AS is to produce access tokens in the JWT format. The client and the user provide the following input information for that process:

  • Client
    application (via the endpoint URL), client identifier, scopes
  • User
    identity, consent to the requested scopes

A resulting access token could look  like this:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.
eyJpc3MiOiJUaGlua3RlY3R1cmVBdXRob3JpemF0aW9uU2VydmVyIiwiYXVkIjoidXNlcnMiLCJuYmYiOj
EzNzE0OTM1NTAsImV4cCI6MTM3MTQ5NzE1MCwiY2xpZW50X2lkIjoiY29kZWNsaWVudCIsInNjb3B
lIjpbInJlYWQiLCJzZWFyY2giXSwic3ViIjoiZG9taW5pY2sifQ.
pcmbseDO9_sp2wQpkJTQhmu_CqDJQHC-N5HqIltByvM

That’s a serialized JWT – when you copy&paste that JWT to here – you will see the following JSON string:

{
    “iss”: “ThinktectureAuthorizationServer”,
    “aud”: “users”,
    “nbf”: 1371493550,
    “exp”: 1371497150,
    “client_id”: “codeclient”,
    “scope”: [
        “read”,
        “search”
    ],
    “sub”: “dominick”
}

  • iss
    Issuer name of the access token
  • aud
    Audience (the identifier of the application the token is for)
  • nbf
    Not before (start of validity period)
  • exp
    Expiration (end of validity persion)
  • client_id
    The identifier for the client that asked for the token
  • scope
    The granted permissions
  • sub
    Subject. The unique identifier of the user (aka resource owner).

The token is digitally signed – either with a symmetric key or with an X.509 cert.

Remark: When doing an OAuth2 client credentials flow, where no user is involved, the sub claim is missing from the token.

All claims besides sub come from the AS configuration database. It’s the job of the claims transformation module to provide the sub claim. But more on that in a separate blog post.

HTH


Filed under: AuthorizationServer, IdentityModel, OAuth, WebAPI

Authentication in AuthorizationServer

$
0
0

AS does not do its own authentication – that’s by design. When you download from the repo, AS is set up to be a WS-Federation relying party. In the configuration folder of the WebHost project you’ll find two config files: identity.config and identityservices.config that wire up AS to an IdP.

<system.identityModel.services>

  <federationConfiguration>

   

    <wsFederation passiveRedirectEnabled=true

                  issuer=https://idsrv.local/issue/wsfed

                  realm=urn:authorizationserver />

 

  </federationConfiguration>

</system.identityModel.services>

 

You can change these settings to connect to your own IdP, e.g. IdentityServer, ADFS, ACS or WAAD. The “Identity & Access” VS plugin makes it even easier to “auto-configure” AS (just don’t forget to remove the pesky authorization elements from web.config).

AS really only needs a single claim on the current principal to function properly – sub – the subject identifier claim from the JWT spec. It’s the job of claims transformation to provide this claim after authentication has happened. For this purpose AS comes with a pre-defined claims authentication manager that turns incoming NameIdentifier or Name claims into a sub claim. That works out of the box for the above mentioned IdPs:

public class NameIdToSubjectClaimsTransformer : ClaimsTransformerBase
{
    public NameIdToSubjectClaimsTransformer(
     
IAuthorizationServerAdministratorsService
svc)
        : base(svc)
    { }
 
    protected override Claim GetSubject(ClaimsPrincipal principal)
    {
        var nameId = principal.FindFirst(ClaimTypes.NameIdentifier);
        if (nameId == null)
        {
            nameId = principal.FindFirst(ClaimTypes.Name);
            if (nameId == null)
            {
                throw new InvalidOperationException(
                 
"No nameidentifier claim"
);
            }
        }
 
        return new Claim(Constants.ClaimTypes.Subject, nameId.Value);
    }
}

 

If your IdP uses a different mapping, simply change the implementation of GetSubject. If you want to wire up a different claims transformer altogether, you can find the relevant code in global.asax.

If you don’t use an IdP at all, you can also add a local login form to AS or switch to Windows authentication. In that case simply run the claims transformer in PostAuthenticateRequest to provide the sub claim.

The second authentication related plumbing is for the OAuth2 resource owner password flow. Since AS does not do authentication, the credential validation needs to be delegated. By default we do that using WS-Trust to the same IdP that takes care of the web login. This is implemented in the WSTrustResourceOwnerCredentialValidation class, and configured in autofac.config:

<component type=" WSTrustResourceOwnerCredentialValidation …"
            service=" IResourceOwnerCredentialValidation … " >
  <parameters>
    <parameter name="address"
               value="https://idsrv.local/issue/wstrust/mixed/username" />
    <parameter name="realm"
               value="urn:authorizationserver" />
    <parameter name="issuerThumbprint"
               value="BFF6C249A2FFAA51A959B422DAAEDCF10E8A38EB" />
  </parameters>
</component>

 

Again, you can take control over that process be implementing IResourceOwnerCredentialValidation and wire it up in above config.


Filed under: AuthorizationServer, IdentityModel, IdentityServer, OAuth, WebAPI

Thinktecture IdentityServer v2.2

30K Downloads of Thinktecture IdentityModel

NDC Oslo 2013 Slides and Videos

$
0
0

The NDC videos are online now!

Web API Security (includes first public demo ever of AuthorizationServer)
Video: https://vimeo.com/68327244
Slides: https://speakerdeck.com/leastprivilege/securing-asp-dot-net-web-api-ndc-oslo-2013

OAuth2 – The good, the bad and the ugly
Video: https://vimeo.com/68331687
Slides: https://speakerdeck.com/leastprivilege/oauth2-the-good-the-bad-and-the-ugly-ndc-oslo-2013

Enjoy!


Filed under: .NET Security, AuthorizationServer, IdentityModel, IdentityServer, OAuth, WebAPI

Tracing in Thinktecture.IdentityModel

$
0
0

A very common question is: “my Web API returns a 401. Why?”

The easiest way to find out, is to enable tracing in IdentityModel. Add the following code snippet to your web.config:

<system.diagnostics>

  <trace autoflush=true />

 

  <sources>

    <source name=Thinktecture.IdentityModel

            switchValue=Verbose,ActivityTracing>

 

      <listeners>

        <add name=ThinktectureListener />

      </listeners>

    </source>

  </sources>

 

  <!– worker process account needs write access  –>

  <sharedListeners>

    <add name=ThinktectureListener

         type=System.Diagnostics.XmlWriterTraceListener, …

         initializeData=C:\tracing\WebApiSecurity_idm.svclog

         traceOutputOptions=Callstack>

      <filter type=“” />

    </add>

  </sharedListeners>

</system.diagnostics>

 

Detailed authentication errors can now be found in the trace file (using SvcTraceViewer from the SDK), e.g.:

image

HTH


Filed under: IdentityModel, WebAPI

IdentityServer: Using WS-Federation with JWT Tokens

$
0
0

WS-Federation is token agnostic – that means you can also use JWT tokens instead of the default SAML ones.

Why would you want to do that? Well – JWT’s a slightly more compact which I think is irrelevant for WS-Federation (the token is only transmitted once, then exchanged with a cookie). But maybe you want to do something like Vittorio’s “Poor man’s Delegation/ActAs” where you want to forward the JWT token to a Web API.

Are there downsides? JWTs don’t embed the public key used for signature validation. That means you need to deploy those keys to the Trusted People folder on the target machine (as opposed to just checking for a issuer thumbprint match with SAML). That’s something to consider.

How does it work? In IdentityServer we currently don’t support specifying the token type per relying party (we are working on that) – but you can globally set the token type in general configuration:

image

Just copy the value from Default HTTP Token to Default WS* Token.

Here’s a relying party sample that works with JWT. What’s different to the same RP with SAML? Not much – I only registered the JWT handler in identityModel.config – that’s the beauty of WIF…


Filed under: ASP.NET, IdentityModel, IdentityServer

Hawk Support in Thinktecture IdentityModel v3.3

$
0
0

I just released v3.3 of IdentityModel to Github and Nuget.

It includes the [Scope] attribute for Web API (here) and the clickjacking protection for MVC (here).

But the biggest addition is certainly a full featured implementation of the Hawk authentication scheme (spec).

Hawk is a shared secret authentication method where the actual secret is not transmitted on the wire. Instead the secret is used to sign parts of (or the full) HTTP request. The recipient can validate the signature and thus make sure the sender knows the secret key. It also has some replay and integrity protection features when using unsecured transports (though I personally would not recommend to using it as a replacement for SSL).

The implementation is a contribution by Badri from “Pro ASP.NET Web API Security” fame. You can find his intro blog post here and a sample here. Thanks, Badri!

Have fun!


Filed under: ASP.NET, IdentityModel, OAuth, WebAPI

Thinktecture AuthorizationServer v0.5 released

Bringing SWT Support back to Thinktecture IdentityModel

$
0
0

When Microsoft released the JWT library, I thought that’s a good opportunity to remove the SWT support from IdentityModel. But it turns out, there are still scenarios for SWT – so I refreshed my old code and added the SWT token and token handler back.

Note: I am now using the NamedKeyIssuerTokenResolver from the JWT library which is very useful here and allowed me to remove a lot of my custom code.

Here’s how it works – Creating a token:

public SimpleWebToken CreateToken(byte[] key)

{

    var descripter = new SecurityTokenDescriptor

    {

        TokenIssuerName = http://issuer,

        AppliesToAddress = http://audience,

 

        Lifetime = new Lifetime(DateTime.Now, DateTime.Now.AddMinutes(5)),

        Subject = new ClaimsIdentity(GetClaims()),

 

        SigningCredentials = new HmacSigningCredentials(key),

    };

 

    var handler = new SimpleWebTokenHandler();

    return handler.CreateToken(descripter) as SimpleWebToken;

}

 

Validating a token

private static void ValidateSwtToken(string tokenString)
{
    var configuration = new SecurityTokenHandlerConfiguration();
    var validationKey = new InMemorySymmetricSecurityKey(
Convert.FromBase64String(Constants.IdSrv
.SigningKey));
 
    // audience validation
    configuration.AudienceRestriction.AllowedAudienceUris.Add(
new Uri(Constants.Realm));
 
    // signature & issuer validation
    var resolverTable = new Dictionary<string, IList<SecurityKey>>
    {
        { Constants.IdSrv.IssuerUri, new SecurityKey[] { validationKey } }
    };
 
    configuration.IssuerTokenResolver = 
new NamedKeyIssuerTokenResolver(resolverTable);
 
    var handler = new SimpleWebTokenHandler();
    handler.Configuration = configuration;
 
    var token = handler.ReadToken(tokenString);
    var ids = handler.ValidateToken(token);
 
    "\n\nValidated Claims:".ConsoleYellow();
    foreach (var claim in ids.First().Claims)
    {
        Console.WriteLine("{0}\n {1}\n", claim.Type, claim.Value);
    }
}

 


Filed under: IdentityModel, IdentityServer

Using IdentityServer to issue tokens for Windows Server ServiceBus

$
0
0

Windows Server ServiceBus supports SWT tokens to authorize actions on a SB namespace or entity (e.g. listen, send or manage).

In the Azure version of ServiceBus you would use the Azure Access Control Service to issue such tokens. In the on-premise version of ServiceBus you could do the same, but often you want to use an on-premise token issuer here as well.

This is where IdentityServer can help out! In this post, I mentioned, that I added Simple Web Token (SWT) support back to IdentityModel – which means that IdentityServer can issue SWT tokens as well.

Clemens and I exchanged some code snippets and ideas to bring the moving parts together – and the following is a walkthrough of how you could use IdentityServer to issue tokens for Windows Server ServiceBus to authorize access.

Step 0 – Enable SWT support and the SimpleHttp endpoint
Both SWT support and the SimpleHttp token endpoint are not enabled by default.

Use the admin area to enable the protocol:

image

…and uncomment the SWT handler in WebSite\Configuration\identity.config:

<!-- SWT -->
<add type="Thinktecture.IdentityModel.Tokens.SimpleWebTokenHandler, … " />

 

Step 1 – Create a relying party in IdentityServer
Start with creating a relying party that represents the SB namespace:

image

Possible realm names for SB are (check the docs for more info):

  • http://{server-host-name} /{namespace}/ – complete namespace
  • http://{server-host-name}/{namespace} /myqueue – for a specific queue
  • http://{server-host-name}/{namespace} /mytopic – for a specific topic
  • http://{server-host-name} /{namespace} /mytopic/subscriptions/mysub – for a specific subscription

The namespace would be swttest in our case. Also generate a symmetric signing key.

Step 2 – Configure ServiceBus
You use the SB Powershell cmdlets to configure the SB namespace. For that you need the symmetric signing key you just created and the issuer Issuer URI (that’s the Site ID on IdSrv’s general config page).

set-sbnamespace -IssuerUri http://idsrvsiteid -IssuerName http://idsrvsiteid -PrimarySymmetricKey fWUU…N4 -Name swttest

See the docs for more information.

Step 3 – Provide SB specific claims
To provide the SB specific claims (send, listen and manage) you need to provide a claims repository. I wrote about the general process of customizing IdentityServer here. You basically need to implement IClaimsRepository (or derive from the existing standard one) to get involved in providing the claims for the outgoing token.

The following sample repository illustrates the idea:

public class MyClaimsRepository : ProviderClaimsRepository
{
    string sbClaimType = "net.windows.servicebus.action";
 
    public override IEnumerable<Claim> GetClaims(
ClaimsPrincipal principal, RequestDetails
requestDetails)
    {
        if (requestDetails.Realm.Uri.AbsoluteUri == "http://sbserver/swttest/")
        {
            if (principal.Identity.Name == "bob")
            {
                return new List<Claim>
                {
                    new Claim(sbClaimType, "Listen"),
                    new Claim(sbClaimType, "Manage"),
                };
            }
            else
            {
                return new List<Claim>
                {
                    new Claim(sbClaimType, "Send"),
                };
            }
        }
 
        return base.GetClaims(principal, requestDetails);
    }
}

 

Step 7 – Request the token
To request a token you can use the SimpleHttp endpoint. This endpoint uses a simple GET request with two querystring parameters for realm and token type. The user needs to authenticate via Basic Authentication. In return you get a token response that contains the token and lifetime information.

var client = new HttpClient {

    BaseAddress = new Uri(Constants.IdSrv.SimpleHttpEndpoint)

};

 

client.SetBasicAuthentication(“bob”, “abc!123”);

 

var response = client.GetAsync(
 
“?realm=http://sbserver/swttest/&tokentype=swt”
).Result;

response.EnsureSuccessStatusCode();

 

var tokenResponse = response.Content.ReadAsStringAsync().Result;

var token = JObject.Parse(tokenResponse)[“access_token”].ToString();

 

(I am using Json.Net to parse the token response)

Step 8 – Use the token
OK – the last step is to use the token with ServiceBus – that is as simple as:

StaticSimpleWebTokenProvider tp = new StaticSimpleWebTokenProvider(token);
            
MessagingFactory factory =
    MessagingFactory.Create("sb://sbserver/swttest/", tp);
            
var qc = factory.CreateQueueClient("swttest");
qc.Send(new BrokeredMessage());

 

(The full source code can be found here.)

HTH


Filed under: Azure, IdentityModel, IdentityServer

IdentityServer: Overview of OpenID Connect Basic Client Profile

Two days of Claims-based Identity & Access Control Workshop in London

$
0
0

Great news! The London edition of the NDC conference has pre-con workshops and Jakob invited us to hold our claims-based identity & access control workshop there.

This is the first time Brock and I are teaching the workshop together, and given that we live on different continents, this won’t happen too often! This will be big fun!

So – come join us for two action packed days of claims and tokens goodness ;) Find the detailed agenda here, and I will announce an additional lecture once we get closer to the event!

You can book here.

 


Filed under: .NET Security, ASP.NET, AuthorizationServer, Conferences & Training, IdentityModel, IdentityServer, OAuth, OpenID Connect, WCF, WebAPI

Using AuthorizationServer with Web API v2/Katana–first look

$
0
0

Traditionally we have used Thinktecture.IdentityModel to parse and validate incoming JWT tokens in Web API. The good news is, there is nothing you have to change when moving to Web API v2 – the delegating handler approach, and thus IdentityModel are totally supported in v2.

If you want to move to OWIN-based hosting and Katana, you have to exchange our AuthenticationHandler with the new JWT middleware, e.g. like this:

app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions

{

    AllowedAudiences = new[] { Constants.Audience },

    IssuerSecurityTokenProviders =
      new[] { new SymmetricKeyIssuerSecurityTokenProvider(

                Constants.AS.IssuerName,

                Constants.AS.SigningKey) }

});

…and voila.

The above is not exactly the most brilliant looking API in the world, is it? (speaking the native tongue of the dev :p)…compared to IdentityModel (at least for the simple cases):

authentication.AddJsonWebToken(

    issuer: Constants.AS.IssuerName,   
    audience:
Constants.Audience,
   
    signingKey:
Constants.AS.SigningKey,
   
   
claimMappings:
ClaimMappings.None);

 

..But we are getting there…stay tuned…

(full sample is here)


Filed under: ASP.NET, AuthorizationServer, IdentityModel, Katana, OAuth, WebAPI

Claims Transformation Middleware for Katana

$
0
0

One missing piece in Katana security/authentication is claims transformation. Fortunately, this is easy to add:

public class ClaimsTransformationMiddleware : OwinMiddleware

{

    ClaimsAuthenticationManager _claimsAuthenticationManager;

 

    public ClaimsTransformationMiddleware(
            OwinMiddleware next,
            ClaimsAuthenticationManager claimsAuthenticationManager)
       :
base
(next)

    {

        if (claimsAuthenticationManager == null)

        {

            throw new ArgumentNullException(“claimsAuthenticationManager”);

        }

 

        _claimsAuthenticationManager = claimsAuthenticationManager;

    }

 

    public override Task Invoke(IOwinContext context)

    {

        if (context.Authentication.User != null)

        {

            context.Authentication.User =
              _claimsAuthenticationManager.Authenticate(

                context.Request.Uri.AbsoluteUri,

                context.Authentication.User);

        }

 

        return Next.Invoke(context);

    }

}

 

This leverages the .NET built-in ClaimsAuthenticationManager class. The corresponding AppBuilder extension method would look like this:

public static IAppBuilder UseClaimsTransformation(
this IAppBuilder app,
ClaimsAuthenticationManager
claimsAuthenticationManager)
{
    app.Use(typeof(ClaimsTransformationMiddleware), claimsAuthenticationManager);
    return app;
}

 

And last but not least, this is how you would wire it up in the Katana pipeline:

app.UseClaimsTransformation(new ClaimsTransformer());

 

Place the claims transformation middleware after all your authentication middleware. This will allow it to see all identities.

The full sample can be found here.


Filed under: AuthorizationServer, IdentityModel, Katana, WebAPI

Adding OAuth2 to ADFS (and thus bridging the gap between modern Applications and Enterprise Back ends)

$
0
0

AuthorizationServer can be combined with arbitrary authentication methods, but the fact that it comes pre-configured as a WS-Federation relying party, makes it particularly easy to combine it with e.g. ADFS.

This is a really interesting scenario, because it essentially allows adding OAuth2 support to your enterprise authentication infrastructure. And this in turn allows connecting your “modern applications” like HTML/JS, native mobile apps (iOS, Android, Win8/WP8) very easily to your enterprise Web API back ends.

That’s exactly what quite a high percentage of my customers want *today* – e.g. connecting their iPads to a Web API in their AD protected back end. Unfortunately this is not possible with *today’s* available Microsoft products.

AuthorizationServer to the rescue! By adding AS as a relying party to your ADFS you can leverage your existing federated authentication system – and that can range from “simple” IdP-only scenarios to full blown infrastructures containing federation gateways, proxies and (external) federation partners.

Here and here I already introduced the WS-Federation configuration for AuthorizationServer – this post specifically deals with the AS/ADFS combination.

Add AuthorizationServer as a relying party to ADFS
The first step is to “register” AS in ADFS. This is a normal relying party registration. Go to Trust Relationships –> Add Relying Party Trust and select Enter data manually.

Choose some display name, e.g. “AuthorizationServer” and don’t select an encryption certificate. Then enable WS-Federation and add the base address of your AS installation as the protocol URL:

image

On the next screen you have to choose a relying party identifier. That’s up to you, but AS comes pre-configured with urn:authorizationserver. So that’s probably the easiest:

image

On the issuance authorization rules page you could now configure which domain users get access to AS and thus OAuth2. That’s very nice but I leave that for you as an exercise if needed. By default every domain user will be able to request tokens.

As the last step, you have to add a claim rule that passes the user name to AS. You could use the domain\user format or user@domain. That’s up to you.

Use a pass-through rule for that:

image

You could also pass other arbitrary claims to AS, but the minimum requirement is a unique user identifier (this will become the sub claim in the access token).

That’s it. One last things since you are already in the ADFS management tool. Later on we need the thumbprint of the ADFS signing certificate. You can get the from Service –> Certificates. Double click the token-signing cert and copy the thumbprint (under Details):

image

Gotcha: This dialog is a buggy piece of sh**. You wouldn’t believe how often I already pulled my hair because of some “mysterious behaviour”. When you copy from this dialog you also copy some invisible Unicode characters. That means when pasting the thumbprint into web.config, the certificate validation will fail, because the APIs search for the value plus the hidden characters – even when string comparison succeeds. Can drive you crazy. The workaround is to use a text editor like Notepad+ or Sublime to remove the hidden characters (also remove the spaces for good measure)….or just use this great tool from Raffaele: DeployManager.

Connect ADFS to AuthorizationServer
Next you need to connect AS to ADFS. This could be done using the Identity & Access VS Add-in (see the video I linked to above). I am almost always faster changing the configuration manually.

First open configuration\identityModel.services.config in the WebHost project:

<system.identityModel.services>

  <federationConfiguration>

   

    <wsFederation passiveRedirectEnabled=true

                  issuer=https://adfs_server/adfs/ls

                  realm=urn:authorizationserver />

 

  </federationConfiguration>

</system.identityModel.services>

 

If you also used urn:authorizationserver in ADFS then you only need to insert the name of the ADFS server here.

Next open identityModel.config:

<system.identityModel>
  <identityConfiguration>
    
    <audienceUris>
      <add value="urn:authorizationserver" />
    </audienceUris>
    
    <issuerNameRegistry type=" …ValidatingIssuerNameRegistry, … ">
      <authority name="ADFS">
        <keys>
          <add thumbprint="signing_cert_thumbprint" />
        </keys>
        <validIssuers>
          <add name="http://adfs_server/adfs/services/trust" />
        </validIssuers>
      </authority>
    </issuerNameRegistry>
 
  </identityConfiguration>
</system.identityModel>

 

Here you need to paste in the token signing cert thumbprint and add your ADFS issuer URI. This is typically the above value modulo your ADFS server name. If you are unsure, you can look that up in the ADFS MMC under Federation Service Properties.

If you want to use the OAuth2 resource owner credential flow, you also need to open autofac.config to configured the OAuth2/WS-Trust bridge:

<autofac>
  <components>
    <component type="WSTrustResourceOwnerCredentialValidation"
               service="IResourceOwnerCredentialValidation" >
      <parameters>
        <parameter name="address"
                   value="https://adfs_server/adfs/services/trust/13/usernamemixed" />
        <parameter name="realm"
                   value="urn:authorizationserver" />
        <parameter name="issuerThumbprint"
                   value="signing_cert_thumbprint" />
      </parameters>
    </component>
  </components>
</autofac>

 

Here you need to configure ADFS’ WS-Trust endpoint (again, typically inserting the server name is sufficient) and also the signing cert thumbprint again.

Now AS is a proper ADFS relying party. The last step would be configure which domain user(s) are AS administrators. You have two options here: either run the initial configuration wizard and enter the user name there, or open the AS configuration database in App_Data and enter the user name into the AuthorizationServerAdministrators table directly.

Make sure you use the same user name format as you configured in ADFS (SAM account name format vs UPN). By default that would be domain\user.

To verify everything is working properly, try the Flows demo project and try out every OAuth2 flow. If everything is fine – you are now able to access AS and the Web API using your domain account – and that’s exactly what we wanted to achieve.

What about ADFS3?
The version of ADFS on soon to be released Windows Server 2012 R2 has built-in OAuth2 support. So you might not need our AuthorizationServer at all. In fact, many companies/admins indeed prefer a supported Microsoft product compared to some OSS project – also the the fact that it is built-into ADFS as opposed to a separate server piece might be easier to manage. ADFS3 also has other features around BYOD that could be useful to you. So if you can deploy Windows Server 2012 R2 this is a viable option.

Nevertheless I still see AuthorizationServer as very valuable and in a number of situations actually far more useful as ADFS OAuth2 support, e.g.

  • AS implements all OAuth2 flows – and ADFS3 only code flow (I might be wrong on that one since there is no real documentation right now). But we see a lot of value in the other flows as well – so do our customers.
  • AS fully embraces the OAuth2 scope concept – as well as the full authorization model around it (client, scopes, flows etc..). ADFS3 seems to divide its world into resources (== relying parties) and even uses a non-standard protocol parameter for that. There does not seem to be support for scopes at all. We had the same issue when we tried to add OAuth2 to IdentityServer which is a classic IdP – the concepts just don’t mix very well. That’s why we built AS from scratch.
  • For many real world scenarios it is actually beneficial that AS and ADFS are separate pieces. ADFS is typically administrated by “Domain Admins” whereas the authorization server logically belongs to the application and thus to “Application Admins”. I’ve seen a lot of friction between those two parties. Separating the concerns makes them often happier.
  • AS allows for full customization, e.g. the consent screen. ADFS deliberately moved away from IIS to limit customization.
  • AS has a UI for OAuth2. ADFS has PowerShell. sigh.

So to summarize – ADFS in general is a powerful identity provider/federation gateway for Active Directory based networks and user bases. ADFS3 adds “limited” OAuth2 capabilities to it.
AuthorizationServer is a fully featured implementation of OAuth2 – and in combination with ADFS as the authentication back end you get the best of both worlds.


Filed under: AuthorizationServer, IdentityModel, IdentityServer, OAuth, WebAPI

OWIN Claims Transformation Middleware–Take 2

$
0
0

Thanks to some good feedback from @grumpydev, @loudej and Chriss Ross – I changed my original claims transformation middleware (see here). What I learned is, that for better compatibility and discoverability, you should not expose the types of a specific framework (in my case Katana) on your public API surface. It is OK to use that framework internally – if you can live with that dependency. Here’s my 2nd take:

public class ClaimsTransformationMiddleware

{

    readonly ClaimsTransformationOptions _options;

    readonly Func<IDictionary<string, object>, Task> _next;

 

    public ClaimsTransformationMiddleware(
      Func<IDictionary<string, object>, Task> next,
      ClaimsTransformationOptions
options)

    {

        _next = next;

        _options = options;

    }

 

    public async Task Invoke(IDictionary<string, object> env)

    {

        // use Katana OWIN abstractions (optional)

        var context = new OwinContext(env);

        var transformer = _options.ClaimsAuthenticationManager;

 

        if (context.Authentication != null &&

            context.Authentication.User != null)

        {

            context.Authentication.User = transformer.Authenticate(

                context.Request.Uri.AbsoluteUri,

                context.Authentication.User);

        }

 

        await _next(env);

    }

}

 

Note that I am not deriving from OwinMiddleware anymore and also use the AppFunc on the Invoke method (instead of IOwinContext).

Note: This middleware does not work with Katana’s passive authentication mode. But that’s another issue.


Filed under: IdentityModel, Katana, WebAPI

Thinktecture.IdentityModel v.Next

$
0
0

Thinktecture.IdentityModel (github, nuget) is a popular library in the security community.

image

But we have reached a point now where we realized that we have too many dependencies and too many legacy stuff in it. With the release of Web API v2 and OWIN we thought now is the right time to split IdentityModel into smaller more manageable and more focused parts.

Welcome to the new Thinktecture.IdentityModel!

Core

  • Base64Url encoding
  • Epoch Date Time conversion
  • Random number generation
  • Time-constant string comparison
  • Certificate Store Access
  • Useful constants when dealing with algorithms, date time formats, tokens and protocols
  • Anoynmous claims principal
  • Authentication instant claim
  • Claims-based authorization
  • ClaimsPrincipal factory
  • Extension Methods for XML, security token conversion, X.509 certificates

Extensions and Middleware for OWIN/Katana

  • Claims transformation
  • Token format support
  • Support for retrieving tokens from headers or query strings
  • Authentication middleware

HTTP Security / OAuth2 Client Library

  • Portable library (.NET 4.5, Windows 8, Windows Phone 8)
  • OAuth2 client library
    • URL generation for code and implicit flow
    • Token requests for authorization codes, resource owner credentials, refresh tokens, assertions
    • Parsing of authorize and token responses
    • Extensible
  • HttpClient helpers for dealing with Basic Authentication and token headers

Embedded STS

  • Easy to use embeddable, zero-config STS for ASP.NET

Hawk

  • Implementation of Hawk authentication mechanism for Web API and OWIN

WCF 

  • WS-Trust bindings for UserName, Windows, Issued Tokens and X.509 certificates
  • Helpers for dealing with RSTRs and entropy
  • WS-Trust Client

SWT

  • WIF integration for Simple Web Tokens

We are not done yet and if you have feature ideas or want to contribute in a certain area, contact us on github. We believe that the new format makes it much easier to evolve the various parts and makes external contribution more feasible.

I will also publish pre-release nuget packages of all libraries soon.


Filed under: .NET Security, ASP.NET, IdentityModel, Katana, OAuth, WCF, WebAPI

Adding SAML11 and SAML2 Support to Katana/OWIN

$
0
0

Katana has pretty straightforward extensibility for adding support for token formats. It ships with built-in support for JWT (consuming) and their internal token format (consuming & producing).

By implementing ISecureDataFormat, you can add your own. The following class is a bridge from Katana to WIF’s security token handler:

public class WifTokenFormat : ISecureDataFormat<AuthenticationTicket>

{

    SecurityTokenHandler _handler;

 

    public WifTokenFormat(SecurityTokenHandler handler)

    {

        _handler = handler;

    }

 

 

    public string Protect(AuthenticationTicket data)

    {

        throw new NotSupportedException();

    }

 

    public AuthenticationTicket Unprotect(string protectedText)

    {

        if (string.IsNullOrWhiteSpace(protectedText))

        {

            throw new ArgumentNullException(“protectedText”);

        }

 

        var token = _handler.ReadToken(protectedText);

        var identity = _handler.ValidateToken(token);

 

        return new AuthenticationTicket(
          identity.First(),
         
new AuthenticationProperties
());

    }

}

 

You can then use the token format class with Katana’s built-in OAuth2 bearer authentication middleware like:

public static IAppBuilder UseTokenHandlerAuthentication(this IAppBuilder app, SecurityTokenHandler handler)

{

    var options = new OAuthBearerAuthenticationOptions

    {

        AccessTokenFormat = new WifTokenFormat(handler)

    };

 

    app.UseOAuthBearerAuthentication(options);

 

    return app;

}

 

And since WIF supports SAML 1.1 and SAML 2 out of the box – and with a little syntactic sugar you end up here:

public class Startup

{

    public void Configuration(IAppBuilder app)

    {

        //app.UseSaml11BearerAuthentication(

        //    audience:         new Uri(“urn:testrp”),

        //    issuerThumbprint: “973…5F8”,

        //    issuerName:       “sts”);

 

        app.UseSaml2BearerAuthentication(

            audience: new Uri(“urn:testrp”),

            issuerThumbprint: “973…5F8”,

            issuerName: “sts”);

 

 

        app.UseWebApi(WebApiConfig.Register());

    }

}

 

Which is a Web API that supports SAML 2 (or SAML 1.1) tokens. Of course any other WIF token handler that supports stringified tokens – and also any other OWIN/Katana compatible framework would work as well. QED.

Sample is here.


Filed under: IdentityModel, OWIN, WebAPI
Viewing all 204 articles
Browse latest View live