Spring Security est un grand module, et cet article n'implique que l'authentification des paramètres personnalisés. Les paramètres de vérification par défaut de Spring Security ne sont que le nom d'utilisateur et le mot de passe, qui ne sont généralement pas suffisants. Parce que le temps est passé trop longtemps, certains oublient et certains d'entre eux peuvent manquer. Ok, pas de bêtises.
Les configurations de sécurité à ressort et à ressort utilisent Javaconfig et les versions sont à leur tour 4.2.5 et 4.0.4.
Idée globale: personnalisez le point d'entrée, ajoutez des paramètres personnalisés pour étendre AuthenticationToken et AuthenticationProvider pour la vérification.
Définissez d'abord le point d'entrée:
import org.springframework.security.core.authenticationException; import org.springframework.security.web.authentication.loginurlauthenticationEntrypoint; import javax.servletservlexception; import javax.servlet.http.httpservletexest; Import javax.servlet.http.httpservletResponse; import java.io.ioException; classe publique myAuthenticationEntryPoint étend LoginurlAuthenticationEntryPoint {public myAuthenticationEntryPoint (String LoginFormUrl) {super (loginformurrl); } @Override public void début (httpServLeRequest request, httpservletResponse Response, AuthenticationException AuthException) lève ioException, ServletException {super.comance (request, réponse, authException); }}Ensuite, le jeton, ValidCode est le paramètre de code de vérification:
import org.springframework.security.authentication.UserAmEpasswordAuthenticationToken; public class MyUserAmEpasswordAuthenticationToken étend usernamepasswordAuthenticationToken {private String validcode; public myUserNamePasswordAuthenticationToken (String Principal, String Idemellings, String validCode) {super (principal, Identials); this.validcode = validcode; } public String getValidCode () {return validcode; } public void setValidCode (String validcode) {this.validcode = validcode; }}Continuez à traiter Filter,
import com.core.shared.validatecodehandle; import org.springframework.security.core.authentication; import org.springframework.security.core.authenticationxception; import org.springframework.security.web.autentication.abstractAuthenticationProcessingFilter; Importer; org.springframework.security.web.util.matcher.antpathrequestmatcher; import javax.servlet.servletException; importer javax.servlet.http.httpservletRequest; importation javax.servlet.httter java.io.ioException; classe publique MyValidCodeProcessingFilter étend AbstractAuthenticationProcessingFilter {private String usernameParam = "username"; chaîne privée PasswordParam = "Password"; chaîne privée validcodeparam = "validatecode"; public myValidCodeProcessingFilter () {super (new antpathRequestmatcher ("/ user / ligin", "post")); } @Override Public Authentication TentierAuthentication (HttpServLetRequest Request, HttpServletResponse Response) lève AuthenticationException, ioException, servlexception {String username = request.getParameter (userNameParam); String Password = request.getParameter (PasswordParam); String validcode = request.getParameter (validCodeParam); valide (validcode, request.getSession ()); MyUserNamePasswordAuthenticationToken token = new MyUserNamePasswordAuthenticationToken (nom d'utilisateur, mot de passe, validcode); Renvoie ce.getAuthenticationManager (). Authenticiate (token); } public void valid (string validcode, httpSession session) {if (validcode == null) {throw new ValidCodeErRoreXception ("validatecode est vide!"); } if (! validatecodehandle.matchcode (session.getId (), validcode)) {lancez new ValidCodeErRoRORDException ("ValidCodeError!"); }}} Définissez trois paramètres séparément, qui sont utilisés pour recevoir les paramètres du formulaire de connexion. La méthode de construction donne l'URL de connexion et la méthode postale requise
Ensuite, l'authentification. Avant l'arrivée du nom d'utilisateur et du mot de passe d'authentification, j'ai simplement authentifié le code de vérification.
Voici une classe d'outils ValidateCodeHandle et ValidCodeErRorexception:
import java.util.concurrent.concurrentHashmap; public class validatecodehandle {private static concurrenthashmap validatecode = new concurrenthashmap <> (); public static concurrenthashmap getcode () {return validatecode; } public static void Save (String sessionId, String code) {validateCode.put (sessionId, code); } public static static getValidateCode (string sessionID) {objet obj = validateCode.get (sessionId); if (obj! = null) {return string.valueof (obj); } return null; } public static boolean matchcode (string sessionId, string inputcode) {string SAVECODE = getValidateCode (sessionId); if (SAVECODE.Equals (InputCode)) {return true; } return false; }}Ici, vous devez hériter d'authentification Exception pour indiquer qu'il s'agit d'un échec d'authentification de la sécurité, afin que le processus de défaillance ultérieur soit suivi.
import org.springframework.security.core.AuthenticationException; public class validCodeErRoLexception étend AuthenticationException {public validCodeErRoreXception (String msg) {super (msg); } public validCodeErRoreXception (String msg, throwable t) {super (msg, t); }}Ensuite, le fournisseur:
import org.springframework.security.authentication.badcredentialSException; import org.springframework.security.authentication.useramepasswordauthenticationtoken; import org.springframework.security.authentication.dao.daoautenticationprovider; importation. org.springframework.security.core.authenticationException; import org.springframework.security.core.userdetails.userdetails; classe publique myAuthenticationProvider étend daoauthenticationprovider {@Override public support booléen (class <?> Authentication) {return {return MyUserNamePasswordAuthenticationToken.class.isAssignableFrom (Authentication); } @Override Protected void supplémentaireAuthenticationChecks (userDetails userDetails, usernamepasswordAuthenticationToken Authentication) lève AuthenticationException {objet salt = null; if (getSALTSource ()! = null) {salt = getSAlTSource (). getSalt (userDetails); } if (authentication.getCredentials () == null) {logger.debug ("Authentification a échoué: aucune information fournie"); lancer un nouveau BadCredentialSexception ("Nom d'utilisateur ou erreur de mot de passe!"); } String présentépassword = authentication.getCredentials (). ToString (); if (! this.getPasswordEncoder (). iSpasswordValid (userdetails.getPassword (), présentée-mot, sel)) {logger.debug ("Authentification a échoué: le mot de passe ne correspond pas à la valeur stockée"); Jetez un nouveau BadCredentialSexception ("sous nom d'utilisateur ou mot de passe!"); }}} La méthode de support spécifie l'utilisation d'un jeton personnalisé, et la méthode supplémentaire AuthenticationChecks est exactement la même que la logique de la classe parent, je viens de modifier les informations renvoyées par l'exception.
Ensuite, le gestionnaire qui gère l'authentification réussie et l'authentification échouée
import org.springframework.security.core.authentication; import org.springframework.security.web.authentication.simpleurlauthenticationsuccesshandler; import javax.servletservletException; import javax.servlet.http.httpservletrequest; importer javax.servlet.http.httpservletrequest; Importer; javax.servlet.http.httpservletResponse; import java.io.ioException; public class frontAuthenticationsuCcessHandler étend SimpleUrlAuthenticationsUccessHandler {public frontAuthenticationsuCcessHandler (string defaultTargetUrl) {super (defaultargeTUrl); } @Override public void onAuthenticationsUCCESS (HttpServLetRequest Request, HttpServletResponse Response, Authentication Authentication) lève IOException, ServletException {super.onauthenticationsUccess (demande, réponse, authentification); }} import org.springframework.security.core.authenticationException; import org.springframework.security.web.authentication.simpleurlauthenticationfailurehandler; import javax.servlet.servletException; import javax.servlet.http.httpservletrequest; import; javax.servlet.http.httpservletResponse; Importer java.io.ioException; classe publique FrontAuthenticationFailureHandler étend SimpleUrlAuthenticationFailureHandler {public frontAuthenticationFailureHandler (String DefaultFailerUrl) {super (defaultFaileUrl); } @Override public void onAuthenticationFailure (demande httpservletRequest, réponse httpServletResponse, exception d'authentificationxception) lance ioException, servlexception {super.onauthenticationfailure (request, réponse, exception); }}Enfin, la configuration de sécurité la plus importante:
Importer com.service.user.CustomerService; import com.web.filter.sitemshfilter; import com.web.mysecurity. *; import org.springframework.beans.factory.annotation.bean; org.springframework.context.annotation.configuration; import org.springframework.core.annotation.order; import org.springframework.security.authentication.authenticationManager; import org.Springframework.securit org.springframework.security.authentication.providerManager; import org.springframework.security.config.annotation.web.builders.httpulenure; import org.springframework.Securit org.springframework.security.config.annotation.web.configuration.webSecurityConfigurerAdapter; import org.springframework.security.crypto.password.passwordcoder; org.springframework.security.web.access.ExceptionStRanslationFilter; import org.springframework.security.web.authentication.UsernamepasswordAuthenticationFilter; import org.springframework.security.web.contex org.springframework.web.filter.characterencodingfilter; import javax.servlet.dispatchertype; import javax.servlet.filterRegistration; import javax.servlet.servletcontext; import java.util.arraylist; import java.util.enumset; import; java.util.list; @ configuration @ activerwebSecurityPublic class SecurityConfig étend AbstractSecurityWebApplicationInitializer {@Bean Public MotswordEncoder PasswordEncoder () {return new StandardPasswordEncoder ("MD5"); } @Autowired Privy CurvityService CustomerService; @Configuration @Order (1) Classe statique publique FrontendWebSecurityConfigureAdapter étend WebSeCurityConfigurerAdapter {@autowired private myValidCodeProcessingFilter myValidCodeProcessingFilter; @Override Protected void Configure (httpSecurity http) lève une exception {http.csrf (). Disable () .AuthorizeRequests () .Antmatchers ("/ user / ligin", "/ user / logout"). Permutall () .anyRequest (). Authenticated () .and (). .adddFilterBefore (myValidCodeProcessingFilter, usernamepasswordAuthenticationFilter.class) .FormLogin () .logInPage ("/ user / Login") .and () .logout () .logoutUrl (user / LOGOUT ") .logoutsUCSURL (" / user / Login "); }} @Bean (name = "frontAuthenticationProvider") public myAuthenticationProvider frontAuthenticationProvider () {myAuthenticationProvider myAuthenticationProvider = new myAuthenticationProvider (); myAuthenticationProvider.SetUserDetailsService (CustomerService); myAuthenticationProvider.SetPassWordOner (MotswordEncoder ()); retourner myAuthenticationProvider; } @Bean public AuthenticationManager AuthenticationManager () {list <authenticationProvider> list = new ArrayList <> (); list.add (frontAuthenticationProvider ()); AuthenticationManager AuthenticationManager = new ProviderManager (liste); retour authenticationManager; } @Bean public myValidCodeProcessingFilter myValidCodeProcessingFilter (AuthenticationManager AuthenticationManager) {MyValidCodeProcessingFilter Filter = new MyValidCodeProcessingFilter (); filter.setAuthenticationManager (AuthenticationManager); Filter.SetAuthenticationsUCcessHandler (frontAuthenticationsUCcessHandler ()); filter.setAuthenticationFailureHandler (frontAuthenticationFailureHandler ()); filtre de retour; } @Bean public frontAuthenticationFailureHandler frontAuthenticationFailureHandler () {return new frontAuthenticationFailureHandler ("/ user / ligin"); } @Bean public frontAuthenticationsuCcessHandler frontAuthenticationsUCCeshHandler () {return new frontAuthenticationsuCcessHandler ("/ front / test"); } @Bean public myAuthenticationEntryPoint myAuthenticationEntryPoint () {return new myAuthenticationEntryPoint ("/ user / ligin"); }}Tout d'abord, c'est un haricot de la classe de cryptage, et Customypervice est un simple utilisateur de requête
@Service ("CustomerService") CLASSE PUBLIC CLIENTSERVICEIMPL implémente CustomerService {@Autowired Private UserDao UserDao; @Override public UserDetails LoadUserByUserName (String Username) lève UserNamenotFoundException {return userdao.findCustomerByUserName (nom d'utilisateur); }} Ensuite, FrontendWebsCurityConfigureAdapter. J'ai réécrit la méthode de configuration, d'abord désactiver CSRF, activer AMPORTIZERESCESTS (), où "/ user / connexion" et "/ user / déconnexion" lâchez la vérification de l'autorisation, et d'autres demandes nécessitent une authentification de connexion, puis addFilterBeForefore (). Avant d'ajouter mon MyValidCodeProcessingFilter personnalisé à l'USERNAMEPasswordAuthenticationFilter par défaut dans la sécurité, j'effectue d'abord mon authentification de paramètre personnalisée, puis FormLogin (), Configurer l'URL de connexion et l'URL de déconnexion, et l'URL de connexion, l'url de connexion, l'url de connexion, et l'URL de connexion pour déconnecter l'URL, c'est, je dois écrire un client vous-même.
Ensuite, la déclaration d'affichage de bean d'authentificationProvider, AuthenticationManager, ProcessingFilter, AuthenticationFailureHandler, AuthenticationsUccessHandler et EntryPoint.
Ci-dessous est Login.jsp
<body> <div> <formulaire: formulaire automatique AutoCletel = "false" commandname = "userdto" metheth = "post"> <div> <span> <b> $ {spring_security_last_exception.message} </b> </span> </div> username: <form: Path) path = "mot de passe" cssclass = "form-control" /> <br/> validatecode: <form: input path = "validatecode" cssclass = "form-control" /> <label> $ {validate_code} </ label> <div> <vabed> <entrée type = "checkbox" name = "Remember-me" /> Remember Me </ label> Value = "Soumider" /> </ Form: Form> </div> </odody>Lorsque le code de vérification échoue, la ValidCodeErRoreXception est lancée. Puisqu'il hérite de l'authentification Exception, lorsque la sécurité Rencontre AuthenticationException, l'authentificationFailureHandler sera déclenchée. Le bean ci-dessus déclare que l'authentification a échoué et saute à l'URL de connexion, il y a donc $ {Spring_Security_last_Exception.Message} dans Login.jsp. Les informations d'exception sont lancées lorsque je m'authentifie, ce qui peut inviter le convivial.
L'ensemble du processus de vérification de sécurité personnalisé est terminé
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.