diff --git a/pom.xml b/pom.xml index 24bc2ba..e9ecbe8 100644 --- a/pom.xml +++ b/pom.xml @@ -3,12 +3,12 @@ 4.0.0 net.hostsharing.cas casauthhsadmin - 1.0.4 + 1.2.0 CAS Auth HSAdmin - 11 + 21 UTF-8 - 6.4.4.2 + 7.0.3 diff --git a/src/main/java/net/hostsharing/cas/auth/HostsharingAuthEventExecutionPlanConfiguration.java b/src/main/java/net/hostsharing/cas/auth/HostsharingAuthEventExecutionPlanConfiguration.java deleted file mode 100644 index c13aa88..0000000 --- a/src/main/java/net/hostsharing/cas/auth/HostsharingAuthEventExecutionPlanConfiguration.java +++ /dev/null @@ -1,46 +0,0 @@ -package net.hostsharing.cas.auth; - -import org.apereo.cas.authentication.AuthenticationEventExecutionPlan; -import org.apereo.cas.authentication.AuthenticationEventExecutionPlanConfigurer; -import org.apereo.cas.authentication.AuthenticationHandler; -import org.apereo.cas.authentication.principal.PrincipalFactory; -import org.apereo.cas.authentication.principal.PrincipalFactoryUtils; -import org.apereo.cas.authentication.principal.PrincipalResolver; -import org.apereo.cas.services.ServicesManager; -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.context.annotation.Bean; - -public class HostsharingAuthEventExecutionPlanConfiguration implements AuthenticationEventExecutionPlanConfigurer { - - @Autowired - @Qualifier("servicesManager") - private ObjectProvider servicesManager; - - @Autowired - @Qualifier("defaultPrincipalResolver") - private ObjectProvider defaultPrincipalResolver; - - @ConditionalOnMissingBean(name = "hostsharingAuthenticationPrincipalFactory") - @Bean - @RefreshScope - public PrincipalFactory hostsharingAuthenticationPrincipalFactory() { - return PrincipalFactoryUtils.newPrincipalFactory(); - } - - - @Bean - public AuthenticationHandler myAuthenticationHandler() { - final String name = "Hostsharing Authentication"; - return new HostsharingAuthenticationHandler(name, servicesManager.getObject(), hostsharingAuthenticationPrincipalFactory()); - } - - @Override - public void configureAuthenticationExecutionPlan(AuthenticationEventExecutionPlan plan) { - plan.registerAuthenticationHandler(myAuthenticationHandler()); - } - -} diff --git a/src/main/java/net/hostsharing/cas/auth/HostsharingAuthenticationHandler.java b/src/main/java/net/hostsharing/cas/auth/HostsharingAuthenticationHandler.java index 6cb4d2f..dc4f658 100644 --- a/src/main/java/net/hostsharing/cas/auth/HostsharingAuthenticationHandler.java +++ b/src/main/java/net/hostsharing/cas/auth/HostsharingAuthenticationHandler.java @@ -3,6 +3,8 @@ package net.hostsharing.cas.auth; import java.io.IOException; import java.io.InputStream; import java.io.Serializable; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import java.security.GeneralSecurityException; import java.util.ArrayList; @@ -18,7 +20,7 @@ import org.apache.xmlrpc.XmlRpcException; import org.apache.xmlrpc.client.XmlRpcClient; import org.apache.xmlrpc.client.XmlRpcClientConfigImpl; import org.apereo.cas.authentication.AuthenticationHandlerExecutionResult; -import org.apereo.cas.authentication.CoreAuthenticationUtils; +import org.apereo.cas.authentication.MessageDescriptor; import org.apereo.cas.authentication.PreventedException; import org.apereo.cas.authentication.credential.UsernamePasswordCredential; import org.apereo.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler; @@ -31,8 +33,8 @@ import org.xml.sax.SAXException; public class HostsharingAuthenticationHandler extends AbstractUsernamePasswordAuthenticationHandler { - public HostsharingAuthenticationHandler(String name, ServicesManager servicesManager, PrincipalFactory principalFactory) { - super(name, servicesManager, principalFactory, Integer.MAX_VALUE); + protected HostsharingAuthenticationHandler(String name, ServicesManager servicesManager, PrincipalFactory principalFactory, Integer order) { + super(name, servicesManager, principalFactory, order); } @Override @@ -40,27 +42,29 @@ public class HostsharingAuthenticationHandler extends AbstractUsernamePasswordAu throws GeneralSecurityException, PreventedException { final String username = credential.getUsername(); - final String password = credential.getPassword(); + final String password = new String(credential.getPassword()); try { final Map> attributes = validateCredentials(username, password); final Principal principal = this.principalFactory.createPrincipal(username, attributes); - return createHandlerResult(credential, principal); + List list = new ArrayList<>(); + return createHandlerResult(credential, principal, list); - } catch (PasswordValidationException | IOException | XmlRpcException | ParserConfigurationException | SAXException e) { + } catch (Throwable e) { throw new GeneralSecurityException(e); } } private static Map> validateCredentials(final String login, final String password) - throws PasswordValidationException, XmlRpcException, GeneralSecurityException, IOException, ParserConfigurationException, SAXException { + throws PasswordValidationException, XmlRpcException, GeneralSecurityException, IOException, ParserConfigurationException, SAXException, URISyntaxException { if (!login.contains("@")) { throw new GeneralSecurityException("expect email address"); } final String emailDomain = login.split("@")[1]; - final URL url = new URL("http://" + emailDomain + "/.well-known/autoconfig/mail/config-v1.1.xml?emailaddress=" + login); + final URI autoconfigURI = new URI("http://" + emailDomain + "/.well-known/autoconfig/mail/config-v1.1.xml?emailaddress=" + login); + final URL url = autoconfigURI.toURL(); final InputStream autoconfigStream = url.openConnection().getInputStream(); final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); final DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); @@ -78,7 +82,8 @@ public class HostsharingAuthenticationHandler extends AbstractUsernamePasswordAu final String ticket = ticketService.getServiceTicket(grantingTicket); final XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl(); - config.setServerURL(new URL("https://config.hostsharing.net:443/hsar/xmlrpc/hsadmin")); + final URI hsadminURI = new URI("https://config.hostsharing.net:443/hsar/xmlrpc/hsadmin"); + config.setServerURL(hsadminURI.toURL()); config.setEnabledForExtensions(true); final XmlRpcClient client = new XmlRpcClient(); client.setConfig(config); @@ -96,23 +101,23 @@ public class HostsharingAuthenticationHandler extends AbstractUsernamePasswordAu @SuppressWarnings("unchecked") final Map userData = (Map) rpcResult[0]; final String comment = (String) userData.get("comment"); - int firstCommaIndex = comment.indexOf(','); + int firstDotIndex = comment.indexOf('.'); String displayName = comment; - String[] groups = new String[0]; - if (firstCommaIndex > 0) { - displayName = comment.substring(0, firstCommaIndex).trim(); - final String[] splitStrings = comment.substring(firstCommaIndex + 1).split(","); + Object[] groups = new String[0]; + if (firstDotIndex > 0) { + displayName = comment.substring(0, firstDotIndex).trim(); + final String groupsPart = comment.substring(firstDotIndex + 1); + final String[] splitStrings = groupsPart.split("\\."); groups = new String[splitStrings.length]; for (int idx=0; idx attribsMap = new HashMap(); - attribsMap.put("groups", groups); - attribsMap.put("displayName", displayName); - attribsMap.put("mail", login); - final Map> attributes = CoreAuthenticationUtils.convertAttributeValuesToMultiValuedObjects(attribsMap); - return attributes; + final Map> attribsMap = new HashMap>(); + attribsMap.put("groups", List.of(groups)); + attribsMap.put("displayName", List.of(displayName)); + attribsMap.put("mail", List.of(login)); + return attribsMap; } public static void main(String[] args) { @@ -121,8 +126,7 @@ public class HostsharingAuthenticationHandler extends AbstractUsernamePasswordAu for (String key : map.keySet()) { System.out.println(key + ": " + map.get(key)); } - } catch (IOException | PasswordValidationException | XmlRpcException | GeneralSecurityException | ParserConfigurationException | SAXException e) { - // TODO Auto-generated catch block + } catch (IOException | PasswordValidationException | XmlRpcException | GeneralSecurityException | ParserConfigurationException | SAXException | URISyntaxException e) { e.printStackTrace(); } } diff --git a/src/main/java/net/hostsharing/cas/auth/HostsharingEMailAuthenticationConfiguration.java b/src/main/java/net/hostsharing/cas/auth/HostsharingEMailAuthenticationConfiguration.java new file mode 100644 index 0000000..a3006a0 --- /dev/null +++ b/src/main/java/net/hostsharing/cas/auth/HostsharingEMailAuthenticationConfiguration.java @@ -0,0 +1,38 @@ +package net.hostsharing.cas.auth; + +import org.apereo.cas.authentication.AuthenticationEventExecutionPlanConfigurer; +import org.apereo.cas.authentication.AuthenticationHandler; +import org.apereo.cas.authentication.principal.PrincipalFactoryUtils; +import org.apereo.cas.configuration.CasConfigurationProperties; +import org.apereo.cas.services.ServicesManager; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; + +@AutoConfiguration +@EnableConfigurationProperties(CasConfigurationProperties.class) +public class HostsharingEMailAuthenticationConfiguration { + + @Autowired + @Qualifier("servicesManager") + private ObjectProvider servicesManager; + + @Bean + public AuthenticationHandler emailAuthenticationConfiguration(final CasConfigurationProperties casProperties) { + + return new HostsharingAuthenticationHandler("Hostsharing EMail", servicesManager.getObject(), + PrincipalFactoryUtils.newPrincipalFactory(), Integer.valueOf(1)); + } + + @Bean + public AuthenticationEventExecutionPlanConfigurer emailAuthenticationPlan( + @Qualifier("emailAuthenticationConfiguration") + final AuthenticationHandler emailAuthenticationConfiguration) { + return plan -> { + plan.registerAuthenticationHandler(emailAuthenticationConfiguration); + }; + } +} diff --git a/src/main/java/net/hostsharing/cas/auth/TicketService.java b/src/main/java/net/hostsharing/cas/auth/TicketService.java index 5dec238..6fd7d5d 100644 --- a/src/main/java/net/hostsharing/cas/auth/TicketService.java +++ b/src/main/java/net/hostsharing/cas/auth/TicketService.java @@ -4,6 +4,7 @@ import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.InputStreamReader; import java.io.OutputStreamWriter; +import java.net.URI; import java.net.URL; import java.net.URLEncoder; @@ -31,8 +32,8 @@ public class TicketService { String userParam = "username=" + URLEncoder.encode(user, "UTF-8"); String passwordParam = "password=" + URLEncoder.encode(password, "UTF-8"); String encodedData = userParam + "&" + passwordParam; - URL url = new URL("https://login.hostsharing.net/cas/v1/tickets"); - + final URI uri = new URI("https://login.hostsharing.net/cas/v1/tickets"); + final URL url = uri.toURL(); final HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-type", "application/x-www-form-urlencoded; charset=UTF-8"); @@ -55,8 +56,9 @@ public class TicketService { public String getServiceTicket(String grantingTicket) throws PasswordValidationException { String ticket = null; try { - String serviceParam = "service=" + URLEncoder.encode("https://config.hostsharing.net:443/hsar/backend", "UTF-8"); - URL url = new URL(grantingTicket); + final String serviceParam = "service=" + URLEncoder.encode("https://config.hostsharing.net:443/hsar/backend", "UTF-8"); + final URI uri = new URI(grantingTicket); + final URL url = uri.toURL(); final HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.setRequestMethod("POST"); diff --git a/src/main/resources/META-INF/spring.factories b/src/main/resources/META-INF/spring.factories deleted file mode 100644 index aea3009..0000000 --- a/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=net.hostsharing.cas.auth.HostsharingAuthEventExecutionPlanConfiguration diff --git a/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..403a302 --- /dev/null +++ b/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +net.hostsharing.cas.auth.HostsharingEMailAuthenticationConfiguration