[java-idp-plugin-webauthn] branch main updated: Simplify registration views

Phil Smart philip.smart at jisc.ac.uk
Mon Feb 19 14:51:54 UTC 2024


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

philsmart pushed a commit to branch main
in repository java-idp-plugin-webauthn.

View the commit online:
http://git.shibboleth.net/view/?p=java-idp-plugin-webauthn.git;a=commit;h=1ba62aae35f05e12fb9545571c48f9a6a09c610b

The following commit(s) were added to refs/heads/main by this push:
     new 1ba62aa  Simplify registration views
1ba62aa is described below

commit 1ba62aae35f05e12fb9545571c48f9a6a09c610b
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Mon Feb 19 14:51:51 2024 +0000

    Simplify registration views
    
     - Use a single view and cycle the flow to the view until the user
    clicks on Finish.
---
 .../CreatePublicKeyCredentialCreationOptions.java  |  1 -
 .../webauthn-registration-flow.xml                 | 36 ++-------
 .../idp/plugin/authn/webauthn/css/webauthn.css     |  4 +
 .../idp/plugin/authn/webauthn/module.properties    | 25 +++---
 .../authn/webauthn/views/webauthn-register.vm      | 74 +++++++++---------
 .../authn/webauthn/views/webauthn-registered.vm    | 90 ----------------------
 6 files changed, 58 insertions(+), 172 deletions(-)

diff --git a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/CreatePublicKeyCredentialCreationOptions.java b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/CreatePublicKeyCredentialCreationOptions.java
index 99b7e17..ebba6d8 100644
--- a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/CreatePublicKeyCredentialCreationOptions.java
+++ b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/CreatePublicKeyCredentialCreationOptions.java
@@ -137,7 +137,6 @@ public class CreatePublicKeyCredentialCreationOptions extends AbstractWebAuthnRe
                     .withExcludeCredentials(existingCredentialDescriptors)
                     .withUsername(username)
                     .withResidentKeyRequirement(residentKeyRequirement)
-                    // Set the userId as the user handle
                     .withUserId(userId)
                     .withAttestationConveyancePreference(attestationPreference)
                     .withAuthenticatorAttachment(
diff --git a/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-registration/webauthn-registration-flow.xml b/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-registration/webauthn-registration-flow.xml
index e1598d6..f454326 100644
--- a/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-registration/webauthn-registration-flow.xml
+++ b/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-registration/webauthn-registration-flow.xml
@@ -64,6 +64,7 @@
     
     <view-state id="DisplayWebAuthnView" view="webauthn/webauthn-register">
         <on-render>
+
             <evaluate expression="environment" result="viewScope.environment" />
             <evaluate expression="opensamlProfileRequestContext" result="viewScope.profileRequestContext" />
             <evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.plugin.authn.webauthn.context.WebAuthnRegistrationContext))" result="viewScope.webauthnRegContext" />
@@ -87,7 +88,7 @@
         <evaluate expression="StorePublicKeyCredential"/>        
         
         <evaluate expression="'proceed'" />
-        <transition on="proceed" to="DisplayWebAuthnAdminResult">
+        <transition on="proceed" to="GeneratePublicKeyCredentialCreationOptions">
             <!-- TODO externalise message bundle-->
             <set name="flashScope.registrationOutcomes" value="'Key was registered successfully'"/>
         </transition>
@@ -98,39 +99,12 @@
         <evaluate expression="DeletePublicKeyCredential"/>
         
         <evaluate expression="'proceed'" />
-        <transition on="proceed" to="DisplayWebAuthnAdminResult">
+        <transition on="proceed" to="GeneratePublicKeyCredentialCreationOptions">
             <!-- TODO externalise message bundle-->
             <set name="flashScope.registrationOutcomes" value="'Key was removed successfully'"/>
         </transition>
-    </action-state>
-    
-    <view-state id="DisplayWebAuthnAdminResult" view="webauthn/webauthn-registered">
-        <on-entry>
-            <evaluate expression="LookupRegisteredCredentials"/>            
-        </on-entry>
-        <on-render>
-            <evaluate expression="environment" result="viewScope.environment" />
-            <evaluate expression="opensamlProfileRequestContext" result="viewScope.profileRequestContext" />
-            <evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.plugin.authn.webauthn.context.WebAuthnRegistrationContext))" result="viewScope.webauthnRegContext" />
-            <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPDigester')" result="requestScope.cspDigester" />
-            <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.CSPNonce')" result="requestScope.cspNonce" />   
-            <evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="viewScope.encoder" />
-            <evaluate expression="T(net.shibboleth.idp.plugin.authn.webauthn.impl.WebAuthnEncoder)" result="viewScope.webAuthnEncoder"/>
-            <evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="viewScope.request" />
-            <evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="viewScope.response" />
-        </on-render>
-        
-        <transition on="registerAnother" to="RegisterAnotherKey" />
-        <transition on="proceed" to="RegistrationComplete" />
-     </view-state>
-     
-    <action-state id="RegisterAnotherKey">
-        <evaluate expression="LookupRegisteredCredentials"/>
-        
-        <evaluate expression="'proceed'" />
-        <transition on="proceed" to="GeneratePublicKeyCredentialCreationOptions"/>
-    </action-state>
-     
+    </action-state> 
+
     <end-state id="RegistrationComplete"/>
     
     <bean-import resource="webauthn-registration-beans.xml" />
diff --git a/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/css/webauthn.css b/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/css/webauthn.css
index 683a62f..0f98e1e 100644
--- a/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/css/webauthn.css
+++ b/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/css/webauthn.css
@@ -19,6 +19,10 @@ tr:hover {
     background-color: rgb(237, 241, 255);
 }
 
+.inline {
+    display:inline;
+}
+
 
 /* Style the button that is used to open and close the collapsible content */
 .collapsible {
diff --git a/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/module.properties b/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/module.properties
index c6e63c1..83ddeed 100644
--- a/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/module.properties
+++ b/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/module.properties
@@ -27,23 +27,20 @@ idp.authn.WebAuthn.4.dest = views/webauthn/webauthn-register.vm
 idp.authn.WebAuthn.5.src = /net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-register-username.vm
 idp.authn.WebAuthn.5.dest = views/webauthn/webauthn-register-username.vm
 
-idp.authn.WebAuthn.6.src = /net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-registered.vm
-idp.authn.WebAuthn.6.dest = views/webauthn/webauthn-registered.vm
+idp.authn.WebAuthn.6.src = /net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-authn-username.vm
+idp.authn.WebAuthn.6.dest = views/webauthn/webauthn-authn-username.vm
 
-idp.authn.WebAuthn.7.src = /net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-username.vm
-idp.authn.WebAuthn.7.dest = views/webauthn/webauthn-username.vm
+idp.authn.WebAuthn.7.src = /net/shibboleth/idp/plugin/authn/webauthn/css/webauthn.css
+idp.authn.WebAuthn.7.dest = edit-webapp/css/webauthn.css
+idp.authn.WebAuthn.7.postenable = Customize edit-webapp/css/webauthn.css and rebuild war to deploy.
 
-idp.authn.WebAuthn.8.src = /net/shibboleth/idp/plugin/authn/webauthn/css/webauthn.css
-idp.authn.WebAuthn.8.dest = edit-webapp/css/webauthn.css
-idp.authn.WebAuthn.8.postenable = Customize edit-webapp/css/webauthn.css and rebuild war to deploy.
+idp.authn.WebAuthn.8.src = /net/shibboleth/idp/plugin/authn/webauthn/js/webauthn-json.browser-ponyfill.js
+idp.authn.WebAuthn.8.dest = edit-webapp/js/webauthn/webauthn-json.browser-ponyfill.js
 
-idp.authn.WebAuthn.9.src = /net/shibboleth/idp/plugin/authn/webauthn/js/webauthn-json.browser-ponyfill.js
-idp.authn.WebAuthn.9.dest = edit-webapp/js/webauthn/webauthn-json.browser-ponyfill.js
+idp.authn.WebAuthn.9.src = /net/shibboleth/idp/plugin/authn/webauthn/js/webauthn-support.js
+idp.authn.WebAuthn.9.dest = edit-webapp/js/webauthn/webauthn-support.js
 
-idp.authn.WebAuthn.10.src = /net/shibboleth/idp/plugin/authn/webauthn/js/webauthn-support.js
-idp.authn.WebAuthn.10.dest = edit-webapp/js/webauthn/webauthn-support.js
-
-idp.authn.WebAuthn.11.src = /net/shibboleth/idp/plugin/authn/webauthn/js/webauthn-json.browser-ponyfill.js.map
-idp.authn.WebAuthn.11.dest = edit-webapp/js/webauthn/webauthn-json.browser-ponyfill.js.map
+idp.authn.WebAuthn.10.src = /net/shibboleth/idp/plugin/authn/webauthn/js/webauthn-json.browser-ponyfill.js.map
+idp.authn.WebAuthn.10.dest = edit-webapp/js/webauthn/webauthn-json.browser-ponyfill.js.map
 
 
diff --git a/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-register.vm b/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-register.vm
index e047794..2086607 100644
--- a/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-register.vm
+++ b/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-register.vm
@@ -88,47 +88,49 @@
          <section>
             <div id="supportedDiv">
                <div class="centre">
+                  #if ($registrationOutcomes)
+                    <p>$registrationOutcomes</p>
+                    <hr/>
+                  #end                 
                   <div>
                      <h1>Registered Keys</h1>
                      #if ($webauthnRegContext.existingCredentials)
-                     <table>
-                        <tr>
-                           <th>#springMessageText("idp.webauthn.register.table.keyName", "Key Name")</th>
-                           <th>#springMessageText("idp.webauthn.register.table.transports", "Transports")</th>
-                           <th>#springMessageText("idp.webauthn.register.table.passkey", "Passkey?")</th>
-                           <th>#springMessageText("idp.webauthn.register.table.registrationTime", "Registration Time")</th>
-                           <th>#springMessageText("idp.webauthn.register.table.action", "Action")</th>
-                        </tr>
-                        #foreach($cred in $webauthnRegContext.existingCredentials)
-                        <tr>
-                           <td>$encoder.encodeForHTML($cred.nickname)</td>
-                           <td>$encoder.encodeForHTML($webAuthnEncoder.formatTransports($cred.transports))</td>
-                           <td>$encoder.encodeForHTML($webAuthnEncoder.formatDiscoverable($cred.isDiscoverable()))</td>
-                           <td>$encoder.encodeForHTML($webAuthnEncoder.formatInstant($cred.registrationTime))</td>
-                           <td>
-                              <form id="deleteKeyForm" action="$flowExecutionUrl" method="post">
-                                 #parse("csrf/csrf.vm")
-                                 <input type="hidden" name="credentialId" value="$cred.credentialIdBase64Url"/>
-                                 <button class="webauthn-table-button" onclick="return confirm('#springMessageText("idp.webauthn.register.credential.remove.confirm", "Are you sure")');" id="removeButton" type="submit" name="_eventId_deleteKey">#springMessageText("idp.webauthn.register.credential.remove", "Remove")</button>
-                              </form>
-                           </td>
-                        </tr>
-                        #end   
-                     </table>
+                         <table>
+                            <tr>
+                               <th>#springMessageText("idp.webauthn.register.table.keyName", "Key Name")</th>
+                               <th>#springMessageText("idp.webauthn.register.table.transports", "Transports")</th>
+                               <th>#springMessageText("idp.webauthn.register.table.passkey", "Passkey?")</th>
+                               <th>#springMessageText("idp.webauthn.register.table.registrationTime", "Registration Time")</th>
+                               <th>#springMessageText("idp.webauthn.register.table.action", "Action")</th>
+                            </tr>
+                            #foreach($cred in $webauthnRegContext.existingCredentials)
+                            <tr>
+                               <td>$encoder.encodeForHTML($cred.nickname)</td>
+                               <td>$encoder.encodeForHTML($webAuthnEncoder.formatTransports($cred.transports))</td>
+                               <td>$encoder.encodeForHTML($webAuthnEncoder.formatDiscoverable($cred.isDiscoverable()))</td>
+                               <td>$encoder.encodeForHTML($webAuthnEncoder.formatInstant($cred.registrationTime))</td>
+                               <td>
+                                  <form id="deleteKeyForm" action="$flowExecutionUrl" method="post">
+                                     #parse("csrf/csrf.vm")
+                                     <input type="hidden" name="credentialId" value="$cred.credentialIdBase64Url"/>
+                                     <button class="webauthn-table-button" onclick="return confirm('#springMessageText("idp.webauthn.register.credential.remove.confirm", "Are you sure")');" id="removeButton" type="submit" name="_eventId_deleteKey">#springMessageText("idp.webauthn.register.credential.remove", "Remove")</button>
+                                  </form>
+                               </td>
+                            </tr>
+                            </table>
+                     #end                     
                      #else
-                     <div><span>#springMessageText("idp.webauthn.register.registered.noKeys", "You have no registered keys")</span></div>
+                        <div><span>#springMessageText("idp.webauthn.register.registered.noKeys", "You have no registered keys")</span></div>
                      #end
                      <br/>
                      <div class="grid">
                         <div class="grid-item">
                             <button id="registerButton">#springMessageText("idp.webauthn.register.addKey", "Add New Security Key")</button>
-                        </div>
-                        <div class="grid-item">
-                            <form id="finish_button_form" action="$flowExecutionUrl" method="post">
+                            <form id="finish_button_form" action="$flowExecutionUrl" method="post" class="inline">
                                #parse("csrf/csrf.vm")                           
                                <button id="finish_button" type="submit" name="_eventId_finish">#springMessageText("idp.webauthn.register.finish", "Finish")</button>
                             </form>
-                        </div>
+                        </div>                        
                      </div>
                      <form id="authenticatorAttestationForm" action="$flowExecutionUrl" method="post">
                         #parse("csrf/csrf.vm")
@@ -138,13 +140,13 @@
                      </form>
                   </div>
                   #if($debug == "true")
-                  <hr/>
-                  <button type="button" class="collapsible">#springMessageText("idp.webauthn.register.debug.title", "Debugging")</button> 
-                  <div class="debug" id="debug-div">
-                     <label for="publicKeyCredentialCreation">#springMessageText("idp.webauthn.register.debug.registration", "Registration Options")</label>
-                     <textarea id="publicKeyCredentialCreation" name="publicKeyCredentialCreation" rows="20" cols="50">
-                     $webauthnRegContext.publicKeyCredentialCreationOptionsJSON</textarea>                   
-                  </div>
+                      <hr/>
+                      <button type="button" class="collapsible">#springMessageText("idp.webauthn.register.debug.title", "Debugging")</button> 
+                      <div class="debug" id="debug-div">
+                         <label for="publicKeyCredentialCreation">#springMessageText("idp.webauthn.register.debug.registration", "Registration Options")</label>
+                         <textarea id="publicKeyCredentialCreation" name="publicKeyCredentialCreation" rows="20" cols="50">
+                         $webauthnRegContext.publicKeyCredentialCreationOptionsJSON</textarea>                   
+                      </div>
                   #end            
                </div>
                <div id="unsupportedDiv" class="hidden">
diff --git a/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-registered.vm b/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-registered.vm
deleted file mode 100644
index c7c7a4b..0000000
--- a/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-registered.vm
+++ /dev/null
@@ -1,90 +0,0 @@
-##
-## Velocity Template for DisplayWebauthnView view-state
-##
-## Velocity context will contain the following properties
-## flowExecutionUrl - the form action location
-## flowRequestContext - the Spring Web Flow RequestContext
-## flowExecutionKey - the SWF execution key (this is built into the flowExecutionUrl)
-## profileRequestContext - root of context tree
-## authenticationContext - context with authentication request information
-## authenticationErrorContext - context with login error state
-## webauthnRegContext = WebAuthn registration context
-## authenticationWarningContext - context with login warning state
-## rpUIContext - the context with SP UI information from the metadata
-## encoder - HTMLEncoder class
-## webAuthnEncoder - WebAuthnEncoder class
-## request - HttpServletRequest
-## response - HttpServletResponse
-## environment - Spring Environment object for property resolution
-## custom - arbitrary object injected by deployer
-##
-#set ($rpContext = $profileRequestContext.getSubcontext('net.shibboleth.profile.context.RelyingPartyContext'))
-##
-<!DOCTYPE html>
-<html>
-    <head>
-        <title>#springMessageText("idp.title", "Web Login Service")</title>
-        <meta charset="UTF-8" />
-        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
-        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0">
-        <link rel="stylesheet" type="text/css" href="$request.getContextPath()#springMessageText("
-            idp.css", "/css/placeholder.css" )">
-        <link rel="stylesheet" type="text/css" href="$request.getContextPath()/css/webauthn.css">
-    </head>
-    <body>
-        <main class="main">
-            <header>
-                <img class="main-logo" src="$request.getContextPath()#springMessageText("
-                    idp.logo", "/images/placeholder-logo.png" )" alt="#springMessageText(" idp.logo.alt-text", "logo" )" />
-    
-                #set ($serviceName = $rpUIContext.serviceName)
-                #if ($serviceName && !$rpContext.getRelyingPartyId().contains($serviceName))
-                <h1>#springMessageText("idp.login.loginTo", "Login to") $encoder.encodeForHTML($serviceName)</h1>
-                #end
-            </header>
-            <section>
-                <div class="centre">
-                    <p>$registrationOutcomes</p>
-    
-                    <hr />
-                    
-                    #if ($webauthnRegContext.existingCredentials)
-                        <p>Registered Keys</p>
-                        <table>
-                            <tr>
-                                <th>#springMessageText("idp.webauthn.register.table.keyName", "Key Name")</th>
-                                <th>#springMessageText("idp.webauthn.register.table.transports", "Transports")</th>
-                                <th>#springMessageText("idp.webauthn.register.table.passkey", "Passkey?")</th>
-                                <th>#springMessageText("idp.webauthn.register.table.userVerifiedOnRegistration", "User Verified?")</th>
-                                <th>#springMessageText("idp.webauthn.register.table.registrationTime", "Registration Time")</th>
-                            </tr>
-                            #foreach($cred in $webauthnRegContext.existingCredentials)
-                            <tr>
-                                <td>$encoder.encodeForHTML($cred.nickname)</td>
-                                <td>$encoder.encodeForHTML($webAuthnEncoder.formatTransports($cred.transports))</td>
-                                <td>$encoder.encodeForHTML($webAuthnEncoder.formatDiscoverable($cred.isDiscoverable()))</td>
-                                <td>$encoder.encodeForHTML($cred.userVerified)</td>
-                                <td>$encoder.encodeForHTML($webAuthnEncoder.formatInstant($cred.registrationTime))</td>
-                            </tr>
-                            #end
-                        </table>
-                    #else
-                        <div><span>You have no registered keys</span></div>
-                    #end
-                    <br />
-                    <form id="finish_button_form" action="$flowExecutionUrl" method="post">
-                        #parse("csrf/csrf.vm")
-                        <button id="register_another_button" type="submit" name="_eventId_registerAnother">#springMessageText("idp.webauthn.register.another", "Register Another")</button>
-                    
-                        <button id="finish_button" type="submit" name="_eventId_proceed">#springMessageText("idp.webauthn.register.finish", "Finish")</button>
-                    </form>
-                </div>   
-            </section>
-        </main>    
-        <footer>
-            <div class="cc">
-                <p class="footer-text">#springMessageText("idp.footer", "Insert your footer text here.")</p>
-            </div>
-        </footer>    
-    </body>
-</html>

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


More information about the commits mailing list