Developer forum

Forum » Development » Use of UseFixedSecret gives 400 Badrequest

Use of UseFixedSecret gives 400 Badrequest

Anders Ebdrup
Reply

Hi DynamicWeb,

 

We experience that using the globalsetting: "/Globalsettings/Modules/Users/Jwt/UseFixedSecret" results in a 400 Badrequest when calling webapi methods marked with [PermissionFilter], where the Bearer-token is generated by this method: Dynamicweb.Frontend.Classic.Api.Controllers.JwtService.GetToken(Pageview.User, 3600).

Can you please try to look into that?

 

Best regards, Anders


Replies

 
Morten Bengtson Dynamicweb Employee
Morten Bengtson
Reply

Hi Anders,

A 400 bad request error would usually occur if...

1. The "Authorization" header is empty or the value cannot be parsed (scheme, parameter).
2. The user cannot be resolved from the provided token. This is done internally by calling JwtService.GetPrincipal(token) which parses the token, tries to lookup the user and then generates a claims principle from that user.
3. The user doesn't have the required permissions to the requested resource, e.g. making a GET request for something where the user doesn't have the required Read permission.

If the issue only occurs for endpoints with PermissionFilter then 3 is probably the cause.
Otherwise, try to check if the issue could be related to any of the following... 

A. It seems that you currently need to restart the application after changing the JWT configuration settings

/Globalsettings/Modules/Users/Jwt/UseFixedSecret
/Globalsettings/Modules/Users/Jwt/Secret

This is probably unintended. I'll need to get that confirmed.

Note: The secret must be exactly 32 characters long for this to work.

B. When UseFixedSecret mode is enabled the token generation and validation is different from how it works in the normal mode (default).
The normal mode will use the user id as identifier in the token, but the fixed secret mode will use the username as identifier in the token.
The identifier in the token is used for looking up the actual user in the request.
If you have multiple users with the same username then it might not work as expected.
I'm not sure why this part of the token handling is different. I'll need to ask someone else about that.

If you still can't find the cause of the issue then please provide some more details (DW version, api endpoint, request/response examples) and we can take a closer look at it.

/Morten

 
Anders Ebdrup
Reply

Dear Morten,

Thank you very much for the detailed explanation of the implementation.

Based on your description, I can deduce that the reason I am receiving a 400 Bad Request is that my user does not have a username. In our setup, we impersonate “customers” who are not allowed to log in to the solution, and therefore do not have a username associated with their account.

This leads to another question:
Why is the username used as the identifier in the JWT token, rather than—for example—the user’s UniqueId?

Best regards, Anders

 
Morten Bengtson Dynamicweb Employee
Morten Bengtson
Reply

I think the JWT token handling was implemented before UniqueId was added to users. Maybe we can change it to use the UniqueId or make the behavior configurable.
I have added a feature request to our backlog, but it hasn't been approved and planned yet.

DevOps #26546

/Morten
 

 
Nuno Aguiar Dynamicweb Employee
Nuno Aguiar
Reply

Hi Anders,

 

I've been down the path of having Impersonation of "customers" who are not allowed to log into the solution, but that came with a lot of issues (i.e. sharing of saved cards, problems getting proper statistics/tracking data, limitations in smart searches, sharing of favorites, ...)

 

There's a new approach coming that overcomes these issues that you might want to consider as well (although not all features are available in Ring 1 just yet):

  • Customers/Accounts are User Groups (of a specific type)
  • Each person will have a Login (DW user)
    • this one contains the password
  • For each Account the person can manage, it would have a Profile
    • different DW user that has the same username as the Login, no password, same Customer Number as the Account, and value "ShopID" that matches the Customer number
    • by having the same customer number, you can get addresses from the Account (User Group)
    • by having a different "ShopId", you can get multiple dw users with the same username (email)
    • by having unique DW users, we can overcome the issues I've been experiencing
  • New features in DW allow you to Switch between Profiles (users with the same username)

 

All that to say that, it justifies using JWT tokens instead of FixedSecret, because you'll tend to have multiple users with the same username. Already in R1 you have the endpoint to return the profiles. Some of the UI features (i.e. listing subgroups in a list instead of tree so we can also search) are still being finalized.

endpoint: /dwapi/docs/index.html?url=/dwapi/api.json#/User%20creation%20%26%20management%20>%20User%20information/Users_GetProfiles

 

Hope this helps,

Nuno Aguiar

 

 
Anders Ebdrup
Reply

Hi Nuno,

Thank you very much for the detailed explanation!

Your description of the new Login/Profile approach is extremely helpful. Especially the part about how separating Login users and Profile users (with shared usernames but different ShopIDs and Customer Numbers).

It makes perfect sense that this new model naturally leads toward using JWT tokens instead of a FixedSecret, since having multiple DW users with the same username would otherwise cause conflicts. I really appreciate the insight into what is already available in Ring 1 and what is still being finalized - that helps a lot in planning ahead.

One quick question: 

Do you know when the remaining features of this new approach are expected to be fully in place in DynamicWeb?
Thanks again for taking the time to explain this! It’s extremely valuable!

Best regards,
Anders

 
Nuno Aguiar Dynamicweb Employee
Nuno Aguiar
Reply

Hi Anders,

 

Short answer: I do not know. But the "remaining features" may not be important to you, but you can already play with switching profiles. 

 

Currently:

* You already have a way to switch profiles. There's an endpoint that returns you the Profiles https://doc.dynamicweb.dev/webapi/delivery/delivery-api-test.html#/User%20creation%20%26%20management%20%3E%20User%20information/Users_GetProfiles

* You'd then get back a JTW token for each profile

 

And assuming you're doing a headless implementation (if you're using JWT tokens), you can just use the appropriate JWT token (of the desired profile) to handle your requests.

 

The way we're essentially handling is our frontend application manages 2 JWT tokens. One for the Login, to do things like showing generic information and password updates and another for the "active" Profile, which is then used for almost all endpoints.

 

What's mainly missing are some UI features to view/manage the data, specially with big amounts of data (i.e. list user sub groups as a list in the main pane and having the ability to search and paginate; viewing/edting addresses on user groups - because that's where we'd import addresses tied to a customer number,...). The main thing we're waiting for though is a way to update groups (using the delivery api), because we're using a different group type for Roles. That allows us to have:

  • Each proflile can belong to different Roles
  • Because Roles are user groups, we set permissions (in the backend) on Roles
  • And some admin users will have the ability to update Roles for other users - hence the need to have it in the delivery api

 

So again, you might not need what I'm waiting for. Take profiles for a spin ;)

 

Best Regards,

Nuno

 

You must be logged in to post in the forum