تروي هذه المقالة قصة SPRING BOOT التي تدمج Spring Security لتنفيذ التحكم في الإذن باستخدام التعليقات التوضيحية على الأساليب ، واستخدام مستخدم userDetailService مخصص لتحميل معلومات المستخدم من MySQL. استخدم تشفير MD5 الذي يأتي مع الأمان لتشفير كلمة مرور المستخدم. يستخدم قالب الصفحة محرك ThymeLeaf.
عنوان رمز المصدر: https://github.com/li5454yong/springboot-security.git
1. إدخال تبعيات POM
<Arnal> <roupl> org.springframework.boot </groupId> <intifactid> spring-boot-starter-parent </shintifactid> <sophy> 1.4.4 <StifactId> Spring-Boot-Starter-Web </shintifactid> </sependency> <reperency> <roupiD> org.springframework.boot </rougeid> <StifactId> spring-boot-starter-security </stifactid> </sependenc <StifactId> Spring-Security-OAuth2 </stifactid> </sependency> <reperency> <roupiD> org.springframework.boot </groupiD> <StifactId> spring-boot-starter-thymeleaf </stifactid> <StifactId> Spring-boot-starter-data-JPA </stifactid> </reperence> <reperence> <roupiD> org.springframework.boot </rougeid> <StifactId> spring-boot-starter-jdbc </semptactid> </rependency> <StifactId> mysql-connector-java </stifactid> <الإصدار> 5.1.34 </version> </repreadency> <reperency> <roupiD> com.alibaba </rougiD> </referency> druid </shintifactid> <splem
هنا ، استخدم تجميع اتصال Druid ، و Dring Data JPA ينفذ الوصول إلى قاعدة البيانات.
2. تكوين أمان الربيع
@configuration @enableWebmvcSecurity @enableGlobalmethodSecurity (prepostenabled = true) // تمكين التعليقات المتعلقة بالتعليقات الأمنية ، فئة WebSecurity ClasseConfig يمتد WebSecurityConfigureRadapter {bean @override المصادقة المحمية Override AuthenticationManager () Throws Throws {return super.authentication () ؛ } override contected void التكوين (httpsecurity http) يلقي استثناء {// السماح لجميع المستخدمين بالوصول إلى "/" و "/home" http.authorizerequests () .antmatchers ("/" ، "/home"). // حدد صفحة تسجيل الدخول لتكون "/login" .loginPage ("/login") .DefaultSuccessurl ("/hello") // بعد تسجيل الدخول الناجح ، القفز إلى "/hello" افتراضيًا. .permitall (). و () .logout () .logoutsuccessurl ("/home") // عنوان URL الافتراضي بعد تسجيل الخروج هو "/home" .permitall () ؛ } autowired public void configglobal (AuthenticationManagerBuilder Auth) يلقي الاستثناء {auth .userDetailsService (customerDetailsService ()) .passwordencoder (passwordencoder () ؛ } / *** قم بتعيين طريقة التشفير لكلمة مرور المستخدم إلى تشفير MD5* return* / bean public md5passwordercoder passwerencoder () {إرجاع md5passwordencoder () ؛ } / *** مخصص userDetailsService لقراءة معلومات المستخدم من قاعدة البيانات* regurn* / bean publicuserDetailsService chemuSerDetailsService () {return new CustomerDetailsService () ؛ }} يتم إجراء تكوينات أساسية فقط هنا ، وإعداد عنوان URL لتسجيل الدخول ، وعنوان URL الذي يقفز بعد تسجيل الدخول ناجح ، وعنوان URL الذي يقفز بعد تسجيل الدخول. باستخدام التعليق التوضيحي enableglobalmethodsecurity (prepostenabled = true) يمكن أن يمكّن من شرح الأمن. يمكننا استخدام preauthorize و @prefilter على الأساليب التي تتطلب أذونات التحكم.
3. مخصص userDetailservice
الفئة العامة customerDetailsService تنفذ userDetailsService {Autowired // فئة خدمة المجال الخاصة suserservice waitservice ؛ Override public userdetails loadUserByUsername (اسم المستخدم السلسلة) يلقي usernamenotfoundException {// Suser يتوافق مع جدول المستخدم في قاعدة البيانات ، وهو الجدول الذي يخزن في النهاية المستخدم وكلمة المرور ، والتي يمكن تخصيصها // هذا المثال يستخدم البريد الإلكتروني في اسم المستخدم: SusererService.Finduserby.Findery. if (user == null) {رمي usernamenotfoundException جديد ("اسم المستخدم" + اسم المستخدم + "غير موجود") ؛ }. Collection <SimgrantEdauthority> السلطات = ArrayList جديد <SimplgrantedAuthority> () ؛ السلطات. add (جديد simplegrantedauthority ("rob_admin")) ؛ إرجاع الأمن. }}هنا تحتاج فقط إلى تنفيذ واجهة userDetailsService ، وإعادة كتابة طريقة LoadUserByUserName ، واسترداد معلومات المستخدم من قاعدة البيانات. أخيرًا ، يتم إرجاع فئة تنفيذ userDetails.
4. تحديد تكوين معالجة الخطأ
ConfigurationPublic Class ErrorPageConfig {bean public inmbedservletcontainercustomizer inmbedservletcontainercustomizer () {return new mycustomizer () ؛ } تنفذ الفئة الثابتة الخاصة mycustomizer inserdedServletContainerCustomizer {Override Public Void (ConfigableMedDedServletContainer Container) {Container.AdderRorpages (new errorpage (httpstatus.forbidden ، "/403")) ؛ }}}عند حدوث خطأ في الوصول ، قفز إلى "/403".
5. واجهة وحدة التحكم
controllerpublic class indexController {ersource private suserservice suserservice ؛ requestmapping ("/home") public string home () {return "home" ؛ } preAuthorize ("hasrole ('user')") @requestmapping (value = "/admin" ، method = requestMethod.get) public string toadmin () {return "helloadmin" ؛ } @requestmapping ("/hello") السلسلة العامة Hello () {return "hello" ؛ } @requestmapping ("/login") public string login () {return "login" ؛ } @requestmapping ("/") public string root () {return "index" ؛ } @requestmapping ("/403") خطأ في السلسلة العامة () {return "403" ؛ }}يتم استخدام @preAuthorize ("Hasrole ('user'))") على طريقة toadmin () ، مما يشير إلى أنك بحاجة إلى دور المستخدم للوصول إلى هذه الطريقة. إذا كنت ترغب في التحكم في مستوى الأذونات ، فيمكنك استخدام preauritize ("haspermission ()"). هذا مجرد واحد من الاستخدامات. لمزيد من طرق الاستخدام ، يمكنك قراءة الوثائق الرسمية. تجدر الإشارة إلى أن بادئة الدور الافتراضي لأمن الربيع هي "دور_" ، والتي تمت إضافتها افتراضيًا عند استخدام طريقة Hassrole. لذلك ، يجب أن يكون دور المستخدم في قاعدة البيانات "rob_user" ، ويتم إضافة بادئة المستخدم "rob_" قبل المستخدم.
6. اختبار
ابدأ المشروع وزيارة http: // localhost: 1130/تسجيل الدخول
انقر لتسجيل الدخول وأدخل "/مرحبا"
انقر للقفز إلى صفحة المسؤول
في عنوان URL الخلفية "/admin" المقابل لطريقة "المستخدم" ، يجب أن يكون للمستخدمين دور "المستخدم". يتم تعيين المستخدم الذي سجل الدخول أيضًا في قاعدة البيانات للحصول على هذا الدور.
الآن نقوم بتعديل دور المستخدم في قاعدة البيانات ونغيره إلى "rob_admin". بعد تسجيل الخروج ، قم بتسجيل الدخول مرة أخرى ، انقر فوق الزر "انتقل إلى صفحة المسؤول" مرة أخرى ، وسيقفز إلى الصفحة التالية.
نظرًا لعدم وجود إذن "مستخدم" الآن ، تم طرح استثناء أثناء الوصول ، وتم اعتراضه وإعادة توجيهه إلى "/403".
7. الوصول بعد الوصول ، رمز الخطأ 403
أولاً ، التغيير "/المسؤول" لنشر الطلب
preAuthorize ("hasrole ('user')") requestMapping (value = "/admin" ، method = requestMethod.post) public string toadmin () {return "helloadmin" ؛ }قم بتغيير طريقة الطلب لزر "انتقل إلى صفحة المسؤول" من تعبير النموذج الأصلي ، احصل على تقديم إلى Ajax Post Simplision. بالنسبة إلى سبب عدم تقديمنا باستخدام POST POST ، سنتحدث عنها لاحقًا. قم بتعديل الرمز أولاً
<Body> <h1 th: inline = "text"> hello [[$ {#httpservletrequest.remoteuser}]]! </h1> <!-<form th: action = "@{/logout}" method = "post"> <post type = "submit" value = ty: type = "pridt" th: value = "انتقل إلى صفحة المسؤول"/> </form>-> <a th: href = "{/admin}" rel = "خارجي nofollow"> انتقل إلى صفحة مستخدم المسؤول </a> <input th: type = "prident" onClick = "testPost ()" th: value = $ .ajax ({url: "/admin" ، النوع: 'post' ، النجاح: function (data) {}}) ؛ } </script> انقر فوق الزر "انتقل إلى صفحة المسؤول" ، ويمكنك رؤية ما يلي في منصة تصحيح الأخطاء
وذلك لأن الإطار يمنع CSRF (طلب التزوير عبر المواقع عبر المواقع) من الحدوث ، مما يحد من معظم الأساليب باستثناء الحصول على.
هنا حل:
أضف أولاً المحتوى التالي في العلامة.
<meta name = "_ csrf" th: content = "$ {_ csrf.token}"/> <meta name = "_ csrf_hader" th: content = "$ {_ csrf.headername}"/> طالما تمت إضافة هذا الرمز المميز ، فإن الخلفية ستتحقق من صحة هذا الرمز المميز. إذا كان هذا صحيحًا ، فسيقبل الوصول إلى ما بعد.
ثم أضف الرمز التالي في رمز Ajax:
var token = $ ('meta [name = "_ csrf"]'). attr ("content") ؛ var header = $ ('meta [name = "_ csrf_hader"]'). attr ("content") ؛ $ (document) .ajaxSend (function (e ، xhr ، opt) وبهذه الطريقة ، يمكنك الوصول إليها عادة باستخدام Post و Delete وغيرها من الطرق.
المذكورة أعلاه باستخدام طريقة نشر النموذج لتقديم. يمكنك أن ترى من خلال عرض الكود المصدري للصفحة.
يقوم الإطار تلقائيًا بإدراج حقل مخفي في النموذج ، وقيمة القيمة هي الرمز المميز ، لذلك يمكن تمرير نموذج النموذج لإرسال طلب نشر مباشرة ، وإذا قمت بإرساله بطريقة AJAX ، فيجب إضافة هذا الرمز.
حسنًا ، هذا كل شيء عن هذا المقال. ستكون هناك مقالات لاحقًا حول كيفية استخدام Spring Security للتحكم في الأذونات في نمط REST API.
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.