Spring Security هو وحدة كبيرة ، وهذه المقالة لا تتضمن سوى مصادقة المعلمات المخصصة. معلمات التحقق الافتراضية لأمن الربيع هي فقط اسم المستخدم وكلمة المرور ، والتي لا تكفي عمومًا. لأن الوقت قد مرت لفترة طويلة ، والبعض الآخر قد ينسى وقد يكون بعضها مفقود. حسنًا ، لا هراء.
تستخدم تكوينات أمان الربيع والربيع javaconfig ، والإصدارات هي 4.2.5 و 4.0.4 بدورها.
الفكرة الإجمالية: تخصيص نقطة الإدخال ، أضف معلمات مخصصة لتوسيع AuthenticationToken و AuthenticationProvider للتحقق.
حدد أول نقطة دخول:
استيراد org.springframework.security.core.AuthenticationException ؛ استيراد org.springframework.security.web.Authentication.loginurlauthenticationentrypoint ؛ import javax.servlet.servletexception ؛ javax.servlet.http.httpletrequest ؛ javax.servlet.http.httpservletresponse ؛ import java.io.ioException ؛ فئة myauthenticationentrypoint العامة تمتد loginurlauthenticationentrypoint } Override public void بدء (طلب httpservletrequest ، استجابة httpservletresponse ، antainticationexception uplyexception) يلقي iOexception ، servletexception {super.sommence (طلب ، استجابة ، AuthException) ؛ }}التالي هو الرمز المميز ، ValidCode هو معلمة رمز التحقق:
استيراد org.springframework.security.authentication.usernamepasswordauthenticationToken ؛ الطبقة العامة myusernamepasswordauthenticationtoken تمتد usernamepasswordauthenticationtoken public myusernamepasswordauthenticationToken (سلسلة السلسلة ، بيانات الاعتماد السلسلة ، سلسلة alvalCode) {super (principal ، بيانات الاعتماد) ؛ this.validCode = validCode ؛ } السلسلة العامة getValidCode () {return alvalCode ؛ } public void setValidCode (String appalCode) {this.validCode = appalCode ؛ }}متابعة المعالجة ،
استيراد com.core.shared.validateCodeHandle ؛ استيراد org.springframework.security.core.authentication ؛ استيراد org.springframework.security.core.AuthentEctionEcception org.springframework.security.web.util.matcher.antpathrequestmatcher ؛ استيراد javax.servlet.servletexception ؛ استيراد javax.servlet.http.httpservletrequest ؛ java.io.ioException ؛ الطبقة العامة myvalidCodeProcessingFilter يمتد مجردة uTreasicationProcessingFilter {private string usernameparam = "username" ؛ سلسلة passwordparam = "كلمة المرور" ؛ سلسلة خاصة validCodeParam = "ValidateCode" ؛ public myvalidCodeProcessingFilter () {super (جديد antathrequestMatcher ("/user/login" ، "post")) ؛ } Override Override Public Anughtication (HttPservletRequest request ، httpservletresponse) يلقي المصادقة ، ioException ، servleTexception {String username = request.getParameter (usernameparam) ؛ سلسلة كلمة المرور = request.getParameter (passwordparam) ؛ string appalCode = request.getParameter (validCodeParam) ؛ صالح (appalCode ، request.getSession ()) ؛ myusernamepasswordauthenticationtoken token = جديد myusernamepasswordauthenticationtoken (اسم المستخدم ، كلمة المرور ، alvalCode) ؛ إرجاع this.getAuthenticationManager (). المصادقة (الرمز المميز) ؛ } void public applicated (سلسلة alvalCode ، جلسة httpsession) {if (valedCode == null) {throw new valedCodeerRorexception ("ValidateCode فارغ!") ؛ } if (! validateCodeHandle.MatchCode (session.getId () ، alvalCode)) {رمي جديد ValidCodeRorerorexception ("ValidCodeerror!") ؛ }}} تحديد ثلاث معلمات بشكل منفصل ، والتي تستخدم لتلقي المعلمات من نموذج تسجيل الدخول. تعطي طريقة البناء عنوان URL لتسجيل الدخول وطريقة البريد المطلوبة
التالي هو المصادقة. قبل وصول اسم مستخدم وكلمة مرور المصادقة ، قمت للتو المصادقة على رمز التحقق.
فيما يلي فئة الأدوات ValidateCodeHandle و ValidCodeerRorexception:
استيراد java.util.concurrent.concurrenthashmap ؛ فئة عامة ValiteCodeHandle {private static concurrenthashmap validateCode = new ConcurrentHashMap <> () ؛ concurrenthashmap getCode () {return validateCode ؛ } void static static save (String SessionId ، رمز السلسلة) {validateCode.put (SessionId ، Code) ؛ } السلسلة الثابتة العامة getValidateCode (سلسلة SessionId) {object obj = validateCode.get (SessionId) ؛ if (obj! = null) {return string.valueof (obj) ؛ } إرجاع فارغ ؛ } static matchcode static static (سلسلة SessionId ، string inputCode) {String SaveCode = getValidateCode (SessionId) ؛ if (sevecode.equals (inputCode)) {return true ؛ } إرجاع خطأ ؛ }}تحتاج هنا إلى ورث المصادقة extractication للإشارة إلى أنه فشل مصادقة أمان ، بحيث سيتم اتباع عملية الفشل اللاحقة.
استيراد org.springframework.security.core.AuthenticationException ؛ الفئة العامة ValidCodeerRorexception يمتد المصادقة {public alvalCodeerRorexception (string msg) {super (msg) ؛ } public appalCodeerRorexception (String msg ، thrainable t) {super (msg ، t) ؛ }}التالي هو الموفر:
استيراد org.springframework.security.authentication.BadcredentialSexception ؛ استيراد org.springframework.security.authentication.usernamepasswordauthenticationtoken ؛ استيراد org.springframework.security.authentication.dao org.springframework.security.core.AuthenticationException ؛ استيراد org.springframework.security.core.userDetails.userDetails ؛ الطبقة العامة myauthenticationprovider يمتد daoauthenticationprovider myusernamepasswordauthenticationToken.class.isAsassignableFrom (المصادقة) ؛ } override void proideAuthenticationChes (userDetails userDetails ، usernamepasswordauthenticationtoken مصادقة) يرمي المصادقة {كائن الملح = null ؛ if (getSaltSource ()! = null) {salt = getSaltsource (). getSALT (userDetails) ؛ } if (Authentication.getCredentials () == null) {logger.debug ("فشل المصادقة: لم يتم توفير بيانات اعتماد") ؛ رمي badcredentialsexception جديد ("اسم المستخدم أو خطأ كلمة المرور!") ؛ } string passpassword = antaintication.getCredentials (). toString () ؛ if (! this.getPasswordenCoder (). isPasswordValid (userDetails.getPassword () ، provespassword ، salt)) {logger.debug ("المصادقة فشل: كلمة المرور لا تتطابق مع القيمة المخزنة") ؛ رمي badcredientialsexception جديد ("تحت اسم المستخدم أو كلمة المرور!") ؛ }}} تحدد طريقة الدعم استخدام الرمز المميز المخصص ، وتكون طريقة الإضافات الإضافية هي نفس منطق فئة الوالدين ، لقد قمت فقط بتغيير المعلومات التي تم إرجاعها بواسطة الاستثناء.
التالي هو المعالج الذي يتعامل مع المصادقة الناجحة والفشل المصادقة
استيراد org.springframework.security.core. javax.servlet.http.httpservletresponse ؛ import java.io.ioException ؛ public frontauthenticationsuccessHandler تمتد SimplyurlauthenticationsAcsHandler {publicuthenticationsuccessHandler (String defaultTargeturl) {supertargeturl) ؛ } Override public void onauthenticationationsuccess (httpservletrequest request ، httpservletresponse ، مصادقة المصادقة) يلقي iOexception ، servleTexception {super.onauthenticationsuccess (طلب ، استجابة ، مصادقة) ؛ }} استيراد org.springframework.security.core.AuthenticationException ؛ استيراد org.springframework.security.web.Authentication.SimpleUrlauthentIctionFailureHandler javax.servlet.http.httpservletresponse ؛ import java.io.ioException ؛ فئة public frontauthenticationfailureHandler تمتد simplyurlauthenticationfailurehandler {public frontaUticationFailureHandler (String defaultFailureUrl) } Override public void onAuthenticationFailure (طلب httpservletrequest ، استجابة httpservletresponse ، استثناء المصادقة antainedException) يلقي ioException ، servletexception {super.onauthenticationfailure (طلب ، استجابة ، استثناء) ؛ }}أخيرًا ، أهم تكوين أمان:
استيراد com.service.user.customerservice ؛ استيراد com.web.filter.sitemeshfilter ؛ استيراد com.web.mysecurity.*؛ org.springframework.context.annotation.Configuration ؛ استيراد org.springframework.core.antation org.springframework.security.authentication.providermanager ؛ استيراد org.springframework.security.config.antation.web.builders.httpsecurity org.springframework.security.config.annotation.web.configuration.websecurityConfigureRadapter ؛ استيراد org.springframework.security.crypto.password.passworderencoder org.springframework.security.web.access.ExceptionTranslationFilter ؛ import org.springframework.security.web.authentication.usernamepasswordauthenticationfilter ؛ import org.springframework.security.web.Web.AbstractecurityNitialication ؛ org.springframework.web.filter.characterencodingfilter ؛ import javax.servlet.dispatchertype ؛ import javax.servlet.filterregistration ؛ import javax.servlet.servletcontext java.util.list ؛@configuration@enableWebsCurityPublic Class SecurityConfig يمتد ملخصات AsscripeSecurityWebApplicationInitializer {Bean Public PassworderCoder () } autowired Privateerviceervice configuration @order (1) فئة ثابتة عامة FrontendWebsCurityConfigureAdapter يمتد websecurityConfigureRadapter {autowired myvalidCodeProcessingFilter myvalidCodeProcessingfilter ؛ Override تكوين باطل محمي (httpsecurity http) يلقي استثناء {http.csrf (). disable () .AuthorizereQuests () .antmatchers ("/user/login" ، "/المستخدم/logout"). .addfilterbefore (myValIdCodeProcessingFilter ، usernamePasswordauthenticationFilter.class) .formlogin () .loginPage ("/user/login"). و. }} @bean (name = "frontauthenticationprovider") public myauthenticationprovider frontauthenticationprovider () {myAuthenticationProvider myauthenticationprovider = new myuuthenticationprovider () ؛ myAuthenticationProvider.setUserDetailsService (customerervice) ؛ myAuthenticationProvider.setPasswordenCoder (passwordencoder ()) ؛ إعادة myauthenticationprovider ؛ } Bean Public AuthenticationManager AuthenticationManager () {list <IentalicProvider> list = new ArrayList <> () ؛ list.add (frontauthenticationprovider ()) ؛ antainticationManager AuthenticationManager = جديد providermanager (قائمة) ؛ إرجاع المصادقة. } bean public myvalidCodeProcessingFilter myvalidCodeProcessingFilter (مصادقة anuffticationManager) Filter.SetAuthenticationManager (AuthenticationManager) ؛ Filter.SetAuthenticationsuccessHandler (FrontAuthenticationationsuccessHandler ()) ؛ Filter.SetAuthenticationFailureHandler (FrontAuthenticationFailureHandler ()) ؛ مرشح الإرجاع } bean public frontaUnticationFailureHandler FrontaUthenticationFailureHandler () {return new FrontauthenticationFailureHandler ("/user/login") ؛ } bean public frontaUnticationationsuccessHandler FrontaUthenticationsuccessHandler () {return new FrontAuthenticationsuccessHandler ("/front/test") ؛ } bean public myAuthenticationEntryPoint myAuthenticationEntryPoint () {return new myAuthenticationEntryPoint ("/user/login") ؛ }}بادئ ذي بدء ، إنه فول من فئة التشفير ، و CustomerVice هو مستخدم بسيط للاستعلام
Service ("Clientservice") فئة PublicerViceImpl التي تنفذها Corperningervice {Auutowired private userdao userdao ؛ Override public userDetails loadUserByUserName (اسم المستخدم username) يلقي usernamenotfoundException {return userDao.findCustomerByUsername (اسم المستخدم) ؛ }} التالي هو FrontEndWebSecurityConfigureAdapter. لقد قمت بإعادة كتابة طريقة التكوين ، وقم بتعطيل CSRF أولاً ، وتمكين eventizeRequests () ، حيث تتطلب "/تسجيل الدخول" و "/المستخدم/تسجيل الدخول" التحقق من الإذن ، وتتطلب الطلبات الأخرى مصادقة تسجيل الدخول ، ثم addFilterbefore (). قبل إضافة MyValidCodeProcessingFilter المخصص إلى UsernamePasswordauthenticationFilter في الأمان ، أقوم أولاً بإجراء مصادقة المعلمة المخصصة ، ثم Formlogin () ، وتكوين URL لتسجيل الدخول إلى URL ، و URL Logout ، وعنوان URL لتسجيل الدخول URL ، وتسجيل الدخول إلى URL لتسجيل الدخول ،
التالي هو إعلان عرض Bean لـ AuthenticationProvider و AuthenticationManager و ProcessingFilter و AuthenticationFailureHandler و AuthenticationsuccessHandler و EntryPoint.
أدناه هو login.jsp
<Body> <viv> <form: form form autocomplete = "false" commandName = "userDto" method = "post"> <viv> <span> <b> $ {spring_security_last_exception.message} </b> </b> </div> username: <form: path path = "username" path = "password" cssclass = "form-control"/> <br/> ValidateCode: <form: input path = "validatecode" cssclass = "form-control"/> <label> $ {validate_code} </label> <div> value = "submit"/> </form: form> </viv> </body>عند فشل رمز التحقق ، يتم إلقاء alvalCodeerRorexception. نظرًا لأنه يرث المصادقة ، عندما يواجه الأمان المصادقة ، سيتم تشغيل المصادقة FailureHandler. تعلن الفول أعلاه أن المصادقة فشلت وتقفز إلى عنوان URL لتسجيل الدخول ، لذلك هناك $ {spring_security_last_exception.message} في login.jsp. يتم إلقاء معلومات الاستثناء عند المصادقة ، مما قد يطالب بالسهولة.
تم الانتهاء من عملية التحقق من الأمان المخصصة بأكملها
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.