باستخدام Metaclass Groovy لسخرية Shiro SecurityUtils في Bootstrap
-
19-09-2019 - |
سؤال
لمزيد من الخلفية، انظر http://grails.markmail.org/message/62w2xpgneapmhpd.
أحاول أن أسخر من SHIRO SecurityUtils.getSubject () طريقة في bootstrap.groovy. قررت في هذا النهج لأن منشئ الموضوع في أحدث إصدار Shiro غير متوفر في الإصدار الحالي من البرنامج المساعد NIMBLE (الذي أستخدمه). قررت أن أحاول اللعب مع Securityutils.Metaclass ولكن لدي شعور بأنني أفتقد شيئا أساسيا حول كيفية عمل Metaclasses. للرجوع اليها، إليك الطبق القابل للتتبع:
abstract class Trackable {
User createdBy
Date dateCreated
User lastUpdatedBy
Date lastUpdated
static constraints = {
lastUpdated(nullable:true)
lastUpdatedBy(nullable:true)
createdBy(nullable:true)
}
def beforeInsert = {
def subject
try {
subject = SecurityUtils.subject
} catch (Exception e) {
log.error "Error obtaining the subject. Message is [${e.message}]"
}
createdBy = (subject ? User.get( subject.principal ) :
User.findByUsername("admin"))
}
def beforeUpdate = {
def subject
try {
subject = SecurityUtils.subject
} catch (Exception e) {
log.error "Error obtaining the subject. Message is [${e.message}]"
}
lastUpdatedBy = (subject ? User.get( subject.principal ) :
User.findByUsername("admin"))
}
}
في بلدي bootstrap.groovy، لدي هذا:
def suMetaClass = new ExpandoMetaClass(SecurityUtils)
suMetaClass.'static'.getSubject = {[getPrincipal:{2}, toString:{"Canned Subject"}] as Subject}
suMetaClass.initialize()
SecurityUtils.metaClass = suMetaClass
وهذا يعمل ... نوع من. إذا قمت بطباعة الموضوع من Bootstrap.groovy، أحصل على "موضوع معلب". إذا حاولت إنشاء وحفظ مثيلات الفئات الفرعية القابلة للتتبع، أحصل على:
No SecurityManager accessible to this method, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton. See the org.apache.shiro.SecurityUtils.getSubject() method JavaDoc for an explanation of expected environment configuration.
هل أفتقد شيئا ما لا يتجزأ حول كيفية عمل metaclasses؟
المحلول
لقد اكتشفت ما كان يحدث. في بلدي bootstrap كنت أفعل شيئا مثل هذا:
def init = { servletContext->
switch (Environment.current.name) {
case "local":
def suMetaClass = new ExpandoMetaClass(SecurityUtils)
suMetaClass.'static'.getSubject = {[getPrincipal:{2}, toString:{"Canned Subject"}] as Subject}
suMetaClass.initialize()
SecurityUtils.metaClass = suMetaClass
new TrackableSubClass().save()
//Create some other domain instances
SecurityUtils.metaClass = null
}
//Create a couple domain instances that aren't environment specific
}
أضفت بعض بيانات التصحيح ورأيت أن الأخطاء التي كنت أراها كانت تحدث في نهاية إغلاق النسخة الأولية. فعلت بعض googling لفحص مزدوج كيفية تدفق جلسة السبات الخاصة بي. ثم قمت بالتغييرات التالية:
def sessionFactory
def init = { servletContext->
switch (Environment.current.name) {
case "local":
def suMetaClass = new ExpandoMetaClass(SecurityUtils)
suMetaClass.'static'.getSubject = {[getPrincipal:{2}, toString:{"Canned Subject"}] as Subject}
suMetaClass.initialize()
SecurityUtils.metaClass = suMetaClass
new TrackableSubClass().save()
//Create some other domain instances
sessionFactory.currentSession.flush()
SecurityUtils.metaClass = null
}
//Create a couple domain instances that aren't environment specific
}
يبدو أن هذا قد حل المشكلة تماما والآن يجب أن أكون قادرا على إزالة كتل TRY / CAMK المرهقة من القابل للتتبع. :-)