@@ -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 )
319+ ? HtmlTemplates .fromTemplate (FORM_READONLY_USERNAME_INPUT ).withValue ("username" , username )
320+ : HtmlTemplates .fromTemplate (FORM_USERNAME_INPUT ))
321+ .withValue ("usernameParameter" , this .usernameParameter )
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,17 @@ 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 )
356+ ? HtmlTemplates .fromTemplate (ONE_TIME_READONLY_USERNAME_INPUT ).withValue ("username" , username ).render ()
357+ : ONE_TIME_USERNAME_INPUT ;
358+
340359 return HtmlTemplates .fromTemplate (ONE_TIME_TEMPLATE )
341360 .withValue ("generateOneTimeTokenUrl" , contextPath + this .generateOneTimeTokenUrl )
342361 .withRawHtml ("errorMessage" , renderError (loginError , errorMsg ))
343362 .withRawHtml ("logoutMessage" , renderSuccess (logoutSuccess ))
344363 .withRawHtml ("hiddenInputs" , hiddenInputs )
364+ .withRawHtml ("usernameInput" , usernameInput )
345365 .render ();
346366 }
347367
@@ -410,6 +430,14 @@ private String renderRememberMe(@Nullable String paramName) {
410430 .render ();
411431 }
412432
433+ private @ Nullable String getUsername () {
434+ Authentication authentication = this .securityContextHolderStrategy .getContext ().getAuthentication ();
435+ if (authentication != null && authentication .isAuthenticated ()) {
436+ return authentication .getName ();
437+ }
438+ return null ;
439+ }
440+
413441 private boolean isLogoutSuccess (HttpServletRequest request ) {
414442 return this .logoutSuccessUrl != null && matches (request , this .logoutSuccessUrl );
415443 }
@@ -511,7 +539,7 @@ private boolean matches(HttpServletRequest request, @Nullable String url) {
511539 {{errorMessage}}{{logoutMessage}}
512540 <p>
513541 <label for="username" class="screenreader">Username</label>
514- <input type="text" id="username" name="{{usernameParameter}}" placeholder="Username" required autofocus>
542+ {{usernameInput}}
515543 </p>
516544 <p>
517545 <label for="password" class="screenreader">Password</label>
@@ -522,6 +550,14 @@ private boolean matches(HttpServletRequest request, @Nullable String url) {
522550 <button type="submit" class="primary">Sign in</button>
523551 </form>""" ;
524552
553+ private static final String FORM_READONLY_USERNAME_INPUT = """
554+ <input type="text" id="username" name="{{usernameParameter}}" value="{{username}}" placeholder="Username" required readonly>
555+ """ ;
556+
557+ private static final String FORM_USERNAME_INPUT = """
558+ <input type="text" id="username" name="{{usernameParameter}}" placeholder="Username" required autofocus>
559+ """ ;
560+
525561 private static final String HIDDEN_HTML_INPUT_TEMPLATE = """
526562 <input name="{{name}}" type="hidden" value="{{value}}" />
527563 """ ;
@@ -554,11 +590,19 @@ private boolean matches(HttpServletRequest request, @Nullable String url) {
554590 {{errorMessage}}{{logoutMessage}}
555591 <p>
556592 <label for="ott-username" class="screenreader">Username</label>
557- <input type="text" id="ott-username" name="username" placeholder="Username" required>
593+ {{usernameInput}}
558594 </p>
559595 {{hiddenInputs}}
560596 <button class="primary" type="submit" form="ott-form">Send Token</button>
561597 </form>
562598 """ ;
563599
600+ private static final String ONE_TIME_READONLY_USERNAME_INPUT = """
601+ <input type="text" id="ott-username" name="username" value="{{username}}" placeholder="Username" required readonly>
602+ """ ;
603+
604+ private static final String ONE_TIME_USERNAME_INPUT = """
605+ <input type="text" id="ott-username" name="username" placeholder="Username" required>
606+ """ ;
607+
564608}
0 commit comments