[JAVA] Exemple d'implémentation lors de l'utilisation de l'authentification par formulaire et de l'authentification d'en-tête de demande dans Spring Security

Déclenchement Dans un certain développement d'application Web, il était nécessaire de réaliser les deux suivants en même temps. ① L'authentification par formulaire peut être effectuée en entrant l'ID et le mot de passe à partir de l'écran de connexion. (2) L'authentification peut être effectuée avec la valeur d'un attribut spécifique dans l'en-tête de requête HTTP.

(2) est une exigence pour réaliser l'authentification unique en utilisant le système d'authentification externe existant car il définit un jeton dans l'en-tête de la requête HTTP et redirige lorsque l'authentification est réussie.

(1) Des exemples d'implémentation indépendants ou (2) indépendants peuvent être trouvés partout sur Internet, mais je n'ai pas trouvé de modèle pour les utiliser ensemble (et c'était technique comme c'était), donc je vais vous présenter comment cela a été réalisé.

Source Réglez comme suit. https://github.com/ShandyGaffLover/sample001/blob/master/src/main/resources/spring-security.xml

Explication Personnalisez "PRE_AUTH_FILTER" et "FORM_LOGIN_FILER".
    <sec:custom-filter position="PRE_AUTH_FILTER" ref="siteminderFilter" />
    <sec:custom-filter position="FORM_LOGIN_FILTER" ref="formLoginFilter" />

Personnaliser PRE_AUTH_FILTER

Pour personnaliser "PRE_AUTH_FILTER", utilisez la classe RequestHeaderAuthenticationFilter comme suit. Définissez la propriété exceptionIfHeaderMissing sur false et la propriété continueFilterChainOnUnsuccessfulAuthentication sur true pour faciliter l'authentification par formulaire.

  <bean id="siteminderFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
    <property name="principalRequestHeader" value="SM_USER"/>
    <property name="authenticationManager" ref="sm_authenticationManager" />
    <property name="exceptionIfHeaderMissing" value="false"/>

    <property name="continueFilterChainOnUnsuccessfulAuthentication" value="true"/>
  </bean>

Ici, AuthenticationManager (et AuthenticationProvider) est défini comme suit.

  <sec:authentication-manager id="sm_authenticationManager">
    <sec:authentication-provider ref="preauthAuthProvider" />
  </sec:authentication-manager>

  <bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
    <property name="preAuthenticatedUserDetailsService">
      <bean id="userDetailsServiceWrapper"
          class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
        <property name="userDetailsService" ref="customUserDetailsService"/>
      </bean>
    </property>
  </bean>

Utilisez la classe PreAuthenticatedAuthenticationProvider pour AuthenticationProvider. Notez que le UserDetailsService donné à la propriété preAuthenticatedUserDetailsService doit être encapsulé par la classe UserDetailsByNameServiceWrapper.

Personnaliser FORM_LOGIN_FILER La personnalisation de "FORM_LOGIN_FILER" est la suivante.
 <sec:authentication-manager id="form_authenticationManager">
    <sec:authentication-provider  user-service-ref="customUserDetailsService" >
    </sec:authentication-provider>
  </sec:authentication-manager>

  <bean id="formLoginFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
    <property name="authenticationManager" ref="form_authenticationManager" />
    <property name="authenticationSuccessHandler" ref="formLoginSuccessHandler" />
    <property name="authenticationFailureHandler" ref="formLoginFailureHandler" />
    <property name="filterProcessesUrl" value="/login" />
  </bean>

Notez que puisqu'un filtre personnalisé est utilisé ici, il est nécessaire de définir l'attribut entry-point-ref de la balise comme indiqué ci-dessous.

  <sec:http auto-config="false" use-expressions="true" entry-point-ref="loginUrlAuthenticationEntryPoint">

  ~Omission~

    <sec:custom-filter position="PRE_AUTH_FILTER" ref="siteminderFilter" />
    <sec:custom-filter position="FORM_LOGIN_FILTER" ref="formLoginFilter" />
  </sec:http>

  <bean id="loginUrlAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
    <constructor-arg value="/loginPage" />
  </bean>

chose réelle Vous pouvez vérifier le fonctionnement de ce qui suit. [^ 1] https://shandygafflover.herokuapp.com/

① Depuis l'écran de connexion, saisissez «utilisateur» pour le nom d'utilisateur et «mot de passe» pour le mot de passe pour vous connecter et vous serez authentifié. (2) Si vous définissez la valeur "utilisateur" sur l'attribut "SM_USER" dans l'en-tête de la requête HTTP [^ 2], vous serez authentifié. Ici, ModHeader présenté dans l'article suivant est utilisé.

Définissez les informations d'authentification en externe dans l'en-tête HTTP du navigateur - Qiita  https://qiita.com/utwang/items/1eeb25d27e8acea33a8a

[^ 1]: Je suis vraiment désolé, mais au moment de poster l'article, on dit qu'il ne supporte pas https (même s'il s'agit d'authentification!). Je suis désolé. Je prendrai le temps de m'en occuper.

[^ 2]: Le nom d'attribut "SM_USER" dans l'en-tête de la requête n'est qu'un exemple. Dans le développement réel, les noms d'attributs doivent être difficiles à deviner et doivent rester confidentiels.

Résultat de l’exécution Définissez la valeur "utilisateur" sur l'attribut "SM_USER" dans l'en-tête de la requête HTTP. ![requestheader.png](https://qiita-image-store.s3.amazonaws.com/0/322008/7b04e084-5929-255d-8d10-7ee600665ee6.png)

Dans cet état, par exemple, accédez à l'URL suivante. url.png

Ensuite, vous serez authentifié et la page s'affichera. greeting.png

Si l'attribut "SM_USER" n'est pas défini dans l'en-tête de la requête HTTP, l'écran de connexion sera affiché, vous serez donc authentifié par nom d'utilisateur et mot de passe. login.png greeting.png

URL de référence

Authentification / autorisation de mémo d'utilisation de Spring Security - Qiita https://qiita.com/opengl-8080/items/032ed0fa27a239bdc1cc

03-1. Comment configurer Spring Security 2 --soracane https://sites.google.com/site/soracane/home/springnitsuite/spring-security/spring-securityno-settei-houhou

Note technique - Explique comment créer votre propre processus d'authentification de sécurité Spring http://javatechnology.net/spring/spring-security-login-filter-original/

Notes de travail lors de l'application du blog Spring Security-Namihira http://namihira.hatenablog.com/entry/20160817/1471396975

AbstractAuthenticationProcessingFilter (Spring Security 4.2.6.RELEASE API) https://docs.spring.io/spring-security/site/docs/4.2.6.RELEASE/apidocs/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilter.html

Spring Security Java - Multiple Authentication Manager - 2 bean found error - Stack Overflow https://stackoverflow.com/questions/32105846/spring-security-java-multiple-authentication-manager-2-bean-found-error

Recommended Posts

Exemple d'implémentation lors de l'utilisation de l'authentification par formulaire et de l'authentification d'en-tête de demande dans Spring Security
Erreur de mise en œuvre lors de la mise en œuvre de la validation Spring
Créer une authentification par clé API pour l'API Web dans Spring Security
À propos de l'authentification Spring Security