javascript
pdf secured_使您的Spring Security @Secured注释更干燥
pdf secured
最近,Grails用戶郵件列表中的一個用戶想知道在定義@Secured注釋時如何減少重復 。 在Java批注中指定屬性的規則非常嚴格,因此我看不到直接執行他所要求的方法的方法。
使用Groovy并沒有真正的幫助,因為Groovy類中的注釋大部分與Java中的注釋幾乎相同(數組值的語法除外)。 當然,Groovy現在支持注釋中的閉包,但這需要在插件中進行代碼更改。 但是后來我想到了Jeff Brown最近在緩存插件中所做的一些工作。
Spring的緩存抽象API包括三個注釋。 @Cacheable , @CacheEvict和@CachePut 。 我們正在考慮支持比這些注釋所允許的更多的配置選項,但是由于您無法對注釋進行子類化,因此我們決定使用AST轉換來查找這些注釋的版本(當前具有與Spring注釋相同的屬性)并進行轉換有效的Spring注釋。 因此,我查看了Jeff的代碼 ,它最終成為解決此問題的基礎。
無法使用代碼外部化權限列表,因為您無法控制編譯順序。 因此,我最終得到了一個不完美但可以使用的解決方案–我在項目根目錄中尋找一個屬性文件( roles.properties )。 格式很簡單–密鑰是每個權限列表的名稱,值是權限名稱的列表,以逗號分隔。 這是一個例子:
admins=ROLE_ADMIN, ROLE_SUPERADMIN switchUser=ROLE_SWITCH_USER editors=ROLE_EDITOR, ROLE_ADMIN這些鍵是用于新@Authorities批注的值:
package grails.plugins.springsecurity.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.codehaus.groovy.transform.GroovyASTTransformationClass; /** * @author Burt Beckwith */ @Target ({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE}) @Retention (RetentionPolicy.RUNTIME) @Inherited @Documented @GroovyASTTransformationClass ( "grails.plugins.springsecurity.annotation.AuthoritiesTransformation" ) public @interface Authorities { /** * The property file key; the property value will be a * comma-delimited list of role names. * @return the key */ String value(); }例如,這是一個使用新注釋的控制器:
@Authorities ( 'admins' ) class SecureController { @Authorities ( 'editors' ) def someAction() { ... } }這等效于此控制器(如果使用@Authorities反編譯,則會看到兩個注釋):
@Secured ([ 'ROLE_ADMIN' , 'ROLE_SUPERADMIN' ]) class SecureController { @Secured ([ 'ROLE_EDITOR' , 'ROLE_ADMIN' ]) def someAction() { ... } }AST轉換類使用屬性文件中指定的角色名稱查找@Authorities批注,加載屬性文件并添加新的@Secured批注(不會刪除@Authorities批注):
package grails.plugins.springsecurity.annotation; import grails.plugins.springsecurity.Secured; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Properties; import org.codehaus.groovy.ast.ASTNode; import org.codehaus.groovy.ast.AnnotatedNode; import org.codehaus.groovy.ast.AnnotationNode; import org.codehaus.groovy.ast.ClassNode; import org.codehaus.groovy.ast.expr.ConstantExpression; import org.codehaus.groovy.ast.expr.Expression; import org.codehaus.groovy.ast.expr.ListExpression; import org.codehaus.groovy.control.CompilePhase; import org.codehaus.groovy.control.SourceUnit; import org.codehaus.groovy.transform.ASTTransformation; import org.codehaus.groovy.transform.GroovyASTTransformation; import org.springframework.util.StringUtils; /** * @author Burt Beckwith */ @GroovyASTTransformation (phase=CompilePhase.CANONICALIZATION) public class AuthoritiesTransformation implements ASTTransformation { protected static final ClassNode SECURED = new ClassNode(Secured. class ); public void visit(ASTNode[] astNodes, SourceUnit sourceUnit) { try { ASTNode firstNode = astNodes[ 0 ]; ASTNode secondNode = astNodes[ 1 ]; if (!(firstNode instanceof AnnotationNode) || !(secondNode instanceof AnnotatedNode)) { throw new RuntimeException( "Internal error: wrong types: " + firstNode.getClass().getName() + " / " + secondNode.getClass().getName()); } AnnotationNode rolesAnnotationNode = (AnnotationNode) firstNode; AnnotatedNode annotatedNode = (AnnotatedNode) secondNode; AnnotationNode secured = createAnnotation(rolesAnnotationNode); if (secured != null ) { annotatedNode.addAnnotation(secured); } } catch (Exception e) { // TODO e.printStackTrace(); } } protected AnnotationNode createAnnotation(AnnotationNode rolesNode) throws IOException { Expression value = rolesNode.getMembers().get( "value" ); if (!(value ConstantExpression)) { (!(value instanceof ConstantExpression)) { // TODO System.out.println( "annotation @Authorities value isn't a ConstantExpression: " + value); return null ; } String fieldName = value.getText(); String[] authorityNames = getAuthorityNames(fieldName); if (authorityNames == null ) { return null ; } return buildAnnotationNode(authorityNames); } protected AnnotationNode buildAnnotationNode(String[] names) { AnnotationNode securedAnnotationNode = new AnnotationNode(SECURED); List<Expression> nameExpressions = new ArrayList<Expression>(); for (String authorityName : names) { nameExpressions.add( new ConstantExpression(authorityName)); } securedAnnotationNode.addMember( "value" , new ListExpression(nameExpressions)); return securedAnnotationNode; } protected String[] getAuthorityNames(String fieldName) throws IOException { Properties properties = new Properties(); File propertyFile = new File( "roles.properties" ); if (!propertyFile.exists()) { // TODO System.out.println( "Property file roles.properties not found" ); return null ; } properties.load( new FileReader(propertyFile)); Object value = properties.getProperty(fieldName); if (value == null ) { // TODO System.out.println( "No value for property '" + fieldName + "No value for property '" + fieldName + "'" ); return null ; } List<String> names = new ArrayList<String>(); String[] nameArray = StringUtils.commaDelimitedListToStringArray( value.toString()) for (String auth : nameArray) { auth = auth.trim(); if (auth.length() > 0 ) { names.add(auth); } } return names.toArray( new String[names.size()]); } }我可能會在某個時候將其包含在插件中-我已提醒您創建了JIRA問題 -但現在您可以將這兩個類復制到應用程序的src / java文件夾中,并在項目根目錄中創建一個roles.properties文件。 每當您要添加或刪除條目或從條目添加或刪除角色名稱時,請更新屬性文件,運行grails clean和grails compile以確保使用最新值。
參考:在An Solipsists博客上,由我們的JCG合作伙伴 Burt Beckwith 使您的Spring Security @Secured注釋更加干燥 。
翻譯自: https://www.javacodegeeks.com/2012/06/make-your-spring-security-secured.html
pdf secured
總結
以上是生活随笔為你收集整理的pdf secured_使您的Spring Security @Secured注释更干燥的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓复仇者行动免谷歌(安卓复仇者)
- 下一篇: 环评备案证明或环评报告(环评备案证)