Store multiple credentials in Keycloak - keycloak

Is it possible to store multiple credentials for a given user in Keycloak?
They don't need to be all active/enabled at the same time. The use case for us is rather that we want to store new credentials in advance but don't want to have them active yet. They should be activated/enabled at a later time after some manual user verification.
The Keycloak REST API documentation states that UserRepresentation indeed comprises an array of CredentialRepresentation but in my few tests the GET call wouldn't even return a credentials attribute.

I would say that's impossible to have more credentials for a user.
But you can always implement your own user storage SPI that implements interface CredentialInputValidator, where you can check for the valid password.
Let's say in your DB, you have 2 colums for passwords: pas_col1 and pas_col2, and 1 more column as flag, which tells what column is used for user authentication, so in isValid(RealmModel realm, UserModel user, CredentialInput input) method you can check for your conditions.
Link to SPI: https://www.keycloak.org/docs/3.4/server_development/index.html#_user-storage-spi

Related

Join user id from one database with user profile data stored in another database with .Net core

I am retrieving data over an API and displaying it in my web application as shown:
The obvious problem being that I need Last Edited By to show the users name, rather than their GUID.
I use Identity Server 4, so UserProfile details are all held in a separate (OAuth) database.
The flow for returning data to the web app is as follows, and I'd like to know how I could return First and Last name from the OAuth database, instead of user IDs (guids)
My query in the repository at the moment is simply:
public IEnumerable<Survey> GetSurveys()
{
var surveys = _context.Surveys
.Include(s => s.SurveyStatus)
.ToList();
return surveys;
}
The issue is that you are missing the information in your (business) database. First and last name are actually both identity information as business information. This means that first and last name should be part of both the identity model and business model.
To solve this: add a user table (containing userId, first and last name) and update the table with information when a user logs in.
Since you are logging activity of a logged in user, you always have the information you need. So there is no need to query the user table in the Identity Model. For a first setup you may want to create the new table using information from the identity database.
Though information is stored multiple times, it is not redundant. In fact, you would do the same thing when storing information about external logins.
Most of the time when you have an external identity provider, you'll keep certain claims on authenticated users as part of a local profile.
For logging / auditing, you would use their identity key from the external identity provider as well a foreign key to the user's record in your profile table. I would keep this so that you have access to the correct record in profiles even when they are not logged in (and the record will remain updated for as long as the user continues coming back).
When a user logs in, you can check their claims against your profiles table and update it. Then when you look at the audit info or logs, the db query would be getting the updated profile information.

How to securize an entitie on Sails?

I'm developing an API with Sails, and now I need to securize some variables from an entity. Those variable will be accesed only from Admin or own user.
I have an structure like this:
Employee (contains your employee records)
fullName
hourlyWage
phoneNumber
accountBank
Location (contains a record for each location you operate)
streetAddress
city
state
zipcode
...
I need to encrypt phonenumber and accountbank, to avoid anyone to see the values of this fields in the DataBase. Only the owner or the admin.
How I can do that? Thanks
You are looking for a way to encrypt data so that people with no required access right could not see it.
The solution for that is not Sails.js specific and Node actually comes with tools to encrypt data :https://nodejs.org/api/crypto.html.
The key rule here is to always keep your secret password safe.
As for integration in your Sails.js application, I would use callbacks in Models. The official documentation provides a good example here : http://sailsjs.org/documentation/concepts/models-and-orm/lifecycle-callbacks
Basically you just define a function that will be called each time the record is about to be created, fetched or updated. You can then apply your encrypt/decrypt functions there.
This will encrypt/decrypt your phone numbers and bank account numbers automatically.
Regarding access control, you can use Sails' policies along with authentication to determine if the client has the right to access the resource. If not you can always remove attributes from the response sent back to the client.

REST API logged in user can access data (parse.com)

I'm using the parse REST API.
I need to setup so that for any requests made:
1) only logged in/authenticated users can Read or Write.
2) users can only access/modify records they own.
My current implementation:
1) using the Application key + REST API key.
2) sending request to user login endpoint, on success returning the user data including the session token
for 2), I'm not doing anything with the session token yet.
I understand that parse has:
1) class based permissions
2) object-level permissions (ACL's)
With Read and Write access on the class level, and by simply using the Application Key + REST API Keys,
anyone with these two keys can access that class (ofcourse, the Master Key has even more "power").
I want to simply say that they can Read and Write on the class level, if they're logged in/authenticated.
And when they Read, Update or Delete, they can only do so if they're owner of the object.
I assume that session token will play a role in the logged in part, and ownership is defined by object-level ACL
Is this correct and how to roughly set this scenario up in parse?
It's not clear to me in the REST API how to handle this (what I think is a common) type of scenario.
Thanks for any feedback
{"ACL":{"$CURRENT_USER":{"read":true,"write":true}}}
above in acl column will mean at the security level, only the creator has RW permissions. No other user can see these records with this ACL attr value regardless of their access on the CLASS level.
OR
you control the accessor predicates in your app. So you can add a column = 'createdBY' of type pointer_to_class_User.
Any queries just contain predicate ..
'where={"createdBy":{"__type":"Pointer","className":"User","objectId":"$CURRENT_USER"}}'
which enforces ( outside row security level ) idea of only getting result sets containing rows for the current-user.
all depends on how you want to use the security layer.
I would do it using the predicates and resort to the ACL only where you may have stuff like SSN's or Salary where as a policy you dont what general read permissions.

Connect with custom user name in Scala/Play using default tools

In my Scala/Play application i have to work with database but there's no default user and password because every authenticated application user is bound to different DB user. So i'd like to specify user name and password on obtaining connection, smth like:
DB.withConnection(user = "James", password = "secret") { ... }
For now i can't find such capabilities in docs (and honestly saying i'm not sure how to specify a search query for my question).
And another question: is it safe to store user password in session taking into account that session is stored on user side? Or are there any best practices for such case when different DB users work with app?
Answer to Question 1
In Play, you obtain datasources by name:
def getDataSource(name: String): DataSource
You'd have to do some heavy hacking of the stuff in package play.api.db to get the functionality you require.
That, or you can predefine a bunch of datasources if the number of users of your app is small, and retrieve the connection by their login name, e.g.:
db.bob.url="jdbc:h2:mem:db_for_bob"
db.bob.driver=org.h2.Driver
db.alice.url="jdbc:h2:mem:db_for_alice"
db.alice.driver=org.h2.Driver
And
DB.withConnection("bob") { implicit connection =>
Or
DB.withConnection(userNameKnownAtRuntime) { implicit connection =>
Answer to Question 2
Even though the data in sessions are heavily encrypted using the application secret, I would recommend not to store these client-side. Instead, implement something along the lines of Resource Owner Password Credentials Grant according to this section in the OAuth 2 spec. That would give your client a token which is only valid for a set period, and could be invalidated server-side if need be.

how to set maximum password length in web.config file?

I had set minRequiredPasswordLength,minRequiredNonalphanumericCharacters in membership section of web.config file. but i need maximum password length also to set. how to set in web.config file?
I think that the default implementations of MembershipProvider does not support this feature. However, you could obtain the same results by validating the password length when the users set/change it.
Edit related to PasswordRecovery control
If you are using a standard implementation of the MembershipProvider class with the PasswordRecovery control you are unable to interfere with the generation of the new password (more precisely ResetPassword - "Resets a user's password to a new, automatically generated password").
If you want to use the PasswordRecovery control I see no other option than creating a custom membership provider deriving from the abstract MembershipProvider class or from one of its concrete implementation (like SqlMembershipProvider);
The other option would be to implement your custom password recovery interface as you could still rely on functionality implemented in your MembershipProvider. When the user wants to reset his password you could use GetUser method to obtain the related information, then ResetPassword to obtain a new password. In this moment you may use the password that ResetPassword returns and call ChangePassword to set a new password that meets your criteria, than email it to the user. There are many ways to implement the corresponding user interface, but the reset password logic would be almost the same.
Also in case you decide that keeping the passwords encrypted instead of hashed meets your requirements, your problem will be solved as users will receive through email their old passwords (that meet the maximum length condition from the moment they were set). For this make the following changes in web.config:
Passwordformat="encrypted"
Passwordreset="true"
Passwordretriaval="true"
You must use ValidatingPassword event. Here you can check maximum length, etc. More info available at:
http://forums.asp.net/t/946218.aspx