Replacing Claim in a token without authenitcation - identityserver4

My application connects to different databases based on the choice of the user at login.
At the time of login user is asked for the division and I found the way to include that division id in the token by using the object parameter named extra on tokenClient.RequestResourceOwnerPasswordAsync method.
Now if the user changes the division I want to replace the division id in token to the new division without asking the user their credentials again.
Its just a change of one claim in the token.
In Essence once the token is being created, is there any way to replace a claim in the token without asking for user credentials again?
Is this possible using extension grants? If not then what is the recommended solution?
Thanks in advance.
Noufal

Related

identityServer4 with Login Step-up and MFA

In one of my Projects i need to implement Login Step-up. That means a user can login an application with simple username and password to get some readonly access access on website and API behind it.
If user want to performan any sensetive data operations like "write/update", he need to authenticate via second factor (via SMS code).
second factor login is for maximum 10 minutes valid, if user does not interect the website for 10 minuets, he will be automatically logout from second factor, but he still remain logged in with one factor.
can identityserver4 support this szenario out of the box? or do i need to implement it by my own ?
Here is my solution proposal:
for one factor login, identityserver provide a one factor scope, which client need to understand. it provide a access token which also have limited scope.
when client application need two factor scope, it call identityserver again where user must provide second factor authentication. hence a new token with second factor scope sent back to client. with this token client can call API methodes which need second factor authentication.
second factor authentication token has a validity of 10 minutes
after 10 min token is invalid, but one factor token is still valid as it has long life time.
Questions:
- Can IdentityServer4 offer Login Step-up out-of-box? if no, what are the alternative solutions ?
what is your suggesstion regarding my solution proposal?
Thanks in Advance
What you wrote in the bullet points is basically how I'd see it implemented in IdentityServer4. It's just setting up two different scopes and issuing two separate tokens for the same user. First scope 'readonly', lifetime=24h, acceptable only by safe operations in the application api, second scope 'full' with lifetime=10mins acceptable by all operations. No big problem, it should be perfectly doable with basic IdentityServer4. However, you will have to RT(F)M and configure the scopes, clients, tokens, etc. in the IdentityServer4 config. And also, you'll have to implement the two-token access policies in your app's backend api implementation, and of course client apps will have to be careful about which token they obtain and which token they use for which backend call.. but all of that is more-or-less obvious (and you seem to understand that, judging from that bullet points) so I don't quite see what you'd want by saying "out of the box" or what are you worried about in terms of support for that on the IdentityServer4 side..

Verify that a user can only query his own data/information

o/
I'm working on a smaller app, and its going pretty well so far. I talked with a friend about it and he suddenly made me realize something. How do i make sure a user is only able to query his own data from a Database in the cloud?
Its a very simple app, where you can create a user and make some personal shopping lists.
I thought about a couple of options, but I'm not sure what is the right direction to take - or even if any of them is the right one.
The username/id & password is stored locally and appended to the request, and checked against the DB every time.
A token is generated, saved both in the DB & stored locally as a "active" session, and every time a request is send, the token is appended to the request and checked.
...?
I'm sorry if i placed this topic have the wrong tags, since i was not 100% sure where they should be placed.
Well, from your description it seams that you are working on a "no backend" app. If it is the case I suggest you to take a look to Firebase since it will solve all your concerns about authentication and user authorization.
If your would like to use a more custom approach, simply consider that appending the username and a passowrd to a request is always not recommended and since you are using a token is also unnecessary.
Now, returning to the question, i will give you my vision related to contexts where an authentication token is used and thus a backend is needed:
when you log-in a user, you produce a token that is function of the user id
each user request must contain that token
the backend can extract the id of the user that submitted the request from the appended token
a policy or a specific condition will check that data that is going to be retrieved must belong to the user whose id has been extracted.
Hope this could help you

Enabling multiple tenants using OWIN Active Directory bearer tokens

I've recently started playing with Azure Active Directory to authenticate users against my website built on AngularJS.
Using blogs and sample code on GitHub, I've gotten it working with single-tenant using a combination of ADAL.js and Katana's Bearer Token AD integration.
However, I'm now running into some issues with supporting multiple tenants.
I've got a page set up that displays the user as ADAL sees them (found through the root scope's userInfo), as well as makes a call to my server that gets picked up by OWIN, and serializes context.Authentication.User.
Client-side, everything seems to be working properly. I can log in with any of my tenants, and it gives me the object I'd expect (with isAuthenticated: true, username populated, and all sorts of properties on profile describing the user, login, and tenant).
This is accomplished client-side by leaving off the tenant argument to my adalAuthenticationServiceProvider.init call, as described in the documentation.
Server-side, however, the UseWindowsAzureActiveDirectoryBearerAuthentication method doesn't like having no value for Tenant (in that it throws an exception). I've tried a few values for this, including the tenant with which my app was originally registered and, my logical favorite, "common," but no matter what I put in there (unless it's the tenant I'm trying to log in with, and if my ADAL is set up with that tenant), it seems to just skip over this.
For what it's worth, an actual API call is failing on the [Authorize] filter and returning a 401, which tells me this isn't an issue with my OWIN interceptor.
How can I tell UseWindowsAzureActiveDirectoryBearerAuthentication to support multi-tenant authentication?
I figured this out while writing the question. I think. But I spent all day on this finding almost no documentation on the matter, so I figured I'd post it anyway.
My solution (found through yet another blog post) was to include ValidateIssuer = false as a parameter. This makes sense, since we no longer want to validate that the tenant giving us a token is the one that we've listed.
Here's my code that solved the problem.
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
TokenValidationParameters = new TokenValidationParameters
{
ValidAudience = ConfigurationManager.AppSettings["ida:Audience"],
ValidateIssuer = false // This line made it work
},
AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
Tenant = "common" // I don't know whether this has any impact,
// but it's a required parameter regardless.
});
I'd love if someone else wanted to correct me if this has any unforeseen circumstances--it's a tad daunting flipping a "validate" switch to off when you're working on authentication. But I think this all makes enough sense.
When you are developing a multi tenant application, you can no longer rely 100% on the default authentication logic. The default authentication logic assumes that you declare the azure AD tenant form where you want to receive tokens, and will enforce than only tokens form that tenant are accepted. This is done by examining the metadata document associated to every tenant, which contains (among other things) the identifier of the tenant itself - that identifier must be present in the token you receive, in the iss claim: any other value means that the token comes form another tenant, hence it must be rejected.
By definition, multitenant applications must accept tokens from multiple tenants. This is done by using a parametric endpoint (the common endpoint, see this post) which allows you to "late bind" which tenant will be used to issue a token. However the common endpoint will serve a generic metadata document, which cannot contain a specific iss value: instead, it contains a placeholder that at runtime will always be substituted with the issuer identifier of the tenant you actually got the token from.
This means that in multitenant apps you have to take over the tenant validation logic. If you are just debugging you can turn it off, as you appear to have done - that will prevent the default issuer validation logic from kicking in and refusing the incoming token because its iss value does not correspond to the placeholder found for common. In more realistic cases, however, you will write your own logic in the TokenValidationParameters.IssuerValidator delegate. For example, you might want to compare the iss value in the incoming token against a list of tenants that bought a monthly subscription to your service. HTH

Azure B2C Issues and Questions

I've been working with the Azure B2C for a couple of days now and have a few issues and questions:
Url that it creates to redirect for login is formed incorrectly. It contains a question mark twice - after the url, and again after the profile name. This causes a 404 not found error every time you login, log out, etc. For example, the URL it tries to redirect to for login looks like this: https://login.microsoftonline.com/samlmanbc.onmicrosoft.com/oauth2/v2.0/authorize?p=b2c_1_firstdemoprofile?client_id=08fcblahblah. You'll notice a second question mark after the profile name, and that's what breaks it.
If I fix that and try and log in, it doesn't recognize the username / password of my account that's a global admin. It DOES recognize the username / password of a new user I created locally in the directory.
In the OnRedirectToIdentityProvider method, when the request type is authentication, the AuthenticationResponseChallenge is null, which makes this call fail:
OpenIdConnectConfiguration config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None, notification.OwinContext.Authentication.AuthenticationResponseChallenge.Properties.Dictionary[Startup.PolicyKey]);
I worked around this by using the static string SignInPolicyId for the second parameter. That works fine when an account already exists, but if it doesn't then Azure fails at login and says an account doesn't exist for the user. So what is the right value to use there, and/or how does one initialize it so it isn't null?
The type of a claim that was added to a profile is preceded with "extension_"; is that always going to be true or just for now? For example, I added a property called "favoriteTeam", but the claim type for it is "extension_favoriteTeam".
When you use FaceBook as an identity provider, is there any way to pass along the Facebook access token claim (http://www.facebook.com/claims/AccessToken)? This was useful when using ACS with Facebook because your app can then use that token to make additional calls to Facebook to get data from it.
In relation to issue 1 - I updated my reference Microsoft.IdentityModel.Protocol.Extensions to v1.0.2.206221351 and it started working. I made some updates to other references before this, so if the first one doesn't work, try updating more assemblies from nuget.
This is as expected. A page that signs in "local account" users will not sign in your work or school account (in this case, the global admin user).
Always going to be true. We will be cleaning up the Admin UX to make this more clear.
This is on our roadmap. No ETA as yet.

Two login pages with CakePHP

I have an app that requires login for users. However, to keep matters simple, we are only supplying the user with a unique code, so that they just enter the code and that code logs them in. This code is only valid for two weeks, and will never be repeated.
However, our Admin also needs to log in but the admin requires a username and password.
How will I modify the AppController to allow for both logins? I'm using the AclExtras plugin for Authentication
The one login is located under APP/Users/enter (for the users), the other is under APP/Users/login (for the admins)
Implement a custom Auth adapter that checks for the token. No need to have a separate action except you explicitly want that.
Cake is iterating over all loaded auth adapters so you can have username and password and the token in the same form. If the regular form adapter returns false but the token auth adapter true the user is logged in.
Check the books section about auth. It has all information you need to understand what needs to be done.
You can just make a simple if/else in your AppController checking if the field for unique code is passed, if not then you can implement login with username/password. In all other cases you can implement login by unique code.

Resources