diff --git a/application-home/conf/datasources.xml b/application-home/conf/datasources.xml
index 022ad77..962e116 100644
--- a/application-home/conf/datasources.xml
+++ b/application-home/conf/datasources.xml
@@ -36,6 +36,7 @@
+
diff --git a/src/main/java/org/appng/application/authentication/saml/SamlController.java b/src/main/java/org/appng/application/authentication/saml/SamlController.java
index 4a40300..c570676 100644
--- a/src/main/java/org/appng/application/authentication/saml/SamlController.java
+++ b/src/main/java/org/appng/application/authentication/saml/SamlController.java
@@ -82,6 +82,7 @@ public class SamlController implements InitializingBean {
private @Value("${" + AuthenticationSettings.SAML_FORWARD_TARGET + "}") String forwardTarget;
private List userGroups;
private SamlClient samlClient;
+ private String ssoEndpoint;
public static String CLAIM = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/";
@@ -92,9 +93,9 @@ public void afterPropertiesSet() throws Exception {
.getBytes(StandardCharsets.UTF_8);
userGroups = application.getProperties().getList(AuthenticationSettings.SAML_CREATE_NEW_USER_WITH_GROUPS,
",");
- String assertionConsumerUrl = String.format("%s/service/%s/%s/rest/saml", site.getDomain(), site.getName(),
+ ssoEndpoint = String.format("%s/service/%s/%s/rest/saml", site.getDomain(), site.getName(),
application.getName());
- samlClient = SamlClient.fromMetadata(clientId, assertionConsumerUrl,
+ samlClient = SamlClient.fromMetadata(clientId, ssoEndpoint,
new InputStreamReader(new ByteArrayInputStream(samlDescriptor)), SamlClient.SamlIdpBinding.POST);
LOGGER.info("Created SAML client '{}' with endpoint {}", clientId, samlClient.getIdentityProviderUrl());
} else {
@@ -121,7 +122,8 @@ public ResponseEntity reply(HttpServletRequest request, Environment enviro
try {
String parameter = request.getParameter("SAMLResponse");
SamlResponse samlResp = samlClient.decodeAndValidateSamlResponse(parameter, request.getMethod());
- LOGGER.debug("Received SAMLResponse for {}", samlResp.getNameID());
+ String email = samlResp.getNameID();
+ LOGGER.debug("Received SAMLResponse for {}", email);
Assertion assertion = samlResp.getAssertion();
Map> attributes = new HashMap<>();
@@ -138,7 +140,6 @@ public ResponseEntity reply(HttpServletRequest request, Environment enviro
}
// https://learn.microsoft.com/en-us/azure/active-directory/develop/reference-saml-tokens
- String email = attributes.get(CLAIM + "name").get(0);
Subject subject = coreService.getSubjectByEmail(email);
if (null == subject && !userGroups.isEmpty()) {
subject = createUser(environment, email, attributes);
@@ -176,7 +177,7 @@ public ResponseEntity reply(HttpServletRequest request, Environment enviro
}
private Subject createUser(Environment environment, String email, Map> attributes) {
- String givenname = attributes.get(CLAIM + "givenName").get(0);
+ String givenname = attributes.get(CLAIM + "givenname").get(0);
String surname = attributes.get(CLAIM + "surname").get(0);
String userName = StringUtils.lowerCase(StringNormalizer.normalize(givenname + "." + surname));
try {
@@ -216,4 +217,12 @@ public ResponseEntity logout(@RequestBody String payload) {
return new ResponseEntity<>(payload, HttpStatus.OK);
}
+ public boolean isEnabled() {
+ return samlEnabled;
+ }
+
+ public String getEndpoint() {
+ return ssoEndpoint;
+ }
+
}
\ No newline at end of file
diff --git a/src/main/java/org/appng/application/authentication/webform/LoginData.java b/src/main/java/org/appng/application/authentication/webform/LoginData.java
index 5e0c0ed..41150b6 100644
--- a/src/main/java/org/appng/application/authentication/webform/LoginData.java
+++ b/src/main/java/org/appng/application/authentication/webform/LoginData.java
@@ -19,6 +19,7 @@
import org.appng.api.NotBlank;
+import lombok.Getter;
import lombok.Setter;
@Setter
@@ -29,6 +30,7 @@ public class LoginData {
private String password;
private String passwordConfirmation;
private String digest;
+ private @Getter String ssoLink;
@NotBlank(groups = Login.class, message = "{username.required}")
public String getUsername() {
diff --git a/src/main/java/org/appng/application/authentication/webform/LoginForm.java b/src/main/java/org/appng/application/authentication/webform/LoginForm.java
index d84c54b..d9422df 100644
--- a/src/main/java/org/appng/application/authentication/webform/LoginForm.java
+++ b/src/main/java/org/appng/application/authentication/webform/LoginForm.java
@@ -37,24 +37,26 @@
import org.appng.api.support.SelectionFactory;
import org.appng.api.support.environment.DefaultEnvironment;
import org.appng.application.authentication.AbstractLogon;
+import org.appng.application.authentication.saml.SamlController;
import org.appng.core.domain.SubjectImpl;
import org.appng.xml.platform.Selection;
import org.appng.xml.platform.SelectionType;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
+@AllArgsConstructor
public class LoginForm implements DataProvider {
private static final String PARAM_LANG = "lang";
private static final String PARAM_ACTION = "action";
private static final String SLASH = "/";
- @Autowired
- SelectionFactory selectionFactory;
+ private final SelectionFactory selectionFactory;
+ private final SamlController samlController;
public DataContainer getData(Site site, Application application, Environment environment, Options options,
Request request, FieldProcessor fieldProcessor) {
@@ -63,7 +65,11 @@ public DataContainer getData(Site site, Application application, Environment env
if (null != langSelection) {
dataContainer.getSelections().add(langSelection);
}
- dataContainer.setItem(new LoginData());
+ LoginData loginData = new LoginData();
+ if(samlController.isEnabled()) {
+ loginData.setSsoLink(samlController.getEndpoint());
+ }
+ dataContainer.setItem(loginData);
((DefaultEnvironment) environment).getServletResponse()
.setHeader(com.google.common.net.HttpHeaders.CONTENT_SECURITY_POLICY, "frame-ancestors 'none'");
return dataContainer;
diff --git a/src/test/resources/xml/LoginUserTest-testLoginNoData.xml b/src/test/resources/xml/LoginUserTest-testLoginNoData.xml
index 8361b12..295ad20 100644
--- a/src/test/resources/xml/LoginUserTest-testLoginNoData.xml
+++ b/src/test/resources/xml/LoginUserTest-testLoginNoData.xml
@@ -34,6 +34,7 @@
{password.required}
+
@@ -50,6 +51,9 @@
+
+
+
diff --git a/src/test/resources/xml/LoginUserTest-testLoginOK.xml b/src/test/resources/xml/LoginUserTest-testLoginOK.xml
index ac64b16..acf9105 100644
--- a/src/test/resources/xml/LoginUserTest-testLoginOK.xml
+++ b/src/test/resources/xml/LoginUserTest-testLoginOK.xml
@@ -28,6 +28,7 @@
+
@@ -46,6 +47,9 @@
+
+
+
diff --git a/src/test/resources/xml/LoginUserTest-testLoginWrongPassword.xml b/src/test/resources/xml/LoginUserTest-testLoginWrongPassword.xml
index dc94098..fd5e95b 100644
--- a/src/test/resources/xml/LoginUserTest-testLoginWrongPassword.xml
+++ b/src/test/resources/xml/LoginUserTest-testLoginWrongPassword.xml
@@ -28,6 +28,7 @@
+
@@ -44,6 +45,9 @@
+
+
+