mirror of
https://github.com/netzbegruenung/keycloak-2fa-sms-authenticator.git
synced 2024-04-27 16:44:53 +02:00
Add clientName and clientUrl to challenge
This commit is contained in:
parent
1aaaee60da
commit
432021aa6e
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -6,3 +6,4 @@ dependency-reduced-pom.xml
|
|||
.classpath
|
||||
.project
|
||||
.settings
|
||||
.jpb
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.keycloak.device.DeviceRepresentationProvider;
|
|||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.jpa.entities.ClientEntity;
|
||||
import org.keycloak.models.jpa.entities.RealmEntity;
|
||||
import org.keycloak.models.jpa.entities.UserEntity;
|
||||
import org.keycloak.representations.account.DeviceRepresentation;
|
||||
|
@ -98,7 +99,7 @@ public class AppAuthenticator implements Authenticator, CredentialValidator<AppC
|
|||
logger.infov("App authentication signature string\n\n{0}\n", AuthenticationUtil.getSignatureString(signatureStringMap));
|
||||
}
|
||||
|
||||
MessagingServiceFactory.get(authConfig).send(appCredentialData.getDevicePushId(), ChallengeConverter.getChallengeDto(challenge));
|
||||
MessagingServiceFactory.get(authConfig).send(appCredentialData.getDevicePushId(), ChallengeConverter.getChallengeDto(challenge, context.getSession()));
|
||||
|
||||
Response response = context.form()
|
||||
.setAttribute("appAuthStatusUrl", String.format(
|
||||
|
@ -123,6 +124,7 @@ public class AppAuthenticator implements Authenticator, CredentialValidator<AppC
|
|||
EntityManager em = getEntityManager(context.getSession());
|
||||
RealmEntity realm = em.getReference(RealmEntity.class, context.getRealm().getId());
|
||||
UserEntity user = em.getReference(UserEntity.class, context.getUser().getId());
|
||||
ClientEntity client = em.getReference(ClientEntity.class, context.getAuthenticationSession().getClient().getId());
|
||||
|
||||
try {
|
||||
TypedQuery<Challenge> query = em.createNamedQuery("Challenge.findByRealmAndDeviceId", Challenge.class);
|
||||
|
@ -154,6 +156,7 @@ public class AppAuthenticator implements Authenticator, CredentialValidator<AppC
|
|||
challenge.setOsVersion(deviceRepresentation.getOsVersion());
|
||||
challenge.setIpAddress(deviceRepresentation.getIpAddress());
|
||||
challenge.setUpdatedTimestamp(Time.currentTimeMillis());
|
||||
challenge.setClient(client);
|
||||
|
||||
em.persist(challenge);
|
||||
em.flush();
|
||||
|
|
|
@ -1,9 +1,17 @@
|
|||
package netzbegruenung.keycloak.app.dto;
|
||||
|
||||
import netzbegruenung.keycloak.app.jpa.Challenge;
|
||||
import org.keycloak.common.util.StringPropertyReplacer;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.services.util.ResolveRelative;
|
||||
import org.keycloak.theme.Theme;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
|
||||
public class ChallengeConverter {
|
||||
public static ChallengeDto getChallengeDto(Challenge challenge) {
|
||||
public static ChallengeDto getChallengeDto(Challenge challenge, KeycloakSession session) {
|
||||
return new ChallengeDto(
|
||||
challenge.getUser().getUsername(),
|
||||
challenge.getUser().getFirstName(),
|
||||
|
@ -15,7 +23,21 @@ public class ChallengeConverter {
|
|||
challenge.getDevice(),
|
||||
challenge.getBrowser(),
|
||||
challenge.getOs(),
|
||||
challenge.getOsVersion()
|
||||
challenge.getOsVersion(),
|
||||
resolveClientName(challenge.getClient().getName(), session),
|
||||
ResolveRelative.resolveRelativeUri(session, challenge.getClient().getRootUrl(), challenge.getClient().getBaseUrl())
|
||||
);
|
||||
}
|
||||
|
||||
private static String resolveClientName(String clientName, KeycloakSession session) {
|
||||
return StringPropertyReplacer.replaceProperties(clientName, getProperties(session));
|
||||
}
|
||||
|
||||
private static Properties getProperties(KeycloakSession session) {
|
||||
try {
|
||||
return session.theme().getTheme(Theme.Type.ACCOUNT).getMessages(Locale.ENGLISH);
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,8 +18,10 @@ public class ChallengeDto implements Serializable {
|
|||
private final String browser;
|
||||
private final String os;
|
||||
private final String osVersion;
|
||||
private final String clientName;
|
||||
private final String clientUrl;
|
||||
|
||||
public ChallengeDto(String userName, String userFirstName, String userLastName, String targetUrl, String codeChallenge, Long updatedTimestamp, String ipAddress, String device, String browser, String os, String osVersion) {
|
||||
public ChallengeDto(String userName, String userFirstName, String userLastName, String targetUrl, String codeChallenge, Long updatedTimestamp, String ipAddress, String device, String browser, String os, String osVersion, String clientName, String clientUrl) {
|
||||
this.userName = userName;
|
||||
this.userFirstName = userFirstName;
|
||||
this.userLastName = userLastName;
|
||||
|
@ -31,6 +33,8 @@ public class ChallengeDto implements Serializable {
|
|||
this.browser = browser;
|
||||
this.os = os;
|
||||
this.osVersion = osVersion;
|
||||
this.clientName = clientName;
|
||||
this.clientUrl = clientUrl;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
|
@ -77,6 +81,14 @@ public class ChallengeDto implements Serializable {
|
|||
return osVersion;
|
||||
}
|
||||
|
||||
public String getClientName() {
|
||||
return clientName;
|
||||
}
|
||||
|
||||
public String getClientUrl() {
|
||||
return clientUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
@ -92,11 +104,13 @@ public class ChallengeDto implements Serializable {
|
|||
Objects.equals(this.device, entity.device) &&
|
||||
Objects.equals(this.browser, entity.browser) &&
|
||||
Objects.equals(this.os, entity.os) &&
|
||||
Objects.equals(this.osVersion, entity.osVersion);
|
||||
Objects.equals(this.osVersion, entity.osVersion) &&
|
||||
Objects.equals(this.clientName, entity.clientName) &&
|
||||
Objects.equals(this.clientUrl, entity.clientUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(userName, userFirstName, userLastName, targetUrl, codeChallenge, updatedTimestamp, ipAddress, device, browser, os, osVersion);
|
||||
return Objects.hash(userName, userFirstName, userLastName, targetUrl, codeChallenge, updatedTimestamp, ipAddress, device, browser, os, osVersion, clientName, clientUrl);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package netzbegruenung.keycloak.app.jpa;
|
|||
|
||||
import org.hibernate.annotations.OnDelete;
|
||||
import org.hibernate.annotations.OnDeleteAction;
|
||||
import org.keycloak.models.jpa.entities.ClientEntity;
|
||||
import org.keycloak.models.jpa.entities.RealmEntity;
|
||||
import org.keycloak.models.jpa.entities.UserEntity;
|
||||
|
||||
|
@ -35,6 +36,11 @@ public class Challenge {
|
|||
@OnDelete(action = OnDeleteAction.CASCADE)
|
||||
private UserEntity user;
|
||||
|
||||
@ManyToOne(optional = false)
|
||||
@JoinColumn(name = "client_id", nullable = false)
|
||||
@OnDelete(action = OnDeleteAction.CASCADE)
|
||||
private ClientEntity client;
|
||||
|
||||
@Column(name = "target_url", nullable = false, length = 1023)
|
||||
private String targetUrl;
|
||||
|
||||
|
@ -154,4 +160,11 @@ public class Challenge {
|
|||
this.osVersion = osVersion;
|
||||
}
|
||||
|
||||
public ClientEntity getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
public void setClient(ClientEntity client) {
|
||||
this.client = client;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ public class ChallengeResource {
|
|||
}
|
||||
|
||||
return Response
|
||||
.ok(Arrays.asList(ChallengeConverter.getChallengeDto(challenge)))
|
||||
.ok(Arrays.asList(ChallengeConverter.getChallengeDto(challenge, session)))
|
||||
.build();
|
||||
|
||||
} catch (IllegalStateException e) {
|
||||
|
|
|
@ -40,4 +40,16 @@
|
|||
<addForeignKeyConstraint baseColumnNames="user_id" baseTableName="app_auth_challenge" constraintName="FK_APP_AUTH_CHALLENGE_ON_USER" onDelete="CASCADE" referencedColumnNames="id" referencedTableName="user_entity"/>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
<changeSet id="app-auth-challenge-23.0.2" author="giuliano.mele@verdigado.com">
|
||||
<delete tableName="app_auth_challenge">
|
||||
</delete>
|
||||
<addColumn tableName="app_auth_challenge">
|
||||
<column name="client_id" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
<addForeignKeyConstraint baseTableName="app_auth_challenge" baseColumnNames="client_id" onDelete="CASCADE"
|
||||
referencedTableName="client" referencedColumnNames="ID" constraintName="FK_APP_AUTH_CHALLENGE_ON_CLIENT"/>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
INSERT INTO APP_AUTH_CHALLENGE (id, realm_id, user_id, target_url, device_id, secret, updated_timestamp, ip_address, device, browser, os, os_version)
|
||||
VALUES (random_uuid(), 'baeldung', 'a5461470-33eb-4b2d-82d4-b0484e96ad7f', 'target_url', 'test_device_id', 'secret', DATEDIFF('SECOND', DATE '1970-01-01', CURRENT_TIMESTAMP()) * 1000, 'ip_address', 'device', 'browser', 'os', 'os_version');
|
||||
INSERT INTO APP_AUTH_CHALLENGE (id, realm_id, user_id, client_id, target_url, device_id, secret, updated_timestamp, ip_address, device, browser, os, os_version)
|
||||
VALUES (random_uuid(), 'baeldung', 'a5461470-33eb-4b2d-82d4-b0484e96ad7f', '12eebf0b-a3eb-49f8-9ecf-173cf8a00145', 'target_url', 'test_device_id', 'secret', DATEDIFF('SECOND', DATE '1970-01-01', CURRENT_TIMESTAMP()) * 1000, 'ip_address', 'device', 'browser', 'os', 'os_version');
|
||||
|
|
Loading…
Reference in a new issue