Keycloak addUser inside custom Authenticator getting error - keycloak

Here is my not finished source that will do some "checks" then addUser if not exist,
Currently I'm testing simply adding new user here is my writings
public void authenticate(AuthenticationFlowContext context) {
KeycloakSession session = context.getSession();
RealmModel realm = context.getRealm();
String username = "hello";
UserProvider users = session.userLocalStorage();
UserModel user = users.getUserByUsername(realm,username);
if (user == null) {
logger.infof("addingUser");
user = session.users().addUser(realm,username);
logger.infof("isEnabled()");
user.setEnabled(true);
user.setEmail("mail#mail.com");
user.setEmailVerified(true);
}
context.setUser(user);
context.success();
}
with this source when I try to login for the first time, it gets me error but user is created.
Then if I try to login for the second time, it logs in successfully (shows me personal page)
06:05:12,633 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-8)
Unique index or primary
key violation: "UK_RU8TT6T700S9V50BU18WS5HA6_INDEX_B ON PUBLIC.USER_ENTITY(REALM_ID,
USERNAME) VALUES ('Customer', 'hello', 5)"; SQL statement:
2021-11-12T06:05:12.634069100Z insert into USER_ENTITY (CREATED_TIMESTAMP, EMAIL,
EMAIL_CONSTRAINT, EMAIL_VERIFIED, ENABLED, FEDERATION_LINK,
FIRST_NAME, LAST_NAME, NOT_BEFORE, REALM_ID, SERVICE_ACCOUNT_CLIENT_LINK, USERNAME,
ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [23505-197]
2021-11-12T06:05:12.647493900Z
Additional information logs show me output twice for example
2021-11-12T06:05:12.610917800Z 06:05:12,610 INFO [class name] (default task-6) addingUser
2021-11-12T06:05:12.615587600Z 06:05:12,615 INFO [class name] (default task-8) addingUser
task 6 reaches log output logger.infof("isEnabled()");
task 8 not

Related

SQL Database Operational Error - no such table : users

sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: users
[SQL: SELECT users.id AS users_id, users.username AS users_username, users.password AS users_password
FROM users
WHERE users.username = ?]
the above is the error im getting.
class User(db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(24), unique=True, nullable=False)
password = db.Column(db.String(), nullable=False)
this is my User code.
#app.route('/', methods=['GET', 'POST'])
def index():
reg_form = Registeration()
if reg_form.validate_on_submit():
username = reg_form.username.data
password = reg_form.password.data
# for checking if someone has taken the username already
user_object = User.query.filter_by(username=username).all()
if user_object:
return "This username has been taken. Try another one.."
#registering in the database and commiting and etc
user = User(username=username, password=password)
db.session.add(user)
db.session.commit()
return 'Registered into the database!'
return db.create_all()
the application code.
I'm unable to figure out.. any help would be greatly appreciated. Btw im trying to make a registration system where the username and the pass get stored in Postgres Database.

sqlalchemy many to many relationships (the value of a duplicate key breaks the unique constraint) flask_user role

can you help me,
when i run this script it works well
class User(db.Model, UserMixin):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
active = db.Column('is_active', db.Boolean(), nullable=False, server_default='1')
# User authentication information. The collation='NOCASE' is required
# to search case insensitively when USER_IFIND_MODE is 'nocase_collation'.
email = db.Column(db.String(255, collation='NOCASE'), nullable=False, unique=True)
email_confirmed_at = db.Column(db.DateTime())
password = db.Column(db.String(255), nullable=False, server_default='')
# User information
first_name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
last_name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
# Define the relationship to Role via UserRoles
roles = db.relationship('Role', secondary='user_roles')
# Define the Role data-model
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(50), unique=True)
# Define the UserRoles association table
class UserRoles(db.Model):
__tablename__ = 'user_roles'
id = db.Column(db.Integer(), primary_key=True)
user_id = db.Column(db.Integer(), db.ForeignKey('users.id', ondelete='CASCADE'))
role_id = db.Column(db.Integer(), db.ForeignKey('roles.id', ondelete='CASCADE'))
# Setup Flask-User and specify the User data-model
user_manager = UserManager(app, db, User)
# Create all database tables
db.create_all()
# Create 'member#example.com' user with no roles
if not User.query.filter(User.email == 'member#example.com').first():
user = User(
email='member#example.com',
email_confirmed_at=datetime.datetime.utcnow(),
password=user_manager.hash_password('Password1'),
)
db.session.add(user)
db.session.commit()
# Create 'admin#example.com' user with 'Admin' and 'Agent' roles
if not User.query.filter(User.email == 'admin#example.com').first():
user = User(
email='admin#example.com',
email_confirmed_at=datetime.datetime.utcnow(),
password=user_manager.hash_password('Password1'),
)
user.roles.append(Role(name='Admin'))
user.roles.append(Role(name='Agent'))
db.session.add(user)
db.session.commit()
at this stage the code is working without problems but the problem is just after when I add another user with a role that already exists
in this case the Admin role or the Agent role
for example if I add the code below an error message displays
if not User.query.filter(User.email == 'admin2#example.com').first():
user = User(
email='admin2#example.com',
email_confirmed_at=datetime.datetime.utcnow(),
password=user_manager.hash_password('Password1'),
)
user.roles.append(Role(name='Admin'))
user.roles.append(Role(name='Agent'))
db.session.add(user)
db.session.commit()
sqlalchemy.exc.IntegrityError: (psycopg2.IntegrityError) ERREUR: la valeur d'une clé dupliquée rompt la contrainte unique « roles_name_key »
DETAIL: La clé « (name)=(Admin) » existe déjà.
[SQL: 'INSERT INTO roles (name) VALUES (%(name)s) RETURNING roles.id'] [parameters: {'name': 'Admin'}] (Background on this error at: http://sqlalche.
me/e/gkpj)
I tried db driver different (pg8000, pygresql, py-postgresql) and still the same problem,
as the error message shows the problem because of the name value which is unique
name = db.Column (db.String (50), unique = True)
can you explain to me what is the error that I made, and what is the role of this part of code
# Define the relationship to Role via UserRoles
roles = db.relationship ('Role', secondary = 'user_roles')
I use flask with flask_user

JPA optimistic lock can't get the latest version

I am using the JPA's optimistic lock with spring data jpa and using spring retry for ConcurrencyFailureException, but something occurs that i can't understand.
my test code just like below:
#Repository
public interface AccountRepo extends JpaRepository<Account, String>, JpaSpecificationExecutor<Account> {
#Lock(LockModeType.OPTIMISTIC)
#Query(value = "select a from Account a where a.id = :id")
Account findOne(#Param("id") String id);
}
--------------------------------------------------------------------
#Service
public class AccountService {
#Qualifier("accountRepo")
#Autowired
private AccountRepo accountRepo;
#Transactional(value = "transactionManager", isolation = Isolation.READ_COMMITTED)
public Account saveOne(Account account){
return accountRepo.save(account);
}
public Account findOne(String id){
return accountRepo.findOne(id);
}
}
----------------------------------------------------------------------
#Transactional(value = "transactionManager", isolation = Isolation.READ_COMMITTED)
#Retryable(value = {ConcurrencyFailureException.class}, backoff = #Backoff(delay = 3000))
public void testOptimistic(){
Account account = accountService.findOne("abee19e08d3d4ee79d9f831c3ed78344");
account.setHistoryIncome(new BigDecimal("3300"));
account.setTodayTotalIncome(new BigDecimal("3300"));
account.setTodayOnlineIncome(new BigDecimal("3300"));
account.setAvaliableAmount(new BigDecimal("3300"));
accountService.saveOne(account);
AccountOperRecord accountOperRecord = new AccountOperRecord();
accountOperRecord.setId(BuildNoUtil.buildAccountOperRecordId());
accountOperRecord.setTrxType(TrxTypeEnum.EXPENSE.name());
accountOperRecord.setAvaliableAmount(account.getAvaliableAmount());
accountOperRecord.setOperAmount(new BigDecimal("100"));
accountOperRecord.setOrderId("4028b8815c813d64015c813e17f50000");
accountOperRecord.setOutTradeNo("2015061121001004400068549373");
accountOperRecord.setAccountId("abee19e08d3d4ee79d9f831c3ed78344");
accountOperRecordService.saveOne(accountOperRecord);
}
----------------------------------------------------------------------
#Controller
public class TestController extends BaseController {
#RequestMapping(value = "testOptimistic")
#ResponseBody
public JSONObject testOptimisticLock(){
JSONObject result = new JSONObject();
conjunctionService.testOptimistic();
result.put("code", "success");
return result;
}
}
i added a breakpoint at Account account = accountService.findOne("abee19e08d3d4ee79d9f831c3ed78344");, then i run a transaction in mysql to change the version of Account.
After that, the testOptimistic method throws the ConcurrencyFailureException and the method retried, in my opinion, it will success the next time but it failed again, finally it success at the third time, i just can not understand.
the logs of Hibernate SQL showed below
Hibernate: select account0_.id as id1_0_, account0_.create_time as create_t2_0_, account0_.creater as creater3_0_, account0_.edit_time as edit_tim4_0_, account0_.editor as editor5_0_, account0_.remark as remark6_0_, account0_.address as address7_0_, account0_.avaliable_amount as avaliabl8_0_, account0_.email as email9_0_, account0_.history_expense as history10_0_, account0_.history_income as history11_0_, account0_.merchant_name as merchan12_0_, account0_.name as name13_0_, account0_.phone as phone14_0_, account0_.settled_amount as settled15_0_, account0_.settling_amount as settlin16_0_, account0_.splited_amount as splited17_0_, account0_.today_offline_income as today_o18_0_, account0_.today_online_income as today_o19_0_, account0_.today_total_income as today_t20_0_, account0_.version as version21_0_ from account account0_ where account0_.id=?
Hibernate: select accountope0_.id as id1_1_0_, accountope0_.account_id as account_2_1_0_, accountope0_.avaliable_amount as avaliabl3_1_0_, accountope0_.oper_amount as oper_amo4_1_0_, accountope0_.order_id as order_id5_1_0_, accountope0_.out_trade_no as out_trad6_1_0_, accountope0_.remit_id as remit_id7_1_0_, accountope0_.settle_id as settle_i8_1_0_, accountope0_.split_batch_id as split_ba9_1_0_, accountope0_.trx_type as trx_typ10_1_0_ from account_oper_record accountope0_ where accountope0_.id=?
Hibernate: insert into account_oper_record (account_id, avaliable_amount, oper_amount, order_id, out_trade_no, remit_id, settle_id, split_batch_id, trx_type, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: update account set avaliable_amount=?, history_income=?, today_online_income=?, today_total_income=?, version=? where id=? and version=?
Hibernate: select account0_.id as id1_0_, account0_.create_time as create_t2_0_, account0_.creater as creater3_0_, account0_.edit_time as edit_tim4_0_, account0_.editor as editor5_0_, account0_.remark as remark6_0_, account0_.address as address7_0_, account0_.avaliable_amount as avaliabl8_0_, account0_.email as email9_0_, account0_.history_expense as history10_0_, account0_.history_income as history11_0_, account0_.merchant_name as merchan12_0_, account0_.name as name13_0_, account0_.phone as phone14_0_, account0_.settled_amount as settled15_0_, account0_.settling_amount as settlin16_0_, account0_.splited_amount as splited17_0_, account0_.today_offline_income as today_o18_0_, account0_.today_online_income as today_o19_0_, account0_.today_total_income as today_t20_0_, account0_.version as version21_0_ from account account0_ where account0_.id=?
Hibernate: select accountope0_.id as id1_1_0_, accountope0_.account_id as account_2_1_0_, accountope0_.avaliable_amount as avaliabl3_1_0_, accountope0_.oper_amount as oper_amo4_1_0_, accountope0_.order_id as order_id5_1_0_, accountope0_.out_trade_no as out_trad6_1_0_, accountope0_.remit_id as remit_id7_1_0_, accountope0_.settle_id as settle_i8_1_0_, accountope0_.split_batch_id as split_ba9_1_0_, accountope0_.trx_type as trx_typ10_1_0_ from account_oper_record accountope0_ where accountope0_.id=?
Hibernate: insert into account_oper_record (account_id, avaliable_amount, oper_amount, order_id, out_trade_no, remit_id, settle_id, split_batch_id, trx_type, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: update account set avaliable_amount=?, history_income=?, today_online_income=?, today_total_income=?, version=? where id=? and version=?
Hibernate: select version from account where id =?
Hibernate: select account0_.id as id1_0_, account0_.create_time as create_t2_0_, account0_.creater as creater3_0_, account0_.edit_time as edit_tim4_0_, account0_.editor as editor5_0_, account0_.remark as remark6_0_, account0_.address as address7_0_, account0_.avaliable_amount as avaliabl8_0_, account0_.email as email9_0_, account0_.history_expense as history10_0_, account0_.history_income as history11_0_, account0_.merchant_name as merchan12_0_, account0_.name as name13_0_, account0_.phone as phone14_0_, account0_.settled_amount as settled15_0_, account0_.settling_amount as settlin16_0_, account0_.splited_amount as splited17_0_, account0_.today_offline_income as today_o18_0_, account0_.today_online_income as today_o19_0_, account0_.today_total_income as today_t20_0_, account0_.version as version21_0_ from account account0_ where account0_.id=?
Hibernate: select accountope0_.id as id1_1_0_, accountope0_.account_id as account_2_1_0_, accountope0_.avaliable_amount as avaliabl3_1_0_, accountope0_.oper_amount as oper_amo4_1_0_, accountope0_.order_id as order_id5_1_0_, accountope0_.out_trade_no as out_trad6_1_0_, accountope0_.remit_id as remit_id7_1_0_, accountope0_.settle_id as settle_i8_1_0_, accountope0_.split_batch_id as split_ba9_1_0_, accountope0_.trx_type as trx_typ10_1_0_ from account_oper_record accountope0_ where accountope0_.id=?
Hibernate: insert into account_oper_record (account_id, avaliable_amount, oper_amount, order_id, out_trade_no, remit_id, settle_id, split_batch_id, trx_type, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: update account set avaliable_amount=?, history_income=?, today_online_income=?, today_total_income=?, version=? where id=? and version=?
Hibernate: select version from account where id =?
Hibernate: select version from account where id =?
you can see that select version from account where id =? execute two times at the third time, anyone can explain this?!
Thank you very much!

Can't add a claim with ASP.NET Core and identity

I try to add a custom claim to an existing Identity user but I get an exception at run-time:
Npgsql.PostgresException: 23502: null value in column "Id" violates not-null constraint
Help!
What I did. I've created a simple web app on windows using the following command line
dotnet new mvc --auth Individual --framework netcoreapp1.1
I made changes found here to make the app use PostgreSQL as the database back-end. The created default webapp works fine. I can register as a new user, login, log out, etc...
Then I modified the Test method of the Home controller (I know the exceptions are ugly):
[Authorize]
public async Task<IActionResult> Test()
{
var user = await GetCurrentUserAsync();
if (user == null) {
_logger.LogWarning("User is null.");
throw new Exception("Not logged in");
}
_logger.LogWarning("User: {0}, {1}", user.Email, user);
var claim = new Claim("TestClaimType", "TestClaimValue");
IdentityResult idRes = IdentityResult.Failed();
if (_userManager.SupportsUserClaim) {
idRes = await _userManager.AddClaimAsync(user, claim); <------- Adding the claim
}
_logger.LogWarning("Return from adding claim");
if (idRes != IdentityResult.Success) {
throw new Exception("Failed to add claim.");
}
return View();
}
After logging in, I trigger the Test method and get the following logging (the PostgresException is near the end):
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://localhost:5000/Home/Test
info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware[3]
HttpContext.User merged via AutomaticAuthentication from authenticationScheme: Identity.Application.
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1]
Authorization was successful for user: mark#mark.com.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
Executing action method AlumniConnect.Controllers.HomeController.Test (AlumniConnect) with arguments ((null)) - ModelState is Valid
info: Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory[1]
Executed DbCommand (1ms) [Parameters=[#__get_Item_0='?'], CommandType='Text', CommandTimeout='30']
SELECT "e"."Id", "e"."AccessFailedCount", "e"."ConcurrencyStamp", "e"."Email", "e"."EmailConfirmed", "e"."LockoutEnabled", "e"."LockoutEnd", "e"."NormalizedEmail", "e"."NormalizedUserName", "e"."PasswordHash", "e"."PhoneNumber", "e"."PhoneNumberConfirmed", "e"."SecurityStamp", "e"."TwoFactorEnabled", "e"."UserName"
FROM "AspNetUsers" AS "e"
WHERE "e"."Id" = #__get_Item_0
LIMIT 1
warn: AlumniConnect.Controllers.HomeController[0]
User: mark#mark.com, mark#mark.com
warn: AlumniConnect.Controllers.HomeController[0]
User: mark#mark.com, mark#mark.com
info: Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory[1]
Executed DbCommand (4ms) [Parameters=[#__normalizedUserName_0='?'], CommandType='Text', CommandTimeout='30']
SELECT "u"."Id", "u"."AccessFailedCount", "u"."ConcurrencyStamp", "u"."Email", "u"."EmailConfirmed", "u"."LockoutEnabled", "u"."LockoutEnd", "u"."NormalizedEmail", "u"."NormalizedUserName", "u"."PasswordHash", "u"."PhoneNumber", "u"."PhoneNumberConfirmed", "u"."SecurityStamp", "u"."TwoFactorEnabled", "u"."UserName"
FROM "AspNetUsers" AS "u"
WHERE "u"."NormalizedUserName" = #__normalizedUserName_0
LIMIT 1
info: Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory[1]
Executed DbCommand (33ms) [Parameters=[#p0='?', #p1='?', #p2='?', #p17='?', #p3='?', #p4='?', #p18='?', #p5='?', #p6='?', #p7='?', #p8='?', #p9='?', #p10='?', #p11='?', #p12='?', #p13='?', #p14='?', #p15='?', #p16='?'], CommandType='Text', CommandTimeout='30']
INSERT INTO "AspNetUserClaims" ("ClaimType", "ClaimValue", "UserId")
VALUES (#p0, #p1, #p2)
RETURNING "Id";
UPDATE "AspNetUsers" SET "AccessFailedCount" = #p3, "ConcurrencyStamp" = #p4, "Email" = #p5, "EmailConfirmed" = #p6, "LockoutEnabled" = #p7, "LockoutEnd" = #p8, "NormalizedEmail" = #p9, "NormalizedUserName" = #p10, "PasswordHash" = #p11, "PhoneNumber" = #p12, "PhoneNumberConfirmed" = #p13, "SecurityStamp" = #p14, "TwoFactorEnabled" = #p15, "UserName" = #p16
WHERE "Id" = #p17 AND "ConcurrencyStamp" = #p18;
fail: Microsoft.EntityFrameworkCore.DbContext[1]
An exception occurred in the database while saving changes.
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> Npgsql.PostgresException: 23502: null value in column "Id" violates not-null constraint
at Npgsql.NpgsqlConnector.<DoReadMessageAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
There's lots of logging more but it doesn't seem to add new information. I see the same exception mentioned multiple times throughout the log.
What can I do? Is this a PostgreSQL specific issue? Am I trying to add a claim in the wrong way?
Thanks!
In the migration for Identity, all tables that have a generated Integer id have an annotation for adding auto generation of this id. This annotation is SQL Server specific, like .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn)
The fix for this is to add a Postgres specific annotation to the migration: .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn). In older versions of Npgsql.EntityFrameworkCore.PostgreSQL it could be that you need to use .Annotation("Npgsql:ValueGeneratedOnAdd", true).
The part of the migration for creating the AspNetRoleClaims table will then look like:
migrationBuilder.CreateTable(
name: "AspNetRoleClaims",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn),
ClaimType = table.Column<string>(nullable: true),
ClaimValue = table.Column<string>(nullable: true),
RoleId = table.Column<string>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
table.ForeignKey(
name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
column: x => x.RoleId,
principalTable: "AspNetRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
It appears that when the Claim is added to the database, the 'RETURNING "Id"' clause of the SQL statement suggests the ID is returned. However, the table does not have an auto incrementing ID column.
I verified this by following the instructions from Adding 'serial' to existing column in Postgres.
The problem is now of course that this should have been taken care of automatically...

org.postgresql.util.PSQLException: No results returned by the query

hey everyone am trying to insert data in a table using #Query annotation in my spring boot app am getting a postgres Exception :
org.postgresql.util.PSQLException: No results returned by the query
this is my code :
this is the repository
#Query(value="INSERT INTO \"FCT_BY_DEV\"(\"IdDev\", \"IdFonction\") VALUES (?, ?) ",nativeQuery=true)
public String isertfonctionstodev(int dev,int fonction);
this is the controller :
#RequestMapping(value="/function/insert", method = RequestMethod.POST)
public String insererfonctions (int dev,int fonction){
System.out.println("dev="+dev+"fonction="+fonction);
fonctionRepository.isertfonctionstodev(dev, fonction);
System.out.println("********");
return "aaa";
}
am using this service by $http in angularJs
$http.post("/function/insert?dev="+$scope.id+"&fonction="+$scope.idf);
and finaly this is the server log
dev=16006fonction=14
Hibernate: INSERT INTO "FCT_BY_DEV"("IdDev", "IdFonction") VALUES (?, ?)
2016-04-27 16:52:03.204 WARN 7036 --- [nio-8080-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 02000
2016-04-27 16:52:03.204 ERROR 7036 --- [nio-8080-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : Aucun résultat retourné par la requête.
the data is correct and i tried the same query with the same value and it worked why posgres is generating this exception and how can i fixed , thanks to any help
I think modifying queries must be annotared with an extra
#Modifying
This should solve your issue:
#Transactional
#Modifying(clearAutomatically = true)
#Query(value="update policy.tbl_policy set ac_status = 'INACTIVE' where pol_id = :policyId and version_no = :version_no and ac_status = 'ACTIVE'", nativeQuery=true)
public void updateExistingRowbyId(#Param("policyId") Long pol_id, #Param("version_no") Long version_no);
Without #Transactional annotation, following errors may occur:
javax.persistence.TransactionRequiredException: Executing an update/delete query