[java-identity-provider] branch main updated: Better refactoring of simple Principal serializers.

Scott Cantor cantor.2 at osu.edu
Thu Aug 27 18:28:58 UTC 2020


This is an automated email from the git hooks/post-receive script.

scantor pushed a commit to branch main
in repository java-identity-provider.

View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=a62438ed5a37049c79546353a442c38f1d36cd30

The following commit(s) were added to refs/heads/main by this push:
       new  a62438ed5 Better refactoring of simple Principal serializers.
a62438ed5 is described below

commit a62438ed5a37049c79546353a442c38f1d36cd30
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Thu Aug 27 14:28:50 2020 -0400

    Better refactoring of simple Principal serializers.
---
 .../authn/principal/SealedPrincipalSerializer.java | 125 ++++++++++++++
 .../authn/principal/SimplePrincipalSerializer.java | 163 ++++++++++++++++++
 .../idp/authn/duo/impl/DuoPrincipalSerializer.java | 101 -----------
 .../impl/PasswordPrincipalSerializer.java          | 184 ---------------------
 .../impl/UsernamePrincipalSerializer.java          | 104 ------------
 .../DefaultAuthenticationResultSerializerTest.java |  15 +-
 .../shibboleth/idp/conf/general-authn-system.xml   |   9 +-
 7 files changed, 303 insertions(+), 398 deletions(-)

diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/principal/SealedPrincipalSerializer.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/principal/SealedPrincipalSerializer.java
new file mode 100644
index 000000000..90946d954
--- /dev/null
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/principal/SealedPrincipalSerializer.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.authn.principal;
+
+import java.io.IOException;
+import java.security.Principal;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Strings;
+
+import net.shibboleth.utilities.java.support.annotation.ParameterName;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
+import net.shibboleth.utilities.java.support.security.DataSealer;
+import net.shibboleth.utilities.java.support.security.DataSealerException;
+
+/**
+ * Principal serializer that encrypts/decrypts the data when serializing.
+ * 
+ * @param <T> principal type
+ * 
+ * @since 4.1.0
+ */
+public class SealedPrincipalSerializer<T extends Principal> extends SimplePrincipalSerializer<T> {
+
+    /** Field name of password. */
+    @Nonnull @NotEmpty private static final String PASSWORD_FIELD = "PW";
+
+    /** Class logger. */
+    @Nonnull private final Logger log = LoggerFactory.getLogger(SealedPrincipalSerializer.class);
+
+    /** Data sealer. */
+    @Nullable private DataSealer sealer;
+    
+    /**
+     * Constructor.
+     *
+     * @param claz principal type
+     * @param name field name of JSON structure
+     * 
+     * @throws SecurityException if the constructor cannot be accessed 
+     * @throws NoSuchMethodException if the constructor does not exist
+     */
+    public SealedPrincipalSerializer(@Nonnull @ParameterName(name="claz") final Class<T> claz,
+            @Nonnull @NotEmpty @ParameterName(name="name") final String name)
+                    throws NoSuchMethodException, SecurityException {
+        super(claz, name);
+    }
+
+    /**
+     * Set the {@link DataSealer} to use.
+     * 
+     * @param theSealer encrypting component to use
+     */
+    public void setDataSealer(@Nullable final DataSealer theSealer) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+        
+        sealer = theSealer;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean supports(@Nonnull final Principal principal) {
+        if (sealer == null) {
+            log.error("No DataSealer was provided, unable to support serialization");
+            return false;
+        }
+        return super.supports(principal);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean supports(@Nonnull @NotEmpty final String value) {
+        if (sealer == null) {
+            log.error("No DataSealer was provided, unable to support deserialization");
+            return false;
+        }
+        return super.supports(value);
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    protected String getName(@Nonnull final Principal principal) throws IOException {
+        try {
+            return sealer.wrap(super.getName(principal));
+        } catch (final DataSealerException e) {
+            throw new IOException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected String getName(@Nullable final String serializedName) throws IOException {
+        if (!Strings.isNullOrEmpty(serializedName)) {
+            try {
+                return sealer.unwrap(serializedName);
+            } catch (final DataSealerException e) {
+                throw new IOException(e);
+            }
+        }
+        
+        return null;
+    }
+    
+}
\ No newline at end of file
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/principal/SimplePrincipalSerializer.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/principal/SimplePrincipalSerializer.java
new file mode 100644
index 000000000..6f751136b
--- /dev/null
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/principal/SimplePrincipalSerializer.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.authn.principal;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.lang.reflect.Constructor;
+import java.security.Principal;
+import java.util.regex.Pattern;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+import javax.json.JsonException;
+import javax.json.JsonObject;
+import javax.json.JsonReader;
+import javax.json.JsonString;
+import javax.json.JsonStructure;
+import javax.json.stream.JsonGenerator;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Strings;
+
+import net.shibboleth.utilities.java.support.annotation.ParameterName;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+
+/**
+ * Principal serializer for string-based principals that serialize to a simple JSON structure.
+ * 
+ * @param <T> principal type
+ * 
+ * @since 4.1.0
+ */
+ at ThreadSafe
+public class SimplePrincipalSerializer<T extends Principal> extends AbstractPrincipalSerializer<String> {
+
+    /** Class logger. */
+    @Nonnull private final Logger log = LoggerFactory.getLogger(SimplePrincipalSerializer.class);
+
+    /** Principal type. */
+    @Nonnull private final Class<T> principalType;
+
+    /** Constructor. */
+    @Nonnull private final Constructor<T> ctor;
+    
+    /** Field name. */
+    @Nonnull @NotEmpty private final String fieldName;
+
+    /** Pattern used to determine if input is supported. */
+    @Nonnull private final Pattern jsonPattern;
+
+    /**
+     * Constructor.
+     * 
+     * @param claz principal type
+     * @param name field name of JSON structure
+     * 
+     * @throws SecurityException if the constructor cannot be accessed 
+     * @throws NoSuchMethodException if the constructor does not exist
+     */
+    public SimplePrincipalSerializer(@Nonnull @ParameterName(name="claz") final Class<T> claz,
+            @Nonnull @NotEmpty @ParameterName(name="name") final String name)
+                    throws NoSuchMethodException, SecurityException {
+        
+        principalType = Constraint.isNotNull(claz, "Principal type cannot be null");
+        ctor = principalType.getConstructor(String.class);
+        fieldName = Constraint.isNotNull(StringSupport.trimOrNull(name), "Field name cannot be empty or null");
+        jsonPattern = Pattern.compile("^\\{\"" + fieldName + "\":.*\\}$");
+    }
+    
+    /** {@inheritDoc} */
+    public boolean supports(@Nonnull final Principal principal) {
+        return principalType.isInstance(principal);
+    }
+
+    /** {@inheritDoc} */
+    @Nonnull @NotEmpty public String serialize(@Nonnull final Principal principal) throws IOException {
+        final StringWriter sink = new StringWriter(32);
+        try (final JsonGenerator gen = getJsonGenerator(sink)) {
+            gen.writeStartObject()
+                .write(fieldName, getName(principal))
+                .writeEnd();
+        }
+        return sink.toString();
+    }
+    
+    /**
+     * Return the appropriate value to serialize from the input object.
+     * 
+     * @param principal input object
+     * 
+     * @return the value to serialize.
+     * 
+     * @throws IOException if an error occurs
+     */
+    @Nonnull @NotEmpty protected String getName(@Nonnull final Principal principal) throws IOException {
+        return principal.getName();
+    }
+
+    /** {@inheritDoc} */
+    public boolean supports(@Nonnull @NotEmpty final String value) {
+        return jsonPattern.matcher(value).matches();
+    }
+
+    /** {@inheritDoc} */
+    @Nullable public T deserialize(@Nonnull @NotEmpty final String value) throws IOException {
+        
+        try (final JsonReader reader = getJsonReader(new StringReader(value))) {
+            
+            final JsonStructure st = reader.read();
+            if (!(st instanceof JsonObject)) {
+                throw new IOException("Found invalid data structure while parsing " + principalType.getSimpleName());
+            }
+            
+            final JsonString str = ((JsonObject) st).getJsonString(fieldName);
+            if (str != null) {
+                final String name = getName(str.getString());
+                if (!Strings.isNullOrEmpty(name)) {
+                    return ctor.newInstance(name);
+                }
+            }
+            return null;
+        } catch (final JsonException e) {
+            throw new IOException("Found invalid data structure while parsing " + principalType.getSimpleName(), e);
+        } catch (final ReflectiveOperationException e) {
+            throw new IOException("Unable to reflectively create " + principalType.getSimpleName(), e);
+        }
+    }
+
+    /**
+     * Return the appropriate value to create the {@link Principal} around based on the serialized form.
+     * 
+     * @param serializedName the value in the serialization.
+     * 
+     * @return the transformed value
+     * 
+     * @throws IOException if an error occurs 
+     */
+    @Nullable protected String getName(@Nullable final String serializedName) throws IOException {
+        return serializedName;
+    }
+    
+}
\ No newline at end of file
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/duo/impl/DuoPrincipalSerializer.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/duo/impl/DuoPrincipalSerializer.java
deleted file mode 100644
index fe865c5ce..000000000
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/duo/impl/DuoPrincipalSerializer.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Licensed to the University Corporation for Advanced Internet Development,
- * Inc. (UCAID) under one or more contributor license agreements.  See the
- * NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The UCAID licenses this file to You under the Apache
- * License, Version 2.0 (the "License"); you may not use this file except in
- * compliance with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.authn.duo.impl;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.security.Principal;
-import java.util.regex.Pattern;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.ThreadSafe;
-import javax.json.JsonException;
-import javax.json.JsonObject;
-import javax.json.JsonReader;
-import javax.json.JsonString;
-import javax.json.JsonStructure;
-import javax.json.stream.JsonGenerator;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Strings;
-
-import net.shibboleth.idp.authn.duo.DuoPrincipal;
-import net.shibboleth.idp.authn.principal.AbstractPrincipalSerializer;
-import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
-
-/**
- * Principal serializer for {@link DuoPrincipal}.
- */
- at ThreadSafe
-public class DuoPrincipalSerializer extends AbstractPrincipalSerializer<String> {
-
-    /** Field name of {@link DuoPrincipal}. */
-    @Nonnull @NotEmpty private static final String DUO_FIELD = "DUO";
-
-    /** Pattern used to determine if input is supported. */
-    @Nonnull private static final Pattern JSON_PATTERN = Pattern.compile("^\\{\"DUO\":.*\\}$");
-
-    /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(DuoPrincipalSerializer.class);
-
-    /** {@inheritDoc} */
-    public boolean supports(@Nonnull final Principal principal) {
-        return principal instanceof DuoPrincipal;
-    }
-
-    /** {@inheritDoc} */
-    @Nonnull @NotEmpty public String serialize(@Nonnull final Principal principal) throws IOException {
-        final StringWriter sink = new StringWriter(32);
-        try (final JsonGenerator gen = getJsonGenerator(sink)) {
-            gen.writeStartObject()
-                .write(DUO_FIELD, principal.getName())
-                .writeEnd();
-        }
-        return sink.toString();
-    }
-
-    /** {@inheritDoc} */
-    public boolean supports(@Nonnull @NotEmpty final String value) {
-        return JSON_PATTERN.matcher(value).matches();
-    }
-
-    /** {@inheritDoc} */
-    @Nullable public DuoPrincipal deserialize(@Nonnull @NotEmpty final String value) throws IOException {
-        try (final JsonReader reader = getJsonReader(new StringReader(value))) {
-            final JsonStructure st = reader.read();
-            if (!(st instanceof JsonObject)) {
-                throw new IOException("Found invalid data structure while parsing DuoPrincipal");
-            }
-            final JsonString str = ((JsonObject) st).getJsonString(DUO_FIELD);
-            if (str != null) {
-                final String username = str.getString();
-                if (!Strings.isNullOrEmpty(username)) {
-                    return new DuoPrincipal(username);
-                }
-            }
-            return null;
-        } catch (final JsonException e) {
-            throw new IOException("Found invalid data structure while parsing DuoPrincipal", e);
-        }
-    }
-
-}
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/principal/impl/PasswordPrincipalSerializer.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/principal/impl/PasswordPrincipalSerializer.java
deleted file mode 100644
index 7299bd57a..000000000
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/principal/impl/PasswordPrincipalSerializer.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Licensed to the University Corporation for Advanced Internet Development,
- * Inc. (UCAID) under one or more contributor license agreements.  See the
- * NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The UCAID licenses this file to You under the Apache
- * License, Version 2.0 (the "License"); you may not use this file except in
- * compliance with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.authn.principal.impl;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.security.Principal;
-import java.time.Duration;
-import java.time.Instant;
-import java.util.regex.Pattern;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.ThreadSafe;
-import javax.json.Json;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonException;
-import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
-import javax.json.JsonReader;
-import javax.json.JsonString;
-import javax.json.JsonStructure;
-import javax.json.stream.JsonGenerator;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Strings;
-
-import net.shibboleth.idp.authn.principal.AbstractPrincipalSerializer;
-import net.shibboleth.idp.authn.principal.PasswordPrincipal;
-import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
-import net.shibboleth.utilities.java.support.component.ComponentSupport;
-import net.shibboleth.utilities.java.support.security.DataSealer;
-import net.shibboleth.utilities.java.support.security.DataSealerException;
-
-/**
- * Principal serializer for {@link PasswordPrincipal} that encrypts the password.
- */
- at ThreadSafe
-public class PasswordPrincipalSerializer extends AbstractPrincipalSerializer<String> {
-
-    /** Field name of password. */
-    @Nonnull @NotEmpty private static final String PASSWORD_FIELD = "PW";
-
-    /** Pattern used to determine if input is supported. */
-    private static final Pattern JSON_PATTERN = Pattern.compile("^\\{\"PW\":.*\\}$");
-
-    /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(PasswordPrincipalSerializer.class);
-
-    /** Data sealer. */
-    @Nullable private DataSealer sealer;
-    
-    /** JSON object bulder factory. */
-    @Nonnull private final JsonBuilderFactory objectBuilderFactory;
-
-    /** Constructor. */
-    public PasswordPrincipalSerializer() {
-        objectBuilderFactory = Json.createBuilderFactory(null);
-    }
-    
-    /**
-     * Set the {@link DataSealer} to use.
-     * 
-     * @param theSealer encrypting component to use
-     */
-    public void setDataSealer(@Nullable final DataSealer theSealer) {
-        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
-        
-        sealer = theSealer;
-    }
-
-    /** {@inheritDoc} */
-    public boolean supports(@Nonnull final Principal principal) {
-        if (principal instanceof PasswordPrincipal) {
-            if (sealer == null) {
-                log.error("No DataSealer was provided, unable to support PasswordPrincipal serialization");
-                return false;
-            }
-            return true;
-        }
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    @Nonnull @NotEmpty public String serialize(@Nonnull final Principal principal) throws IOException {
-        
-        if (sealer == null) {
-            throw new IOException("No DataSealer was provided, unable to support PasswordPrincipal serialization");
-        }
-        
-        final StringWriter sink = new StringWriter(32);
-        try (final JsonGenerator gen = getJsonGenerator(sink)) {
-            gen.writeStartObject()
-               .write(PASSWORD_FIELD, sealer.wrap(principal.getName(),
-                       Instant.now().plus(Duration.ofDays(365))))
-               .writeEnd();
-        } catch (final DataSealerException e) {
-            throw new IOException(e);
-        }
-        return sink.toString();
-    }
-    
-    /** {@inheritDoc} */
-    public boolean supports(@Nonnull @NotEmpty final String value) {
-        if (JSON_PATTERN.matcher(value).matches()) {
-            if (sealer == null) {
-                log.error("No DataSealer was provided, unable to support PasswordPrincipal deserialization");
-                return false;
-            }
-            return true;
-        }
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    @Nullable public PasswordPrincipal deserialize(@Nonnull @NotEmpty final String value) throws IOException {
-        
-        if (sealer == null) {
-            throw new IOException("No DataSealer was provided, unable to support PasswordPrincipal deserialization");
-        }
-
-        try (final JsonReader reader = getJsonReader(new StringReader(value))) {
-            
-            final JsonStructure st = reader.read();
-            if (!(st instanceof JsonObject)) {
-                throw new IOException("Found invalid data structure while parsing PasswordPrincipal");
-            }
-            
-            final JsonObject obj = (JsonObject) st;
-            final JsonString str = obj.getJsonString(PASSWORD_FIELD);
-            if (str != null) {
-                if (!Strings.isNullOrEmpty(str.getString())) {
-                    try {
-                        return new PasswordPrincipal(sealer.unwrap(str.getString()));
-                    } catch (final DataSealerException e) {
-                        throw new IOException(e);
-                    }
-                }
-                log.warn("Skipping null/empty PasswordPrincipal");
-            }
-            return null;
-        } catch (final JsonException e) {
-            throw new IOException("Found invalid data structure while parsing PasswordPincipal", e);
-        }
-    }
-
-    /**
-     * Get a {@link JsonObjectBuilder} in a thread-safe manner.
-     * 
-     * @return  an object builder
-     */
-    @Nonnull private synchronized JsonObjectBuilder getJsonObjectBuilder() {
-        return objectBuilderFactory.createObjectBuilder();
-    }
-
-    /**
-     * Get a {@link JsonArrayBuilder} in a thread-safe manner.
-     * 
-     * @return  an array builder
-     */
-    @Nonnull private synchronized JsonArrayBuilder getJsonArrayBuilder() {
-        return objectBuilderFactory.createArrayBuilder();
-    }
-    
-}
\ No newline at end of file
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/principal/impl/UsernamePrincipalSerializer.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/principal/impl/UsernamePrincipalSerializer.java
deleted file mode 100644
index 7b7993a42..000000000
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/principal/impl/UsernamePrincipalSerializer.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Licensed to the University Corporation for Advanced Internet Development,
- * Inc. (UCAID) under one or more contributor license agreements.  See the
- * NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The UCAID licenses this file to You under the Apache
- * License, Version 2.0 (the "License"); you may not use this file except in
- * compliance with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.authn.principal.impl;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.security.Principal;
-import java.util.regex.Pattern;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.ThreadSafe;
-import javax.json.JsonException;
-import javax.json.JsonObject;
-import javax.json.JsonReader;
-import javax.json.JsonString;
-import javax.json.JsonStructure;
-import javax.json.stream.JsonGenerator;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Strings;
-
-import net.shibboleth.idp.authn.principal.AbstractPrincipalSerializer;
-import net.shibboleth.idp.authn.principal.UsernamePrincipal;
-import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
-
-/**
- * Principal serializer for {@link UsernamePrincipal}.
- */
- at ThreadSafe
-public class UsernamePrincipalSerializer extends AbstractPrincipalSerializer<String> {
-
-    /** Field name of {@link UsernamePrincipal}. */
-    @Nonnull @NotEmpty private static final String USERNAME_FIELD = "U";
-
-    /** Pattern used to determine if input is supported. */
-    @Nonnull private static final Pattern JSON_PATTERN = Pattern.compile("^\\{\"U\":.*\\}$");
-
-    /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(UsernamePrincipalSerializer.class);
-
-    /** {@inheritDoc} */
-    public boolean supports(@Nonnull final Principal principal) {
-        return principal instanceof UsernamePrincipal;
-    }
-
-    /** {@inheritDoc} */
-    @Nonnull @NotEmpty public String serialize(@Nonnull final Principal principal) throws IOException {
-        final StringWriter sink = new StringWriter(32);
-        try (final JsonGenerator gen = getJsonGenerator(sink)) {
-            gen.writeStartObject()
-                .write(USERNAME_FIELD, principal.getName())
-                .writeEnd();
-        }
-        return sink.toString();
-    }
-
-    /** {@inheritDoc} */
-    public boolean supports(@Nonnull @NotEmpty final String value) {
-        return JSON_PATTERN.matcher(value).matches();
-    }
-
-    /** {@inheritDoc} */
-    @Nullable public UsernamePrincipal deserialize(@Nonnull @NotEmpty final String value) throws IOException {
-        
-        try (final JsonReader reader = getJsonReader(new StringReader(value))) {
-            
-            final JsonStructure st = reader.read();
-            if (!(st instanceof JsonObject)) {
-                throw new IOException("Found invalid data structure while parsing UsernamePrincipal");
-            }
-            
-            final JsonString str = ((JsonObject) st).getJsonString(USERNAME_FIELD);
-            if (str != null) {
-                final String username = str.getString();
-                if (!Strings.isNullOrEmpty(username)) {
-                    return new UsernamePrincipal(username);
-                }
-            }
-            return null;
-        } catch (final JsonException e) {
-            throw new IOException("Found invalid data structure while parsing UsernamePrincipal", e);
-        }
-    }
-
-}
\ No newline at end of file
diff --git a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/DefaultAuthenticationResultSerializerTest.java b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/DefaultAuthenticationResultSerializerTest.java
index dbe327c0f..2206085d5 100644
--- a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/DefaultAuthenticationResultSerializerTest.java
+++ b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/DefaultAuthenticationResultSerializerTest.java
@@ -44,13 +44,13 @@ import net.shibboleth.idp.authn.principal.IdPAttributePrincipal;
 import net.shibboleth.idp.authn.principal.PasswordPrincipal;
 import net.shibboleth.idp.authn.principal.PrincipalServiceManager;
 import net.shibboleth.idp.authn.principal.ProxyAuthenticationPrincipal;
+import net.shibboleth.idp.authn.principal.SealedPrincipalSerializer;
+import net.shibboleth.idp.authn.principal.SimplePrincipalSerializer;
 import net.shibboleth.idp.authn.principal.TestPrincipal;
 import net.shibboleth.idp.authn.principal.UsernamePrincipal;
 import net.shibboleth.idp.authn.principal.impl.IdPAttributePrincipalSerializer;
 import net.shibboleth.idp.authn.principal.impl.LDAPPrincipalSerializer;
-import net.shibboleth.idp.authn.principal.impl.PasswordPrincipalSerializer;
 import net.shibboleth.idp.authn.principal.impl.ProxyAuthenticationPrincipalSerializer;
-import net.shibboleth.idp.authn.principal.impl.UsernamePrincipalSerializer;
 import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
 import net.shibboleth.utilities.java.support.resource.TestResourceConverter;
 import net.shibboleth.utilities.java.support.security.DataSealer;
@@ -87,9 +87,10 @@ public class DefaultAuthenticationResultSerializerTest {
     
     private AuthenticationFlowDescriptor flowDescriptor;
     
-    @BeforeMethod public void setUp() throws ComponentInitializationException {
+    @BeforeMethod public void setUp() throws ComponentInitializationException, NoSuchMethodException, SecurityException {
 
-        final UsernamePrincipalSerializer upSerializer = new UsernamePrincipalSerializer();
+        final SimplePrincipalSerializer<UsernamePrincipal> upSerializer =
+                new SimplePrincipalSerializer<>(UsernamePrincipal.class, "U");
         upSerializer.initialize();
         final GenericPrincipalService<UsernamePrincipal> upService =
                 new GenericPrincipalService<>(UsernamePrincipal.class, upSerializer);
@@ -137,10 +138,12 @@ public class DefaultAuthenticationResultSerializerTest {
             fail(e.getMessage());
         }
 
-        final PasswordPrincipalSerializer pwSerializer = new PasswordPrincipalSerializer();
+        final SealedPrincipalSerializer<PasswordPrincipal> pwSerializer =
+                new SealedPrincipalSerializer<>(PasswordPrincipal.class, "PW");
         pwSerializer.setDataSealer(sealer);
         pwSerializer.initialize();
-        final GenericPrincipalService<PasswordPrincipal> pwService = new GenericPrincipalService<>(PasswordPrincipal.class, pwSerializer);
+        final GenericPrincipalService<PasswordPrincipal> pwService =
+                new GenericPrincipalService<>(PasswordPrincipal.class, pwSerializer);
         pwService.setId("password");
         pwService.initialize();
         
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/general-authn-system.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/general-authn-system.xml
index 99b9a3b08..d1e8a173f 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/general-authn-system.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/general-authn-system.xml
@@ -342,14 +342,16 @@
     <bean p:id="username" class="net.shibboleth.idp.authn.principal.GenericPrincipalService"
             c:claz="net.shibboleth.idp.authn.principal.UsernamePrincipal">
         <constructor-arg name="serializer">
-            <bean class="net.shibboleth.idp.authn.principal.impl.UsernamePrincipalSerializer" />
+            <bean class="net.shibboleth.idp.authn.principal.SimplePrincipalSerializer"
+                c:claz="net.shibboleth.idp.authn.principal.UsernamePrincipal" c:name="U" />
         </constructor-arg>
     </bean>
 
     <bean p:id="password" class="net.shibboleth.idp.authn.principal.GenericPrincipalService"
             c:claz="net.shibboleth.idp.authn.principal.PasswordPrincipal">
         <constructor-arg name="serializer">
-            <bean class="net.shibboleth.idp.authn.principal.impl.PasswordPrincipalSerializer"
+            <bean class="net.shibboleth.idp.authn.principal.SealedPrincipalSerializer"
+                c:claz="net.shibboleth.idp.authn.principal.PasswordPrincipal" c:name="PW"
                 p:dataSealer="#{(systemProperties.contains('idp.sealer.storeResource') or systemProperties.contains('idp.sealer.keyStrategy')) ? getObject('shibboleth.DataSealer') : null}" />
         </constructor-arg>
     </bean>
@@ -357,7 +359,8 @@
     <bean p:id="duo" class="net.shibboleth.idp.authn.principal.GenericPrincipalService"
             c:claz="net.shibboleth.idp.authn.duo.DuoPrincipal">
         <constructor-arg name="serializer">
-            <bean class="net.shibboleth.idp.authn.duo.impl.DuoPrincipalSerializer" />
+            <bean class="net.shibboleth.idp.authn.principal.SimplePrincipalSerializer"
+                c:claz="net.shibboleth.idp.authn.duo.DuoPrincipal" c:name="DUO" />
         </constructor-arg>
     </bean>
 

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list