suppresswarnings sirven sirve que persistencia para notacion las ejemplo categorias anotaciones java spring spring-security

java - persistencia - para que sirven las anotaciones



Cómo crear métodos personalizados para usar en las anotaciones de lenguaje de expresiones de seguridad de primavera (3)

Gracias ericacm , pero no funciona por algunas razones:

  • Las propiedades de DefaultMethodSecurityExpressionHandler son privadas (los kludges de visibilidad de visibilidad son indeseables)
  • Al menos en mi Eclipse, no puedo resolver un objeto MethodSecurityEvaluationContext

Las diferencias son que llamamos al método createEvaluationContext existente y luego agregamos nuestro objeto raíz personalizado. Finalmente, acabo de devolver un tipo de objeto StandardEvaluationContext ya que MethodSecurityEvaluationContext no se resolvería en el compilador (ambos proceden de la misma interfaz). Este es el código que ahora tengo en producción.

Haga que MethodSecurityExpressionHandler use nuestra raíz personalizada:

public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler { // parent constructor public CustomMethodSecurityExpressionHandler() { super(); } /** * Custom override to use {@link CustomSecurityExpressionRoot} * * Uses a {@link MethodSecurityEvaluationContext} as the <tt>EvaluationContext</tt> implementation and * configures it with a {@link MethodSecurityExpressionRoot} instance as the expression root object. */ @Override public EvaluationContext createEvaluationContext(Authentication auth, MethodInvocation mi) { // due to private methods, call original method, then override it''s root with ours StandardEvaluationContext ctx = (StandardEvaluationContext) super.createEvaluationContext(auth, mi); ctx.setRootObject( new CustomSecurityExpressionRoot(auth) ); return ctx; } }

Esto reemplaza la raíz predeterminada al extender StandardEvaluationContext . Aquí he cambiado el nombre de hasRole a hasEntitlement:

public class CustomSecurityExpressionRoot extends SecurityExpressionRoot { // parent constructor public CustomSecurityExpressionRoot(Authentication a) { super(a); } /** * Pass through to hasRole preserving Entitlement method naming convention * @param expression * @return boolean */ public boolean hasEntitlement(String expression) { return hasRole(expression); } }

Finalmente, actualice securityContext.xml (y asegúrese de que esté referenciado desde su applcationContext.xml):

<!-- setup method level security using annotations --> <security:global-method-security jsr250-annotations="disabled" secured-annotations="disabled" pre-post-annotations="enabled"> <security:expression-handler ref="expressionHandler"/> </security:global-method-security> <!--<bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">--> <bean id="expressionHandler" class="com.yourSite.security.CustomMethodSecurityExpressionHandler" />

Nota: la anotación @Secured no aceptará esta anulación ya que se ejecuta a través de un manejador de validación diferente. Entonces, en el xml anterior, los desactivé para evitar una confusión posterior.

Me gustaría crear una clase que agregue métodos personalizados para su uso en el lenguaje de expresiones de seguridad de primavera para la autorización basada en métodos a través de anotaciones.

Por ejemplo, me gustaría crear un método personalizado como ''customMethodReturningBoolean'' para usarlo de esta manera:

@PreAuthorize("customMethodReturningBoolean()") public void myMethodToSecure() { // whatever }

Mi pregunta es esta Si es posible, ¿en qué clase debo crear una subclase para crear mis métodos personalizados, cómo voy a configurarlo en los archivos de configuración primavera xml y que alguien me dé un ejemplo de un método personalizado utilizado de esta manera?


Necesitarás subclasificar dos clases.

Primero, establezca un nuevo manejador de expresiones de método

<global-method-security> <expression-handler ref="myMethodSecurityExpressionHandler"/> </global-method-security>

myMethodSecurityExpressionHandler será una subclase de DefaultMethodSecurityExpressionHandler que anula createEvaluationContext() , estableciendo una subclase de MethodSecurityExpressionRoot en MethodSecurityEvaluationContext .

Por ejemplo:

@Override public EvaluationContext createEvaluationContext(Authentication auth, MethodInvocation mi) { MethodSecurityEvaluationContext ctx = new MethodSecurityEvaluationContext(auth, mi, parameterNameDiscoverer); MethodSecurityExpressionRoot root = new MyMethodSecurityExpressionRoot(auth); root.setTrustResolver(trustResolver); root.setPermissionEvaluator(permissionEvaluator); root.setRoleHierarchy(roleHierarchy); ctx.setRootObject(root); return ctx; }


Ninguna de las técnicas mencionadas funcionará más. Parece que Spring ha realizado grandes esfuerzos para evitar que los usuarios anulen el SecurityExpressionRoot.

EDITAR 11/19/14 Configurar Spring para usar anotaciones de seguridad:

<beans ... xmlns:sec="http://www.springframework.org/schema/security" ... > ... <sec:global-method-security pre-post-annotations="enabled" />

Crea un bean así:

@Component("mySecurityService") public class MySecurityService { public boolean hasPermission(String key) { return true; } }

Luego haz algo como esto en tu jsp:

<sec:authorize access="@mySecurityService.hasPermission(''special'')"> <input type="button" value="Special Button" /> </sec:authorize>

O anota un método:

@PreAuthorize("@mySecurityService.hasPermission(''special'')") public void doSpecialStuff() { ... }

Y recuerda: si estás usando Spring y tienes que resolver un problema ampliando clases, reemplazando métodos, implementando interfaces, etc. ... entonces probablemente estés haciendo algo mal. Son todas las anotaciones y xml, por eso nos encanta tanto Spring y no (versiones anteriores de) EJB.

Además, puede utilizar Spring Expression Language en sus anotaciones @PreAuthorize para acceder a la autenticación actual y a los argumentos del método.

Por ejemplo:

@Component("mySecurityService") public class MySecurityService { public boolean hasPermission(Authentication authentication, String foo) { ... } }

A continuación, actualice su @PreAuthorize para que coincida con la nueva firma de método:

@PreAuthorize("@mySecurityService.hasPermission(authentication, #foo)") public void doSpecialStuff(String foo) { ... }