أصل
في RABC القياسي ، تحتاج الأذونات إلى دعم التكوين الديناميكي ، والأمن الافتراضية للأمان الافتراضي للاتفاق على الأذونات في الكود. تتطلب سيناريوهات الأعمال الحقيقية عادةً تكوين أذونات الوصول إلى الأدوار ، أي تكوين أدوار الوصول المقابلة لعناوين URL في وقت التشغيل.
بناءً على أمن الربيع ، كيفية تحقيق هذا المطلب؟
أسهل طريقة هي تخصيص مرشح لإكمال حكم الإذن ، ولكن يتم فصل هذا عن إطار أمان الربيع. كيف تنفذها بأناقة بناءً على أمان الربيع؟
مراجعة ترخيص أمن الربيع
يتم استخدام Spring Security Filterchainproxy كمرشح للتسجيل في الويب. يحتوي FilterChainproxy على عدة مرشحات مدمجة في وقت واحد. أولاً ، نحتاج إلى فهم مختلف المرشحات المدمجة في أمن الربيع:
| الاسم المستعار | فئة المرشح | عنصر مساحة الاسم أو السمة |
|---|---|---|
| channel_filter | ChannelProcessingFilter | يتطلب http/intercept-url@قناة |
| Security_Context_Filter | SecurityContextPersistenceFilter | http |
| concurrent_session_filter | concurrentsessionfilter | إدارة الجلسة/السيطرة على التزامن |
| Headers_Filter | headerwriterfilter | http/الرؤوس |
| CSRF_FILTER | CSRFFILTER | HTTP/CSRF |
| logout_filter | logoutfilter | http/logout |
| x509_filter | x509AuthenticationFilter | http/x509 |
| pre_auth_filter | AbstractPreAuthenticatedProcessingFilter فئات فرعية | ن/أ |
| cas_filter | casauthenticationFilter | ن/أ |
| form_login_filter | usernamepasswordauthenticationfilter | http/form-login |
| basic_auth_filter | BasicAuthenticationFilter | HTTP/HTTP-BASIC |
| servlet_api_support_filter | SecurityContextholderawareRequestFilter | http/@servlet-api-provision |
| jaas_api_support_filter | JaasapiintegrationFilter | http/@jaas-api-provision |
| تذكر _me_filter | تذكر meauathenticationfilter | http/تذكر |
| Anonymous_filter | AnonymousauthenticationFilter | http/مجهول |
| Session_management_filter | SessionManagementFilter | إدارة الجلسة |
| استثناء _translation_filter | استثناء translationfilter | http |
| filter_security_interceptor | FiltersecurityInterceptor | http |
| switch_user_filter | SwitchUserFilter | ن/أ |
الشيء الأكثر أهمية هو FilterSecurityInterceptor ، الذي ينفذ منطق المصادقة الرئيسي ، والرمز الأكثر جوهريًا هنا:
InterceptorStatustoken المحمي قبل تحديد (كائن كائن) {// احصل على الأذونات المطلوبة للوصول إلى مجموعة url <NugmAttribute> = this.obtainsecuritymetaDataSource () .getattributes (كائن) ؛ المصادقة المصادقة = antextIctIFRequired () ؛ // المصادقة عبر AccessDecisionManager Try {this.accessDecisionManager.docide (مصادقة ، كائن ، سمات) ؛ } catch (AccessDenieDexception AccessDeniedException) {publishEvent (AuthorizationFailureEvent جديد (كائن ، سمات ، مصادقة ، AccessDenieDexception)) ؛ رمي AccessDeniedException ؛ } if (debug) {logger.debug ("Eutlization Success") ؛ } إذا (publishauthorizationsuccessful ") ؛} إذا (publishauthorizationsuccess) {publishevent (جديد ، upertizedevent (كائن ، سمات ، مصادقة))) ؛ {logger.debug ("Runasmanager لم يغير كائن المصادقة") ؛ SecurityContextholder.getContext () ؛كما يتضح من ما سبق ، لتحقيق مصادقة ديناميكية ، يمكننا أن نبدأ من جانبين:
دعونا نرى كيفية تنفيذها بشكل منفصل.
AccessDecisionManager المخصص
يعتمد كل من AccessDecisionManagers الرسميين الثلاثة على AccessDecisionVoter لتنفيذ مصادقة الإذن ، لذلك نحتاج فقط إلى تخصيص AccessDecisionVoter.
التخصيص ينفذ بشكل أساسي واجهة AccessDecisionVoter. يمكننا تنفيذ Awitter Roalevoter:
تنفذ RoleBasedVoter من الفئة العامة AccessDecisionVoter <Object> {Override Public Boolean Support (ConfigAttribute) {return true ؛ } Override public int التصويت (مصادقة المصادقة ، كائن الكائن ، التجميع <ConfigAttribute> سمات) {if (Authentication == NULL) {return access_denied ؛ } int result = access_abstain ؛ مجموعة <؟ يمتد prantedauthority> السلطات = المستخلصات (المصادقة) ؛ لـ (ConfigAttribute Attribute: entributes) {if (attribute.getAttribute () == null) {extre } if (this.supports (السمة)) {result = access_denied ؛ // محاولة العثور على سلطة ممنوحة مطابقة لـ (سلطة التأهيل: السلطات) {if (attribute.getAttribute (). equals (author.getauthority ())) {return access_granted ؛ }}}} نتيجة الإرجاع ؛ } مجموعة <؟ يمتد GrantedAuthority> المستخلصات (مصادقة المصادقة) {return antervication.getAuthorities () ؛ } Override Public Boolean Support (class clazz) {return true ؛ }}كيفية إضافة أذونات ديناميكية؟
نوع كائن كائن في vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) هو الترشيح ، ويمكنك الحصول على عنوان URL للطلب الحالي من خلال getRequesturl:
FilterInvocation fi = (filterInvocation) كائن ؛ url url = fi.getRequesturl () ؛
لذلك ، هناك مساحة كبيرة للتوسع هنا. يمكنك تحميله ديناميكيًا من DB ثم الحكم على تكوين URL.
كيفية استخدام هذا الأدوار المعزولة؟ استخدم طريقة AccessDecisionManager للتخصيص في التكوين. يجب أن نستخدم الرسوم غير القائم على غير القائم ، ثم نضيف rolebasedvoter المخصصة.
@enablewebscurity @enableglobalmethodsecurity (prepoStEnabled = true ، securedEnabled = true) فئة الأمان من الفئة العامة يمتد websecurityconfigureRadapter . // Custom AccessDecisionManager .AccessDecisionManager (AccessDecisionManager ()). و () .Apply (SecurityConfigureRadapter ()) ؛ } bean public AccessDecisionManager AccessDecisionManager () {list <AccessDecisionVoter <؟ يمتد الكائن >> DecentionVoters = Arrays.Aslist (New WebExpressionVoter () ، // new robovoter () ، new rolebasedvoter () ، new AuthenticatedVoter ()) ؛ إرجاع جديد غير قائم على القائمة (DecentionVoters) ؛ }تخصيص SecurityMetAdataSource
لا يحتاج FilterInvocationSecurityMatureAdataSource المخصص إلا إلى تنفيذ الواجهة ، وتحميل قواعد ديناميكي من DB في الواجهة.
من أجل إعادة استخدام التعريفات في الكود ، يمكننا أن نأخذ SecurityMetAdataSource الناتجة في الكود ونمر في FilterInvocationSecurityMetAdatasource في المنشئ.
الطبقة العامة AppFilterInvocationSecurityMetAdataSource تنفذ org.springframework.security.web.ancess.Intercept.filterInvocationSecurityMetAdataTasource Override Public Collection <SimpeAttribute> getAllConfigattributes () {return null ؛ } AppFilterInvocationSecurityMetAdataSource (FilterInvocationSecurityMetAdatasource ExpressionBasedFilterInvocationSecurityMetAdatasource) {this.SuperMetAdataSource = ExpressionBasedFilterInvocationSecurityMetAdatasource ؛ // تكوين إذن تحميل TODO من قاعدة البيانات} antpathmatcher النهائي الخاص = جديد antpathmatcher () ؛ // هنا تحتاج إلى تحميل الخريطة النهائية الخاصة <string ، string> urlrolemap = new hashmap <string ، string> () {{put ("/open/**" ، "rob_anonymous") ؛ ضع ("/Health" ، "rob_anynowyous") ؛ ضع ("/إعادة التشغيل" ، "rob_admin") ؛ ضع ("/demo" ، "rob_user") ؛ }} ؛ Override Public Collection <NovateTribute> getAttributes (كائن كائن) يلقي alfictalargumentException {filterInvocation fi = (filterInvocation) object ؛ url url = fi.getRequesturl () ؛ لـ (map.entry <string ، string> interp: urlrolemap.entryset ()) {if (antpathmatcher.match (entrate.getKey () ، url)) {return securityConfig.createlist (entry.getValue ()) ؛ }} // إرجاع التكوين الافتراضي المحدد بواسطة رمز إرجاع supramtadaDataSource.getAttributes (كائن) ؛ } Override Public Boolean Support (Class <؟> clazz) {return filterinvocation.class.isAssignableFrom (clazz) ؛ }}كيف تستخدمه؟ على عكس AccessDecisionManager ، لا يوفر ExpressionUrlauthorizationConfigurer طريقة محددة لتعيين FilterInvocationSecurityMetAdataSource of FiltersecurityInterceptor ، كيف تفعل؟
اكتشف طريقة تمديد withObjectPostProcessor ، والتي من خلالها تقوم بتخصيص ObjectPostProcessor الذي يتعامل مع نوع FilterSecurityInterceptor ، يمكنك تعديل FilterSecurityInterceptor.
@enablewebscurity @enableglobalmethodsecurity (prepoStEnabled = true ، securedEnabled = true) فئة الأمان من الفئة العامة يمتد websecurityconfigureRadapter . . FSI.SetSecurityMetAdataSource (MySecurityMetAdataSource (FSI.GetSecurityMetAdataSource ()) ؛ } bean public AppFilterInvocationSecurityMetAdataSource mySecurityMetAdataSource AppFilterInvocationSecurityMetAdataSource (FilterInvocationSecurityMetAdataSource) ؛ إرجاع SecurityMetAdataSource ؛}
ملخص
تقدم هذه المقالة طريقتين لتنفيذ أذونات ديناميكية بناءً على أمان الربيع. أحدهما هو تخصيص AccessDecisionManager ، والآخر هو تخصيص FilterInvocationSecurityMetAdataSource. يمكنك اختيار مرونة وفقًا لاحتياجاتك في المشاريع الفعلية.
مزيد من القراءة:
بنية أمان الربيع وتحليل رمز المصدر
لخص
ما سبق هو المحتوى الكامل لهذه المقالة. آمل أن يكون لمحتوى هذه المقالة قيمة مرجعية معينة لدراسة أو عمل الجميع. إذا كان لديك أي أسئلة ، فيمكنك ترك رسالة للتواصل. شكرا لك على دعمك إلى wulin.com.