@@ -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,18 @@ private void initAuthFilter(UsernamePasswordAuthenticationFilter authFilter) {
118121 }
119122 }
120123
124+ /**
125+ * Use this {@link SecurityContextHolderStrategy} to retrieve authenticated users.
126+ * <p>
127+ * Uses {@link SecurityContextHolder#getContextHolderStrategy()} by default.
128+ * @param securityContextHolderStrategy the strategy to use
129+ * @since 7.0
130+ */
131+ public void setSecurityContextHolderStrategy (SecurityContextHolderStrategy securityContextHolderStrategy ) {
132+ Assert .notNull (securityContextHolderStrategy , "securityContextHolderStrategy cannot be null" );
133+ this .securityContextHolderStrategy = securityContextHolderStrategy ;
134+ }
135+
121136 /**
122137 * Sets a Function used to resolve a Map of the hidden inputs where the key is the
123138 * name of the input and the value is the value of the input. Typically this is used
@@ -307,6 +322,13 @@ private String renderFormLogin(HttpServletRequest request, boolean loginError, b
307322 return "" ;
308323 }
309324
325+ String username = getUsername ();
326+ String usernameInput = ((username != null )
327+ ? HtmlTemplates .fromTemplate (FORM_READONLY_USERNAME_INPUT ).withValue ("username" , username )
328+ : HtmlTemplates .fromTemplate (FORM_USERNAME_INPUT ))
329+ .withValue ("usernameParameter" , this .usernameParameter )
330+ .render ();
331+
310332 String hiddenInputs = this .resolveHiddenInputs .apply (request )
311333 .entrySet ()
312334 .stream ()
@@ -317,7 +339,7 @@ private String renderFormLogin(HttpServletRequest request, boolean loginError, b
317339 .withValue ("loginUrl" , contextPath + this .authenticationUrl )
318340 .withRawHtml ("errorMessage" , renderError (loginError , errorMsg ))
319341 .withRawHtml ("logoutMessage" , renderSuccess (logoutSuccess ))
320- .withValue ( "usernameParameter " , this . usernameParameter )
342+ .withRawHtml ( "usernameInput " , usernameInput )
321343 .withValue ("passwordParameter" , this .passwordParameter )
322344 .withRawHtml ("rememberMeInput" , renderRememberMe (this .rememberMeParameter ))
323345 .withRawHtml ("hiddenInputs" , hiddenInputs )
@@ -337,11 +359,17 @@ private String renderOneTimeTokenLogin(HttpServletRequest request, boolean login
337359 .map ((inputKeyValue ) -> renderHiddenInput (inputKeyValue .getKey (), inputKeyValue .getValue ()))
338360 .collect (Collectors .joining ("\n " ));
339361
362+ String username = getUsername ();
363+ String usernameInput = (username != null )
364+ ? HtmlTemplates .fromTemplate (ONE_TIME_READONLY_USERNAME_INPUT ).withValue ("username" , username ).render ()
365+ : ONE_TIME_USERNAME_INPUT ;
366+
340367 return HtmlTemplates .fromTemplate (ONE_TIME_TEMPLATE )
341368 .withValue ("generateOneTimeTokenUrl" , contextPath + this .generateOneTimeTokenUrl )
342369 .withRawHtml ("errorMessage" , renderError (loginError , errorMsg ))
343370 .withRawHtml ("logoutMessage" , renderSuccess (logoutSuccess ))
344371 .withRawHtml ("hiddenInputs" , hiddenInputs )
372+ .withRawHtml ("usernameInput" , usernameInput )
345373 .render ();
346374 }
347375
@@ -410,6 +438,14 @@ private String renderRememberMe(@Nullable String paramName) {
410438 .render ();
411439 }
412440
441+ private @ Nullable String getUsername () {
442+ Authentication authentication = this .securityContextHolderStrategy .getContext ().getAuthentication ();
443+ if (authentication != null && authentication .isAuthenticated ()) {
444+ return authentication .getName ();
445+ }
446+ return null ;
447+ }
448+
413449 private boolean isLogoutSuccess (HttpServletRequest request ) {
414450 return this .logoutSuccessUrl != null && matches (request , this .logoutSuccessUrl );
415451 }
@@ -511,7 +547,7 @@ private boolean matches(HttpServletRequest request, @Nullable String url) {
511547 {{errorMessage}}{{logoutMessage}}
512548 <p>
513549 <label for="username" class="screenreader">Username</label>
514- <input type="text" id="username" name="{{usernameParameter}}" placeholder="Username" required autofocus>
550+ {{usernameInput}}
515551 </p>
516552 <p>
517553 <label for="password" class="screenreader">Password</label>
@@ -522,6 +558,14 @@ private boolean matches(HttpServletRequest request, @Nullable String url) {
522558 <button type="submit" class="primary">Sign in</button>
523559 </form>""" ;
524560
561+ private static final String FORM_READONLY_USERNAME_INPUT = """
562+ <input type="text" id="username" name="{{usernameParameter}}" value="{{username}}" placeholder="Username" required readonly>
563+ """ ;
564+
565+ private static final String FORM_USERNAME_INPUT = """
566+ <input type="text" id="username" name="{{usernameParameter}}" placeholder="Username" required autofocus>
567+ """ ;
568+
525569 private static final String HIDDEN_HTML_INPUT_TEMPLATE = """
526570 <input name="{{name}}" type="hidden" value="{{value}}" />
527571 """ ;
@@ -554,11 +598,19 @@ private boolean matches(HttpServletRequest request, @Nullable String url) {
554598 {{errorMessage}}{{logoutMessage}}
555599 <p>
556600 <label for="ott-username" class="screenreader">Username</label>
557- <input type="text" id="ott-username" name="username" placeholder="Username" required>
601+ {{usernameInput}}
558602 </p>
559603 {{hiddenInputs}}
560604 <button class="primary" type="submit" form="ott-form">Send Token</button>
561605 </form>
562606 """ ;
563607
608+ private static final String ONE_TIME_READONLY_USERNAME_INPUT = """
609+ <input type="text" id="ott-username" name="username" value="{{username}}" placeholder="Username" required readonly>
610+ """ ;
611+
612+ private static final String ONE_TIME_USERNAME_INPUT = """
613+ <input type="text" id="ott-username" name="username" placeholder="Username" required>
614+ """ ;
615+
564616}
0 commit comments