<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>User Management on Palmyra</title>
    <link>https://palmyra.dev/docs/api/backend/extensions/user-management/</link>
    <description>Recent content in User Management on Palmyra</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <atom:link href="https://palmyra.dev/docs/api/backend/extensions/user-management/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>UserPasswordRepository</title>
      <link>https://palmyra.dev/docs/api/backend/extensions/user-management/user-password-repository/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://palmyra.dev/docs/api/backend/extensions/user-management/user-password-repository/</guid>
      <description>&lt;h1 id=&#34;userpasswordrepository&#34;&gt;UserPasswordRepository&lt;a class=&#34;anchor&#34; href=&#34;#userpasswordrepository&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;&lt;code&gt;com.palmyralabs.palmyra.ext.usermgmt.repository.UserPasswordRepository&lt;/code&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;a class=&#34;anchor&#34; href=&#34;#overview&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;Plain &lt;code&gt;@Repository&lt;/code&gt; interface for reading and updating &lt;code&gt;UserPasswordModel&lt;/code&gt; records — login, hashed password, salt, audit fields. Not a &lt;code&gt;JpaRepository&lt;/code&gt;: the implementation is supplied by the module so consumers don&amp;rsquo;t depend on Spring Data&amp;rsquo;s method-derivation conventions.&lt;/p&gt;&#xA;&lt;h2 id=&#34;methods&#34;&gt;Methods&lt;a class=&#34;anchor&#34; href=&#34;#methods&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Method&lt;/th&gt;&#xA;          &lt;th&gt;Signature&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;findByLoginName&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;UserPasswordModel findByLoginName(String loginName)&lt;/code&gt; — look up by login name (no email fallback)&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;update&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;void update(UserPasswordModel user)&lt;/code&gt; — persist updated fields (password hash, salt, random token, counters)&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;example&#34;&gt;Example&lt;a class=&#34;anchor&#34; href=&#34;#example&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;Inject as usual — Spring picks up &lt;code&gt;@Repository&lt;/code&gt;:&lt;/p&gt;</description>
    </item>
    <item>
      <title>PasswordMgmtService</title>
      <link>https://palmyra.dev/docs/api/backend/extensions/user-management/password-mgmt-service/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://palmyra.dev/docs/api/backend/extensions/user-management/password-mgmt-service/</guid>
      <description>&lt;h1 id=&#34;passwordmgmtservice&#34;&gt;PasswordMgmtService&lt;a class=&#34;anchor&#34; href=&#34;#passwordmgmtservice&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;&lt;code&gt;com.palmyralabs.palmyra.ext.usermgmt.service.PasswordMgmtService&lt;/code&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;a class=&#34;anchor&#34; href=&#34;#overview&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;Full-surface password lifecycle SPI — verify a credential, reset as admin, change as the user, force-change without the old password. Implementations typically also implement &lt;a href=&#34;https://palmyra.dev/docs/api/backend/extensions/user-management/password-verification-service/&#34;&gt;&lt;code&gt;PasswordVerificationService&lt;/code&gt;&lt;/a&gt; for consumers that only need the verify operation.&lt;/p&gt;&#xA;&lt;h2 id=&#34;methods&#34;&gt;Methods&lt;a class=&#34;anchor&#34; href=&#34;#methods&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Method&lt;/th&gt;&#xA;          &lt;th&gt;Signature&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;isValid&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;boolean isValid(UserPasswordModel model, String password)&lt;/code&gt; — validate against an already-loaded user model (no extra DB round-trip)&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;verifyPassword&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;boolean verifyPassword(String loginName, String password) throws Exception&lt;/code&gt; — login-time verification by login name&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;resetPassword&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;boolean resetPassword(ResetPasswordRequest request)&lt;/code&gt; — admin-driven reset flow (typically delivers a reset token / temporary password)&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;changePassword&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;boolean changePassword(ChangePasswordRequest request)&lt;/code&gt; — end-user self-service; requires old password in the request&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;forceChangePassword&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;boolean forceChangePassword(String loginName, String newPassword)&lt;/code&gt; — &lt;strong&gt;bypasses&lt;/strong&gt; the old-password check; admin / force-rotate flow&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;design-note&#34;&gt;Design note&lt;a class=&#34;anchor&#34; href=&#34;#design-note&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;&lt;code&gt;isValid(UserPasswordModel, String)&lt;/code&gt; is the seam that lets &lt;a href=&#34;https://palmyra.dev/docs/api/backend/extensions/user-management/local-db-authentication-provider/&#34;&gt;&lt;code&gt;LocalDBAuthenticationProvider&lt;/code&gt;&lt;/a&gt; pre-load the user model once and re-use it, avoiding a second &lt;code&gt;findByLoginName&lt;/code&gt; call inside &lt;code&gt;verifyPassword&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>PasswordVerificationService</title>
      <link>https://palmyra.dev/docs/api/backend/extensions/user-management/password-verification-service/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://palmyra.dev/docs/api/backend/extensions/user-management/password-verification-service/</guid>
      <description>&lt;h1 id=&#34;passwordverificationservice&#34;&gt;PasswordVerificationService&lt;a class=&#34;anchor&#34; href=&#34;#passwordverificationservice&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;&lt;code&gt;com.palmyralabs.palmyra.ext.usermgmt.service.PasswordVerificationService&lt;/code&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;a class=&#34;anchor&#34; href=&#34;#overview&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;Narrow &amp;ldquo;verify only&amp;rdquo; SPI. Useful when a component needs to check a credential but shouldn&amp;rsquo;t pull in the full reset / change / force-change surface of &lt;a href=&#34;https://palmyra.dev/docs/api/backend/extensions/user-management/password-mgmt-service/&#34;&gt;&lt;code&gt;PasswordMgmtService&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;PasswordMgmtService&lt;/code&gt; and &lt;code&gt;PasswordVerificationService&lt;/code&gt; are &lt;strong&gt;independent&lt;/strong&gt; interfaces — neither extends the other — but the common implementation class typically implements both. Depend on whichever is closer to what you actually need.&lt;/p&gt;&#xA;&lt;h2 id=&#34;methods&#34;&gt;Methods&lt;a class=&#34;anchor&#34; href=&#34;#methods&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Method&lt;/th&gt;&#xA;          &lt;th&gt;Signature&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;verifyPassword&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;boolean verifyPassword(String loginName, String password) throws Exception&lt;/code&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;example&#34;&gt;Example&lt;a class=&#34;anchor&#34; href=&#34;#example&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;@RestController&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;@RequiredArgsConstructor&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;SensitiveActionController&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;final&lt;/span&gt; PasswordVerificationService passwords;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;@PostMapping&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/account/delete&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; ResponseEntity&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;?&amp;gt;&lt;/span&gt; deleteAccount(Principal who, &lt;span style=&#34;color:#a6e22e&#34;&gt;@RequestBody&lt;/span&gt; ConfirmReq req) &lt;span style=&#34;color:#66d9ef&#34;&gt;throws&lt;/span&gt; Exception {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;passwords.&lt;span style=&#34;color:#a6e22e&#34;&gt;verifyPassword&lt;/span&gt;(who.&lt;span style=&#34;color:#a6e22e&#34;&gt;getName&lt;/span&gt;(), req.&lt;span style=&#34;color:#a6e22e&#34;&gt;password&lt;/span&gt;())) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; ResponseEntity.&lt;span style=&#34;color:#a6e22e&#34;&gt;status&lt;/span&gt;(HttpStatus.&lt;span style=&#34;color:#a6e22e&#34;&gt;UNAUTHORIZED&lt;/span&gt;).&lt;span style=&#34;color:#a6e22e&#34;&gt;build&lt;/span&gt;();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        accountService.&lt;span style=&#34;color:#a6e22e&#34;&gt;delete&lt;/span&gt;(who.&lt;span style=&#34;color:#a6e22e&#34;&gt;getName&lt;/span&gt;());&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; ResponseEntity.&lt;span style=&#34;color:#a6e22e&#34;&gt;noContent&lt;/span&gt;().&lt;span style=&#34;color:#a6e22e&#34;&gt;build&lt;/span&gt;();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>LocalDBAuthenticationProvider</title>
      <link>https://palmyra.dev/docs/api/backend/extensions/user-management/local-db-authentication-provider/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://palmyra.dev/docs/api/backend/extensions/user-management/local-db-authentication-provider/</guid>
      <description>&lt;h1 id=&#34;localdbauthenticationprovider&#34;&gt;LocalDBAuthenticationProvider&lt;a class=&#34;anchor&#34; href=&#34;#localdbauthenticationprovider&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;&lt;code&gt;com.palmyralabs.palmyra.ext.usermgmt.security.LocalDBAuthenticationProvider&lt;/code&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;a class=&#34;anchor&#34; href=&#34;#overview&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;Spring Security &lt;code&gt;AuthenticationProvider&lt;/code&gt; backed by a local database. Wire it into your &lt;code&gt;SecurityFilterChain&lt;/code&gt; and every &lt;code&gt;UsernamePasswordAuthenticationToken&lt;/code&gt; is validated against the &lt;code&gt;user_password&lt;/code&gt; table via &lt;a href=&#34;https://palmyra.dev/docs/api/backend/extensions/user-management/user-password-repository/&#34;&gt;&lt;code&gt;UserPasswordRepository&lt;/code&gt;&lt;/a&gt; and &lt;a href=&#34;https://palmyra.dev/docs/api/backend/extensions/user-management/password-mgmt-service/&#34;&gt;&lt;code&gt;PasswordMgmtService&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Annotated &lt;code&gt;@Component&lt;/code&gt;, &lt;code&gt;@Slf4j&lt;/code&gt;, &lt;code&gt;@RequiredArgsConstructor&lt;/code&gt; — Lombok generates the constructor over the two &lt;code&gt;final&lt;/code&gt; dependencies.&lt;/p&gt;&#xA;&lt;h2 id=&#34;dependencies&#34;&gt;Dependencies&lt;a class=&#34;anchor&#34; href=&#34;#dependencies&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;Injected via the Lombok-generated constructor:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;final&lt;/span&gt; UserPasswordRepository userRepository;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;final&lt;/span&gt; PasswordMgmtService    userMgmtService;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;methods&#34;&gt;Methods&lt;a class=&#34;anchor&#34; href=&#34;#methods&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Method&lt;/th&gt;&#xA;          &lt;th&gt;Signature&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;authenticate&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;Authentication authenticate(Authentication authentication) throws AuthenticationException&lt;/code&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;supports&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;boolean supports(Class&amp;lt;?&amp;gt; authentication)&lt;/code&gt; — returns &lt;code&gt;true&lt;/code&gt; unconditionally (accepts every &lt;code&gt;Authentication&lt;/code&gt; subtype)&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;behaviour--what-authenticate-actually-does&#34;&gt;Behaviour — what &lt;code&gt;authenticate()&lt;/code&gt; actually does&lt;a class=&#34;anchor&#34; href=&#34;#behaviour--what-authenticate-actually-does&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Loads the user via &lt;code&gt;userRepository.findByLoginName(authentication.getName())&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Reads &lt;code&gt;authentication.getCredentials()&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;If both the credential and the user model are non-null, delegates to &lt;code&gt;userMgmtService.isValid(userModel, cred.toString())&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;On success&lt;/strong&gt; — returns a &lt;strong&gt;new&lt;/strong&gt; &lt;code&gt;UsernamePasswordAuthenticationToken(name, &amp;quot;password&amp;quot;, emptyAuthorities)&lt;/code&gt;. Note:&#xA;&lt;ul&gt;&#xA;&lt;li&gt;The credential stored in the returned token is the literal string &lt;code&gt;&amp;quot;password&amp;quot;&lt;/code&gt;, &lt;strong&gt;not&lt;/strong&gt; the original credential.&lt;/li&gt;&#xA;&lt;li&gt;Authorities are always an empty &lt;code&gt;HashSet&amp;lt;GrantedAuthority&amp;gt;&lt;/code&gt;; role mapping has to happen upstream (e.g. the ACL extension) or in your own &lt;code&gt;UserDetailsService&lt;/code&gt; wrapper.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;On any failure&lt;/strong&gt; — returns the &lt;strong&gt;original&lt;/strong&gt; &lt;code&gt;authentication&lt;/code&gt; object unchanged rather than throwing &lt;code&gt;BadCredentialsException&lt;/code&gt;. This deviates from the typical Spring Security contract; downstream filters must check &lt;code&gt;isAuthenticated()&lt;/code&gt; themselves to detect auth failure.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;wiring&#34;&gt;Wiring&lt;a class=&#34;anchor&#34; href=&#34;#wiring&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;Register the provider in your security configuration; everything else falls out of Spring&amp;rsquo;s default filter chain:&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
