leastprivilege.com Open in urlscan Pro
192.0.78.25  Public Scan

Submitted URL: http://leastprivilege.com/
Effective URL: https://leastprivilege.com/
Submission: On June 22 via api from GB — Scanned from GB

Form analysis 3 forms found in the DOM

GET https://leastprivilege.com/

<form role="search" method="get" id="searchform" class="searchform" action="https://leastprivilege.com/">
  <div>
    <label class="screen-reader-text" for="s">Search for:</label>
    <input type="text" value="" name="s" id="s">
    <input type="submit" id="searchsubmit" value="Search">
  </div>
</form>

POST https://subscribe.wordpress.com

<form method="post" action="https://subscribe.wordpress.com" accept-charset="utf-8" style="display: none;">
  <div class="actnbr-follow-count">Join 471 other followers</div>
  <div>
    <input type="email" name="email" placeholder="Enter your email address" class="actnbr-email-field" aria-label="Enter your email address">
  </div>
  <input type="hidden" name="action" value="subscribe">
  <input type="hidden" name="blog_id" value="35985647">
  <input type="hidden" name="source" value="https://leastprivilege.com/">
  <input type="hidden" name="sub-type" value="actionbar-follow">
  <input type="hidden" id="_wpnonce" name="_wpnonce" value="7aa8532694">
  <div class="actnbr-button-wrap">
    <button type="submit" value="Sign me up"> Sign me up </button>
  </div>
</form>

<form id="jp-carousel-comment-form">
  <label for="jp-carousel-comment-form-comment-field" class="screen-reader-text">Write a Comment...</label>
  <textarea name="comment" class="jp-carousel-comment-form-field jp-carousel-comment-form-textarea" id="jp-carousel-comment-form-comment-field" placeholder="Write a Comment..."></textarea>
  <div id="jp-carousel-comment-form-submit-and-info-wrapper">
    <div id="jp-carousel-comment-form-commenting-as">
      <fieldset>
        <label for="jp-carousel-comment-form-email-field">Email (Required)</label>
        <input type="text" name="email" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-email-field">
      </fieldset>
      <fieldset>
        <label for="jp-carousel-comment-form-author-field">Name (Required)</label>
        <input type="text" name="author" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-author-field">
      </fieldset>
      <fieldset>
        <label for="jp-carousel-comment-form-url-field">Website</label>
        <input type="text" name="url" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-url-field">
      </fieldset>
    </div>
    <input type="submit" name="submit" class="jp-carousel-comment-form-button" id="jp-carousel-comment-form-button-submit" value="Post Comment">
  </div>
</form>

Text Content

LEASTPRIVILEGE.COM

Dominick Baier on Identity & Access Control
Skip to content
 * Home
 * Training
 * Open Source
 * Pluralsight
 * Publications
 * Archive
 * About
 * Photography

← Older posts



WHAT’S GOING ON?

Posted on May 21, 2021 by Dominick Baier

I just realized that my last blog post was over half a year ago when we
announced our new company Duende Software.

So what happened in the last 6 months of my life? In short – a ton!

We left our comfort zone and started a new company to be able to improve
IdentityServer and make it a full time business. Of course this involved
learning lots of new things like legal, finance, understanding how software
purchase processes work etc… All things we never were involved with before.

Finding the right pricing structure was another really hard thing to figure out.
We never anticipated that IdentityServer is being used in so many and radically
different scenarios – both self-hosting/SaaS, re-distribution and many ways
in-between.

We had to adjust our pricing a couple of times and we also introduced various
special offers and the community edition in particular.

And, finally we had the chance to focus on the code again! We added a couple of
really good features that were on our backlog for quite some time including:

 * automatic key management
 * support for resource isolation
 * support for the BFF pattern to secure SPAs
 * ability to load authentication handlers dynamically

You can follow progress and planned feature on our issue tracker and repo.

We are mostly done for our 5.x releases and think that .NET 6 will be a very
important release for us and our customers. It is the next version of .NET that
has a long term support – and thus a good platform to run token services and
identity management systems on. We will soon move our main branch to our 6.0
work.

I don’t have high hopes that I will be blogging a lot on my personal blog
anytime soon. I will focus on writing more technical post over on our Duende
blog – and hopefully find the time to do more “meta” posts here at some point.

Once I have fully figured out all the OSS business things in my head, I am sure
I want to write about it ;) I will let you know!

Take care!

Posted in Uncategorized | Leave a comment


THE FUTURE OF IDENTITYSERVER

Posted on October 1, 2020 by Dominick Baier

Tl:dr https://blog.duendesoftware.com/posts/20201001_helloduende/

Brock Allen and I have been working on the IdentityServer code-base for more
than 10 years. In 2020 we will be making some important changes to it. Here’s
why we are doing this.

Our History
The very first version of IdentityServer, which was called StarterSTS, was a
collection of 7 aspx files with embedded code-behind. At the time, the project
was considered a “WebSite Project” (Remember those?) and was hosted on CodePlex.
Though StarterSTS was very simple, thanks to WIF, it was a pretty decent
starting point for implementing WS-Federation and WS-Trust.

StarterSTS was the outcome of reimplementing token service solutions for a
handful of customers and subsequently noticing a pattern in boilerplate and
customer-specific usage. This was around 2009.

A lot has happened since then. I began working with Brock, whom I knew from
teaching for DevelopMentor, and together we created IdentityServer1 and
IdentityServer2. Both were ready-to-use web applications built with WebForms and
then later MVC. Through it all, our basic idea never changed: give people a
starting point for building a security token service. At one point, we attempted
to make certain things configurable from the UI, but we quickly realized that
IdentityServer’s real value was its customizability. Driving everything from a
configuration UI just didn’t work.

Enter IdentityServer3. This is when we made the decision to become a framework.
We realized that C# was the ultimate configuration DSL. At the same time,
ASP.NET had become more modular (with Katana) and IdentityServer became a
middleware/engine for implementing OpenID Connect and OAuth 2-based token
services. We dumped WS-* and focused on modern identity and access control. This
turned out to be a great decision.

At this point, it was apparent to us that OpenID Connect and OAuth were becoming
the standard for building SSO and API access. It was also clear that none of the
off-the-shelf products or SaaS solutions were flexible enough to fulfill many of
our customers’ needs. This is still the case.

IdentityServer4 was a logical progression. Brock and I became better as a team,
ASP.NET became better with ASP.NET Core, and IdentityServer became more useful
and popular.

Today IdentityServer4 is used by thousands of companies and has achieved over 12
million total downloads on Nuget, and has become the de facto standard for
.NET-based token services. In addition, it is used as the token plumbing for
Microsoft’s Angular, React and Blazor templates for ASP.NET Core.

IdentityServer and Open Source
Open sourcing StarterSTS began as a way for me to provide code samples along
with my blog posts. There was no Richard Stallman-esque philosophy behind it.

With the move to Github, the OSS vibe, community, pull requests, and
collaboration began to develop, and it was fun. Still, our main goal was to
promote our work, and that’s why we chose an enterprise-friendly license (first
BSD, then Apache 2).

With IdentityServer becoming more popular, we were able to center all of our
commercial work (e.g. consulting, training, build-outs) around our own
framework. This was a dream come true, and we felt there was a good balance
between open source “giving” and what we got back. But we also realized that
maintaining IdentityServer and the community around it had become an additional
full-time job. An unpaid full-time job at that.

It is well-known that the more popular an OSS project becomes, the harder it is
to manage it. Some OSS project maintainers burn out, while others get offered
jobs where they can continue to maintain the project (or not). Some manage to
make the jump from a hobby project to a real business. This is where we are
now—ready to make a jump.

In the beginning, Brock and I were self-funding IdentityServer solely through
consulting and training jobs. When this didn’t work anymore, we looked for
additional ways to fund the OSS work. First we chose sponsorship.

As Eran Hammer points out in his talk on open source sustainability, sponsorship
turns out to be the least sustainable and least predictable way to support OSS.
We experienced this first hand. This is how well (or poorly) sponsorship worked
for us over a three year period:

 * Over the past three years: $60,000 in total from 75 monthly sponsors.
   * ~$53,000 came from 12 companies
   * ~$7,000 came from 63 individuals.

This breaks down to approximately $9,000 per year for each of us.

Ultimately, we had to agree with Hammer: sponsorship just wasn’t sustainable for
us. Although we are very appreciative of our individual sponsors, we feel the
companies that use and depend on our software should be the ones to sponsor it.
Unfortunately, most companies are not setup for sponsoring open source.

Another option we explored was the “open core” model. Our partners Rock Solid
Knowlege in Europe and Solliance in the US provided added value via add-on
components and custom implementations. While this helps, it still does not cover
the cost of running and maintaining the core project and code-base.

Our Future
After going as far as we could with self-funding and sponsorship, we needed to
find a different way to operate. We asked ourselves what our goals should be
going forward and developed a list of the top five:

 * Spend more time on the IdentityServer code-base to implement features and new
   protocols.
 * Create better documentation and samples.
 * Do a better job of supporting the people who use IdentityServer.
 * Give companies the assurances they need when they decide to base their core
   identity infrastructure on our code.
 * Implement a business continuity plan.

To reach these goals we decided to finally bite the bullet and start a real
company.

The current version (IdentityServer4 v4.x) will be the last version we work on
as free open source. We will keep supporting IdentityServer4 until the end of
life of .NET Core 3.1 in November 2022.

To continue our work, we have formed a new company Duende Software, and
IdentityServer4 will be rebranded as Duende IdentityServer. Duende
IdentityServer will contain all new feature work and will target .NET Core 3.1
and .NET 5 (and all versions beyond).

This new product will remain open source but will be offered with a dual license
(RPL and commercial). The RPL (reciprocal public license) keeps Duende
IdentityServer free if you are also doing free open source work. If you are
using Duende IdentityServer in a commercial scenario, then a commercial license
will be required. We offer a variety of ways to license Duende IdentityServer in
an attempt to accommodate the different company sizes and usage models.
Including an RPL license is important to us because it allows us to recognize
and express our gratitude to the open source community and our contributors.

Our partner, Rock Solid Knowledge, will continue to offer commercial add-ons to
Duende IdentityServer (e.g. AdminUI, SAML, FIDO2) as well as custom development
and production support. In addition, Solliance remains our North American
partner for consulting and custom development.

We feel that these changes will best serve the needs of both our open source
community and our corporate community. In addition, they will allow us to make
sure Duende IdentityServer will be a viable long-term solution for everyone.

Last but not least, we have great features in the pipeline and Duende
IdentityServer will continue to be the most flexible, advanced and modern
identity solution for .NET.

If you have questions and want to contact us, or just want more info you can
visit us at https://duendesoftware.com. Also, there is a company blog and
twitter account.

Posted in IdentityServer | 97 Comments


FLEXIBLE ACCESS TOKEN VALIDATION IN ASP.NET CORE

Posted on July 6, 2020 by Dominick Baier

The ASP.NET Core authentication system went through a couple of iterations, and
is pretty good now. For API scenarios, the typical choice is the JwtBearer
authentication handler, which can validate bearer JWT access tokens.

There are other access token types that you might want to use, e.g. reference
tokens that get validated via introspection. ASP.NET Core does not include an
authentication handler for that, but we have one.

In fact, some people decide that certain (risky/public) clients should use
reference token (for revocability), whereas others should use JWTs. This was
historically not easy to achieve in ASP.NET Core, because the authentication
system wasn’t designed for multiple handlers for the same credential type.

I opened an issue describing the problem a long time ago, which was moved to
different backlogs and then ultimately closed with wontfix.

There are a couple of ways to solve the problem – e.g. register two
authentication handler, e.g. JwtBearer and the OAuth introspection handler. Give
them distinct scheme names, and then create an authorization policy that invokes
both.

1
2
3
4
5
6
services.AddAuthorization(options =>
{
    options.AddPolicy("tokens", p =>
        p.AddAuthenticationSchemes("jwt", "introspection"));
        p.RequireAuthenticatedUser();
});

Since this invokes both handlers, one would possibly fail, one possibly succeed.
This is overhead, especially since the introspection handler will do an outbound
network call. So not recommended.

To solve the problem, we created a brand new authentication handler that acts
like a decorator over the JWT and introspection handler. When a token comes in,
it looks at its shape, invokes some advanced machine learning that checks
whether the token contains a dot – and if yes – it must be a JWT. It then
internally dispatches to the JWT handler, otherwise to the introspection
handler.

While this works – it has quite a bit of complexity (inspect the source code,
it’s not pretty). There are other shortcomings:

 * Our handler needs a unified options object that wraps the options of the
   individual handler under the covers. While, again this works for most parts,
   you can be sure that there is someone out there that that needs some setting
   (or event) of some handler, that was not surfaced by our configuration.
 * It really only works for the two specific handlers we decided to wrap. What
   if you want to bring another handler to the mix?
 * Having dependencies on the handlers makes versioning harder.
 * More code to maintain.

Going forward, we decided that we do not want to maintain this “hack” any
longer. There must be a better way. Enter policy schemes.

Policy scheme were added a while ago (I forget the exact version of ASP.NET
Core). Think of them as virtual schemes. They don’t really do anything besides
forwarding the various security gestures to other schemes. And while doing that,
giving you enough flexibility to decide at runtime which other scheme that would
be. Sounds like exactly what we need.

In essence you are providing a function that inspects the current HTTP Request,
and returns the scheme name of a handler to forward the request to:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static string SchemeSelector(HttpContext context)
{
    var (scheme, token) = GetSchemeAndCredential(context);
 
    if (!string.Equals(scheme, "Bearer", StringComparison.OrdinalIgnoreCase))
    {
        return null;
    }
     
    if (token.Contains("."))
    {
        return "Jwt";
    }
    else
    {
        return "Introspection";
    }
}

You would then wire up a policy scheme to the authentication builder to invoke
that function.

1
2
3
4
5
builder.AddPolicyScheme("token", "token", policySchemeOptions =>
{
    policySchemeOptions.ForwardDefaultSelector = context =>
        SchemeSelector(context) ?? DefaultScheme;
});

With this feature, I planned for quite some time already to deprecate our
dedicated handler and replace it with a policy scheme. While prototyping, Brock
pointed me into a direction for an even simple solution.

It turns out that every authentication handler is capable of selectively
forwarding requests to another handler. IOW – simply extend your default handler
with some forwarding logic to be able to handle more token types:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
services.AddAuthentication("token")
 
    // JWT tokens (default scheme)
    .AddJwtBearer("token", options =>
    {
        options.Authority = Constants.Authority;
        options.Audience = "resource1";
 
        options.TokenValidationParameters.ValidTypes = new[] { "at+jwt" };
 
        // if token does not contain a dot, it is a reference token
        options.ForwardDefaultSelector =
Selector.ForwardReferenceToken("introspection");
    })
 
    // reference tokens
    .AddOAuth2Introspection("introspection", options =>
    {
        options.Authority = Constants.Authority;
 
        options.ClientId = "resource1";
        options.ClientSecret = "secret";
    });

The Selector.ForwardReferenceToken is a little helper that I packaged up in the
IdentityModel.AspNetCore.AccessTokenValidation nuget package.

Even when you are not using reference tokens, this is a useful technique for
dynamically changing the handler at runtime.

This alone doesn’t really justify maintaining another nuget package, so we threw
in two other small helpers that come in useful.

The first addition is a shortcut to create a scope-based authorization policy,
e.g.:

1
2
3
4
services.AddAuthorization(options =>
{
    options.AddScopePolicy("admin", "scope1");
}

…and the other is a way to normalize incoming scope claims. This is useful if
your token service uses the new JWT profile for access tokens, where the scope
claim is a space delimited string. This does not play nicely with .NET claims,
hence we included a little claim transformer, that turns that string into
individual claims:

1
services.AddScopeTransformation();

HTH

Posted in ASP.NET Core, OAuth | 6 Comments


REFRESH TOKENS IN IDENTITYSERVER4 V4

Posted on June 29, 2020 by Dominick Baier

I already wrote about the hardening of refresh tokens in this post. I would
recommend reading this first.

The upcoming OAuth 2.1 spec is pretty clear about refresh token handling:

 * If the client is confidential, the refresh token must be bound to the client
   via the client secret.
 * If the client is public, the refresh token must be rotated.

We have always supported client-binding, rotation and also sliding expiration,
but we made a couple of changes in v4 to make customization of refresh token
handling easier.

First of all we consolidated all refresh token related code in a single
extensible place – the IRefreshTokenService with a default implementation called
DefaultRefreshTokenService.

Next, we don’t delete consumed refresh tokens anymore from the database. Instead
we record the consumed time. This allows for auditing as well as custom handling
of refresh token replays of rotated tokens.

The reason you need to be able to implement custom policies is, that receiving a
rotated refresh token more than once, is not necessarily always an attack.
Faulty client logic like race conditions could be a reason for that, also
unstable network connectivity could be the cause.

Depending on your system you might want to tweak the behavior, e.g. implementing
a grace period to accomodate network failures, or you might also want to take
additional steps if you see a refresh token replay, e.g. revoking other tokens
or send notifications.

All of this is now easily possible – check the updated docs.

Posted in IdentityServer, OAuth | 3 Comments


ANNOUNCING IDENTITYSERVER4 V4.0

Posted on June 19, 2020 by Dominick Baier

OK – it’s finally done. I published v4 to Nuget earlier today. You can find the
complete set of changes/bug fixes/breaking changes here.

We had to cut some features which were originally on our roadmap – we’ll revisit
them for the next release, which is planned for end of this year.

Let’s have a look at the big new features that we added for this release.

Updates to the Mutual TLS support
MTLS is an important enabler for strong client authentication and
proof-of-possession access tokens. We added support for more flexible MTLS
endpoint hosting and emitting the cnf claim for ephemeral (or session) X.509
certificates. See this post and docs here.

Private key JWT authentication and JWT secured Authorization requests (JAR)
These both features often go together because they allow authentication of
clients on both front- and back-channel using asymmetric keys.

New features include support for JWK formatted key material, updated validation
checks to conform with JAR and replay cache support. See this post, docs here.

Conformance with the JWT Profile for OAuth Access Tokens
See this post for more information.

Re-worked API resource and scope handling/validation
See this post for more information.

Updated handling around Refresh Tokens
We consolidated all handling into a single place now, and added support to
implement custom replay detection and revocation logic. See this post.


Support for multiple signing Keys and Algorithms
This allows configuring the signing algorithm and thus the key used per client
and API resource. See post here.

More features around Session Management and Back-channel Logout Notifications
Going forward, back-channel logout notifications is the only mechanism that will
work reliably across domain boundaries. That’s why we polished the feature to be
more flexible. Docs soon.

Please give it a try! Have fun!

PS. Our friends from RSK are planning to publish a database migration script. I
will let you know once it is available.

Posted in IdentityServer | 2 Comments


RESOURCE ACCESS IN IDENTITYSERVER4 V4 AND GOING FORWARD

Posted on June 18, 2020 by Dominick Baier

In my last post I alluded to the tension between real-world token-based security
architectures, the OAuth 2.0 scope model, JWT access tokens and the audience
claim.

We went through a couple of iterations in IdentityServer how we deal with those
concepts.

IdentityServer3
By that time OAuth/OIDC and the usage of JWTs was very new, so everybody made
their own sense of these technologies – especially how they are supposed to work
together.

We decided that the audience claim in JWTs doesn’t really map to OAuth and its
scope concept, so we didn’t really use the aud claim. Instead we emitted the
granted scopes in the scope claim.

Mostly to make JWT libraries happy, we also emitted a static aud claim. The
format was issuer_name/resources and was a way in APIs to make sure that this is
an access token coming from a certain issuer.

IdentityServer4 v1-v3
In IdentityServer4 we introduced the ApiResource abstraction to make it easier
to structure the API surface. In our configuration model, you could add named
APIs that could act as a container for scopes and other settings. If an API
resource did not define an explicit scope, we added one under the covers with
the same name as the API.

We continued to emit the granted scopes in the scope claim, but also started
emitting the API names as the aud claim. We also made the static aud claim
optional.

This led to many scenarios where the aud and scope claims were identical, and it
felt wrong to force everyone into the resource abstraction – and certainly
against the original spirit of OAuth.

IdentityServer4 v4
With the advent of the resource indicator spec, we finally have a more
formalized way how resources relate to scopes – and this is also a perfect match
for our resource configuration model.

But at the same time, we’ve done a lot of consulting for very different types of
OAuth-based installation over the last years to know, that not everyone needs
the resource concept.

That’s why we decided to give you more control – you can either model scopes as
a flat list, or hierarchical. Which means you can go from a very simple model
like read/write/update scopes to very complex namespaced resource/scope
combinations. Also sharing scopes between resources is now possible as well.

We made the aud claim optional again (for a scopes only model) – or static – or
based on the requested resource. It’s up to you now.

While we were at it, we also enabled easy support for parameterized scopes like
e.g. transaction:id since they are used for some recent APIs specs like FAPI of
FHIR.

These changes will require some minor migration steps when upgrading to v4, but
allows for more flexibility.

Also, the work we did is foundational for the next step in IdentityServer’s
resource access story, which is supporting resource isolation – or IOW resource
indicators. This will ship in the next major update – which will be around end
of this year, so stay tuned.

I wrote up the conceptional bits in our updated docs. Please give it a try!

Posted in IdentityServer, OAuth | 4 Comments


I DON’T LIKE IDENTITY TOKENS

Posted on June 17, 2020 by Dominick Baier

…or rather the name ;)

I bet that if you wake up most “identity professionals” in the middle of the
night and ask them what an identity token is, the answer would be “a token about
the identity of the user”.

This is not wrong – but it is definitely not the rightest answer.

In OIDC, the token service needs to send data about “what happened during
authentication” back to the client applications, e.g. authentication method,
authentication time, some protocol information and a unique identifier for the
user that was authenticated. And – yes this might also include other identity
information about the user, but this is optional.

This data must be sent in a format that is both tamper proof and that allows the
client to authenticate the issuer. In OIDC this format is JSON – and the way how
you add the above security properties to a JSON object is by wrapping it in a
JWT (along with JWS, JWA and JWK) – hence the name identity token. I would
prefer “authentication response” instead – because that’s exactly what it is.

Also, some people are confused and think you can also use the identity token to
act like an “access token”, which is wrong. Not using the word “token” at all,
would be much clearer.

Posted in OpenID Connect | Leave a comment


THE JWT PROFILE FOR OAUTH 2.0 ACCESS TOKENS (AND IDENTITYSERVER)

Posted on June 15, 2020 by Dominick Baier

As part of creating our new Advanced OAuth training, I created a whole lecture
on the evolution of access tokens and resource access.

It’s fascinating – since the original OAuth 2.0 spec does not have any
information about the token format, content or semantics – everybody kind of
made up something that works for them (including us).

As you can see on the timeline, JWTs were not even a thing when OAuth 2.0 was
released, and to be honest, also the JWT spec is just a framework for how a JWT
might look like, and is not always the best natural match for OAuth semantics.

Still JWTs won because simplicity, and if you look at various vendors’ JWT
format, you can see different interpretations of how OAuth might map to it.

Fast forwarding to 2020, our good friend Vittorio made an effort of trying to
formalize JWTs for OAuth and has been working on an official profile. There have
been discussions going back and forth, we are not always in agreement, but
nevertheless the document will be released soon-ish.

Let’s have a look at the proposed JWT format, and how IdentityServer conforms to
it.

Header
One of the best features of the spec IMO is the introduction of a type header.
This allows resource server to make sure they actually deal with an access
token. The value is at+jwt and we support this for a while now – I wrote about
it here.

iss (issuer) and exp (expiration) claim
These are pretty much no brainers and have been supported in IdentityServer
since ever.

client_id claim
Represents the client ID of the OAuth client. Present since day 1 in
IdentityServer.

jti (JWT identifier) claim
A unique identifier for the token. Allows implementing replay detection. This is
a per-client setting in IdentityServer, but we changed the default value to emit
jti in v4.

scope claim
If the scope request parameter is used, the access token should contain the
granted scopes as a claim. Makes total sense, but there might be some variations
with the actual format. The spec says it must be a space delimited list.
IdentityServer has historically been using a string array for that, because it
played nicer with the .NET claims infrastructure.

As of v4 you can switch from the array format to the string format by setting
the EmitScopesAsSpaceDelimitedStringInJwt option – be aware that this will
probably break existing consumers.

aud (audience) claim
This is a more complicated story – but to make it short: pure OAuth has no
concept of an audience. The closest thing is the scope parameter, which is
spectacularly under-defined and more abstract. IOW – everyone came up with their
own interpretation of that.

In IdentityServer3 we emitted a static audience claim, and we changed that in
IdentityServer4 to use the name of the request API resource(s). We were not
happy with both approaches.

In the new v4 we give you more control – you can set a static audience; you can
omit the audience altogether – or you can use the API resource name (and this
will become even more interesting when you mix in resource indicators). I have a
more detailed post in the making to discuss the various options and will post it
soon.

The JWT profile spec makes aud mandatory and I don’t fully agree with this
decision. Either way, IdentityServer conforms to it, if you want to.

iat (issued_at) claim
The profile favours iat over nbf. The practical intent is similar enough. The
.NET library prefers nbf historically and will emit both now in v4.

sub (subject identifier) claim
This is the really big elephant in the room.

Since we designed IdentityServer to be an OpenID Connect and OAuth 2.0 system
(strong emphasis on the ‘and’) – we decided to use the OIDC definition of the
sub claim for both identity and access tokens. The main motivation was to make
it very explicit to every token consumer: the sub claim represents the unique
identifier of an end-user. This also meant that, when no sub claim is present,
there is no user involved – which e.g. would apply to a pure machine to machine
communication.

This is where the JWT profile differs. It gives the sub claim a dual semantic.
If an end-user is involved, the sub claim uses the OIDC definition (aka the user
ID). If no end-user is involved, the sub claim represents the client ID of the
OAuth client.

I personally (and tbh none of our customers) don’t like that ambiguity and the
best explanation I have is, that this unifies the sub claim to be the target of
authorization rules in the consumer (either a user or a client). But this is
only what I came up with, to make a little bit more sense out of that. I had
situations where this was actually useful – but I prefer the freedom to decide
how I want to model that. The profile does not motivate this besides: sub is
mandatory (which btw is not true according to the JWT specification).

In IdentityServer we always supported emitting static claims per client, so you
can easily emit a static sub claim, and e.g. make that the same value as
client_id.

Other claims
The profile allows for other (user-centric) claims, e.g. auth_time, amr or acr.
Again, this has always been the case in IdentityServer, and makes total sense.

Summary
It’s a lot of work to write and discuss a new specification – so thanks Vittorio
for taking on that task. The main goal of the profile is to give us a common
language when talking about access token content and semantics – and to help
with interop.

Given the type of changes we had to make to IdentityServer to conform with it
(and I suppose we are one of the more agile OAuth implementations), I doubt if
(or when) the major vendors will switch to this format. But still it is a useful
start.

My final comment would be that I would prefer the profile to make the aud and
sub claims optional, because I just don’t agree with the conclusions made here.
But that’s just my personal opinion. We made sure that you can be compliant in
IdentityServer, if you want to.

Posted in IdentityServer, OAuth, OpenID Connect | Leave a comment


UPDATES ON OUR WORKSHOPS

Posted on May 22, 2020 by Dominick Baier

I am pleased to announce that we are now offering two workshops. I was
mentioning that on Twitter already, and got a lot of questions. So I thought it
would make sense to summarise them all in one place.

You can find descriptions for both workshops on our training page:
https://identityserver.io/training/

Identity & Access Control for modern Applications using ASP.NET Core
This is our flagship training that we are running now for many years.

This workshop is an introduction to modern security architecture, OpenID Connect
and OAuth 2.0 from the perspective of an ASP.NET Core developer or architect.

When you start building applications using token-based security, there are a lot
of moving parts around the protocols and the concrete APIs of your application
framework – and you also have to put these blocks together to create meaningful
architectures. That’s what this workshop is all about.

The workshop is always very well attended and very often the biggest workshop
when run at conferences. This tells us that there is definitely a need for this
type of content. We keep evolving it constantly to keep up with ASP.NET Core
changes and the industry best practices.

See here for a detailed agenda and watch this video for a sneak peak into some
of the topics we cover in this two or three day workshop.

We run this workshop either as in-house versions or open enrolments. Either
contact us to discuss an in-house version, or check our page for upcoming open
enrolments.

Advanced OAuth
This is our new 1-day course covering all the new specs and everything you need
to know to create high security OAuth architectures.

We’ve been involved for the last couple of years implementing OpenID Connect and
OAuth in the health sector in Norway. As you can imagine this is subject to many
strict laws and regulations. Other highly regulated industries like finance and
e-gov had similar pushes, and this resulted in various “higher security”
profiles for OAuth and OpenID Connect.

Though pioneered in these high security environments, the specs and guidance is
now being consolidated and make their way into “normal” applications that need
more security than plain RFC 6749 has to offer.

This workshop starts, where our introduction workshop ends and talks about the
latest specs and best practices for securing OAuth and adding additional
features like stronger authentication of front- and back-channels,
proof-of-possession, sender and audience constraints and much more.

This course is currently only offered for in-house/remote deliveries. If you are
a company and are interested in this contact, please contact us. We are thinking
about running open-enrolments later this year – so if you are an individual,
please also contact us, so we can get a better feeling for the demand.

Here’s the overview page for this training, and here you can find a recent
recording covering an excerpt of the security best practices content.

Hopefully see you soon in some training room around the world – virtual or
in-person!

Posted in OAuth, OpenID Connect | Leave a comment


AUTOMATIC TOKEN MANAGEMENT FOR ASP.NET CORE AND WORKER SERVICES 1.0

Posted on May 18, 2020 by Dominick Baier

After a pretty long preview period, I am happy to announce that
IdentityModel.AspNetCore 1.0 is now on Nuget.

This library solves a problem that we have with every single OIDC/OAuth client
we are creating: token management.

Requesting and using a token is the easy part – managing the token and its
lifetime is the hard part. But also boilerplate.

The library helps with access token lifetime management for pure machine to
machine communication and user-centric applications with refresh tokens.
For user-centric it provides:
 * storage abstraction for access and refresh tokens (default implementation
   using the ASP.NET Core authentication session)
 * automatic refresh of expired access tokens
 * refresh token revocation
 * token lifetime automation for HttpClient

For worker services it provides:
 * caching abstraction for access tokens (default implementation using
   IDistributedCache)
 * automatic renewal of expired access tokens
 * token lifetime automation for HttpClient

I’ve been holding back with releasing, because I wanted to get some feedback
from more people and customers, and I also wanted to make sure it is ready for
all of the advanced scenarios I am using for our new Advanced OAuth workshop.


 

Best part – it also has docs. See here for workers, see here for web
applications – and here for some more info on plugging in your own configuration
and storage abstractions.

HTH
Posted in .NET Security, ASP.NET Core, IdentityServer, OAuth, OpenID Connect | 1
Comment
← Older posts

 * Search for:


 * RECENT POSTS
   
   * What’s going on?
   * The Future of IdentityServer
   * Flexible Access Token Validation in ASP.NET Core
   * Refresh Tokens in IdentityServer4 v4
   * Announcing IdentityServer4 v4.0


 * CATEGORIES
   
   * .NET Security (95)
   * ASP.NET (163)
   * ASP.NET Core (27)
   * AuthorizationServer (33)
   * Azure (29)
   * Conferences & Training (40)
   * IdentityModel (347)
   * IdentityServer (205)
   * Katana (46)
   * OAuth (163)
   * OpenID Connect (94)
   * OWIN (45)
   * Photography (14)
   * PolicyServer (3)
   * Resources (1)
   * Uncategorized (625)
   * WCF (109)
   * WebAPI (223)


 * TWEETS
   
   * RT @DuendeIdentity: Feature spotlight: Automatic key management
     blog.duendesoftware.com/posts/20201028… 1 day ago
   * RT @Aaronontheweb: As Dominick points out, the process breaks down in step
     3. Some of that is on maintainers (donations are very weaksauce… 1 day ago


 * FEED
   
    RSS - Posts
   
    RSS - Comments


 * ARCHIVES
   
   * May 2021
   * October 2020
   * July 2020
   * June 2020
   * May 2020
   * April 2020
   * March 2020
   * February 2020
   * January 2020
   * September 2019
   * August 2019
   * July 2019
   * June 2019
   * April 2019
   * February 2019
   * January 2019
   * December 2018
   * July 2018
   * June 2018
   * May 2018
   * February 2018
   * January 2018
   * December 2017
   * November 2017
   * October 2017
   * August 2017
   * July 2017
   * May 2017
   * April 2017
   * March 2017
   * February 2017
   * January 2017
   * December 2016
   * October 2016
   * September 2016
   * August 2016
   * July 2016
   * June 2016
   * May 2016
   * February 2016
   * January 2016
   * December 2015
   * November 2015
   * October 2015
   * September 2015
   * July 2015
   * June 2015
   * May 2015
   * April 2015
   * March 2015
   * February 2015
   * January 2015
   * December 2014
   * November 2014
   * October 2014
   * September 2014
   * August 2014
   * July 2014
   * June 2014
   * May 2014
   * April 2014
   * March 2014
   * February 2014
   * January 2014
   * December 2013
   * November 2013
   * October 2013
   * September 2013
   * August 2013
   * July 2013
   * June 2013
   * May 2013
   * April 2013
   * March 2013
   * February 2013
   * January 2013
   * December 2012
   * November 2012
   * October 2012
   * September 2012
   * August 2012
   * July 2012
   * June 2012
   * May 2012
   * April 2012
   * March 2012
   * February 2012
   * January 2012
   * December 2011
   * November 2011
   * October 2011
   * September 2011
   * July 2011
   * June 2011
   * May 2011
   * April 2011
   * March 2011
   * February 2011
   * January 2011
   * December 2010
   * November 2010
   * October 2010
   * September 2010
   * August 2010
   * July 2010
   * June 2010
   * May 2010
   * April 2010
   * March 2010
   * February 2010
   * December 2009
   * November 2009
   * October 2009
   * September 2009
   * August 2009
   * July 2009
   * June 2009
   * May 2009
   * April 2009
   * March 2009
   * February 2009
   * January 2009
   * December 2008
   * November 2008
   * October 2008
   * September 2008
   * August 2008
   * July 2008
   * June 2008
   * May 2008
   * April 2008
   * March 2008
   * February 2008
   * January 2008
   * December 2007
   * November 2007
   * October 2007
   * September 2007
   * August 2007
   * July 2007
   * June 2007
   * May 2007
   * April 2007
   * March 2007
   * February 2007
   * January 2007
   * December 2006
   * November 2006
   * October 2006
   * September 2006
   * August 2006
   * July 2006
   * June 2006
   * May 2006
   * April 2006
   * March 2006
   * February 2006
   * January 2006
   * December 2005
   * November 2005
   * October 2005
   * September 2005
   * August 2005
   * July 2005
   * June 2005
   * May 2005
   * April 2005
   * March 2005
   * February 2005
   * January 2005
   * December 2004
   * November 2004
   * October 2004
   * September 2004
   * August 2004
   * July 2004
   * June 2004
   * May 2004

leastprivilege.com
Blog at WordPress.com.

leastprivilege.com
Blog at WordPress.com.
 * Follow Following
    * leastprivilege.com
      Join 471 other followers
      
      Sign me up
    * Already have a WordPress.com account? Log in now.

 *  * leastprivilege.com
    * Customize
    * Follow Following
    * Sign up
    * Log in
    * Report this content
    * View site in Reader
    * Manage subscriptions
    * Collapse this bar

 

Loading Comments...

 

Write a Comment...
Email (Required) Name (Required) Website