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
Effective URL: https://leastprivilege.com/
Submission: On June 22 via api from GB — Scanned from GB
Form analysis
3 forms found in the DOMGET 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