@@ -59,6 +59,9 @@ public class DefaultLoginPageGeneratingFilter extends GenericFilterBean {
5959
6060 public static final String ERROR_PARAMETER_NAME = "error" ;
6161
62+ private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
63+ .getContextHolderStrategy ();
64+
6265 private @ Nullable String loginPageUrl ;
6366
6467 private @ Nullable String logoutSuccessUrl ;
@@ -118,6 +121,10 @@ private void initAuthFilter(UsernamePasswordAuthenticationFilter authFilter) {
118121 }
119122 }
120123
124+ public void setSecurityContextHolderStrategy (SecurityContextHolderStrategy securityContextHolderStrategy ) {
125+ this .securityContextHolderStrategy = securityContextHolderStrategy ;
126+ }
127+
121128 /**
122129 * Sets a Function used to resolve a Map of the hidden inputs where the key is the
123130 * name of the input and the value is the value of the input. Typically this is used
@@ -307,6 +314,13 @@ private String renderFormLogin(HttpServletRequest request, boolean loginError, b
307314 return "" ;
308315 }
309316
317+ String username = getUsername ();
318+ String usernameInput = (username == null ) ? FORM_USERNAME_INPUT
319+ : HtmlTemplates .fromTemplate (FORM_READONLY_USERNAME_INPUT )
320+ .withValue ("usernameParameter" , this .usernameParameter )
321+ .withValue ("username" , username )
322+ .render ();
323+
310324 String hiddenInputs = this .resolveHiddenInputs .apply (request )
311325 .entrySet ()
312326 .stream ()
@@ -317,7 +331,7 @@ private String renderFormLogin(HttpServletRequest request, boolean loginError, b
317331 .withValue ("loginUrl" , contextPath + this .authenticationUrl )
318332 .withRawHtml ("errorMessage" , renderError (loginError , errorMsg ))
319333 .withRawHtml ("logoutMessage" , renderSuccess (logoutSuccess ))
320- .withValue ( "usernameParameter " , this . usernameParameter )
334+ .withRawHtml ( "usernameInput " , usernameInput )
321335 .withValue ("passwordParameter" , this .passwordParameter )
322336 .withRawHtml ("rememberMeInput" , renderRememberMe (this .rememberMeParameter ))
323337 .withRawHtml ("hiddenInputs" , hiddenInputs )
@@ -337,11 +351,16 @@ private String renderOneTimeTokenLogin(HttpServletRequest request, boolean login
337351 .map ((inputKeyValue ) -> renderHiddenInput (inputKeyValue .getKey (), inputKeyValue .getValue ()))
338352 .collect (Collectors .joining ("\n " ));
339353
354+ String username = getUsername ();
355+ String usernameInput = (username == null ) ? ONE_TIME_USERNAME_INPUT
356+ : HtmlTemplates .fromTemplate (ONE_TIME_READONLY_USERNAME_INPUT ).withValue ("username" , username ).render ();
357+
340358 return HtmlTemplates .fromTemplate (ONE_TIME_TEMPLATE )
341359 .withValue ("generateOneTimeTokenUrl" , contextPath + this .generateOneTimeTokenUrl )
342360 .withRawHtml ("errorMessage" , renderError (loginError , errorMsg ))
343361 .withRawHtml ("logoutMessage" , renderSuccess (logoutSuccess ))
344362 .withRawHtml ("hiddenInputs" , hiddenInputs )
363+ .withRawHtml ("usernameInput" , usernameInput )
345364 .render ();
346365 }
347366
@@ -410,6 +429,14 @@ private String renderRememberMe(@Nullable String paramName) {
410429 .render ();
411430 }
412431
432+ private @ Nullable String getUsername () {
433+ Authentication authentication = this .securityContextHolderStrategy .getContext ().getAuthentication ();
434+ if (authentication != null && authentication .isAuthenticated ()) {
435+ return authentication .getName ();
436+ }
437+ return null ;
438+ }
439+
413440 private boolean isLogoutSuccess (HttpServletRequest request ) {
414441 return this .logoutSuccessUrl != null && matches (request , this .logoutSuccessUrl );
415442 }
@@ -511,7 +538,7 @@ private boolean matches(HttpServletRequest request, @Nullable String url) {
511538 {{errorMessage}}{{logoutMessage}}
512539 <p>
513540 <label for="username" class="screenreader">Username</label>
514- <input type="text" id="username" name="{{usernameParameter}}" placeholder="Username" required autofocus>
541+ {{usernameInput}}
515542 </p>
516543 <p>
517544 <label for="password" class="screenreader">Password</label>
@@ -522,6 +549,14 @@ private boolean matches(HttpServletRequest request, @Nullable String url) {
522549 <button type="submit" class="primary">Sign in</button>
523550 </form>""" ;
524551
552+ private static final String FORM_READONLY_USERNAME_INPUT = """
553+ <input type="text" id="ott-username" name="{{usernameParameter}}" value="{{username}}" placeholder="Username" required readonly>
554+ """ ;
555+
556+ private static final String FORM_USERNAME_INPUT = """
557+ <input type="text" id="ott-username" name="{{usernameParameter}}" placeholder="Username" required>
558+ """ ;
559+
525560 private static final String HIDDEN_HTML_INPUT_TEMPLATE = """
526561 <input name="{{name}}" type="hidden" value="{{value}}" />
527562 """ ;
@@ -554,11 +589,19 @@ private boolean matches(HttpServletRequest request, @Nullable String url) {
554589 {{errorMessage}}{{logoutMessage}}
555590 <p>
556591 <label for="ott-username" class="screenreader">Username</label>
557- <input type="text" id="ott-username" name="username" placeholder="Username" required>
592+ {{usernameInput}}
558593 </p>
559594 {{hiddenInputs}}
560595 <button class="primary" type="submit" form="ott-form">Send Token</button>
561596 </form>
562597 """ ;
563598
599+ private static final String ONE_TIME_READONLY_USERNAME_INPUT = """
600+ <input type="text" id="ott-username" name="username" value="{{username}}" placeholder="Username" required readonly>
601+ """ ;
602+
603+ private static final String ONE_TIME_USERNAME_INPUT = """
604+ <input type="text" id="ott-username" name="username" placeholder="Username" required>
605+ """ ;
606+
564607}
0 commit comments