简体   繁体   English

是否可以使用注释实现方法级访问检查?

[英]Is it possible to implement method-level access checks with annotations?

Consider some basic authorization framework with User s and Group s where access to methods should be guarded by checks which make sure that the user or the group have the necessary PriviledgeLevel to execute the method and fails otherwise.考虑一些具有UserGroup的基本授权框架,其中对方法的访问应通过检查来保护,以确保用户或组具有执行该方法所需的PriviledgeLevel ,否则会失败。

What I imagine is something like this:我想象的是这样的:

@AccessCheck(PriviledgeLevel.ADMINISTRATOR)
public static void secureMethod(){ ... }

Where the code checking basically does代码检查基本上在哪里

if(currentUser.getPriviledgeLevel >= PriviledgeLevel.ADMINISTRATOR ||
   currentUser.getGroup.priviledgeLevel >= PriviledgeLevel.ADMINISTRATOR)
  // Allow access
else
  // Deny access       

Would it be possible to implement it this way?有可能以这种方式实现吗?

I did a bit of research which points to some existing things based on AspectJ , mostly on the Security Annotation Framework (SAF) and on Spring Security .我做了一些研究,指出了一些基于AspectJ的现有事物,主要是关于Security Annotation Framework (SAF) 和Spring Security

I'm a bit concerned because SAF doesn't seem very active anymore and the documentation isn't that great.我有点担心,因为 SAF 似乎不再很活跃,而且文档也不是那么好。

I'm not sure about Spring Security but it seems to be more focused on security problems in web-related topics.我不确定 Spring 安全性,但它似乎更关注网络相关主题中的安全问题。

The Java Authentication and Authorization Service seems to be related, but doesn't use the annotation approach. Java Authentication and Authorization Service似乎是相关的,但没有使用注释方法。

Does it make sense trying to define these security requirements with this declarative approach?尝试使用这种声明性方法定义这些安全要求是否有意义?

Is there another library/framework I'm missing, which already implements what I want or some techonology which would be relevant here?我是否还缺少另一个库/框架,它已经实现了我想要的或者一些在这里相关的技术?

Or is there a completely different solution (like implementing my own ClassLoader , ...) which is superior to what I imagine (in terms of conciseness and readability for the library user)?还是有一个完全不同的解决方案(比如实现我自己的ClassLoader ,...),它优于我的想象(就库用户的简洁性和可读性而言)?

You could do this fairly trivially yourself by using dynamic proxies.您可以通过使用动态代理自己相当简单地做到这一点。

public interface MyInterface {
           @AccessCheck(Privilege.ADMIN)
           public void doSomething();
}

The proxy would be created on the class that implements your interface and you would annotate your interface with your custom annotation.代理将在实现您的接口的 class 上创建,您将使用自定义注释来注释您的接口。

 MyInterface aInterface = (MyInterface) java.lang.reflect.Proxy.newProxyInstance(obj.getClass()
                .getClassLoader(), obj.getClass().getInterfaces(),
                new YourProxy(new Implementation());

In the invoke() method of your proxy, you can check if your method has the annotation and throw a SecurityException if the privileges are not met.在您的代理的 invoke() 方法中,您可以检查您的方法是否具有注释,如果不满足权限则抛出 SecurityException。

public YourProxy implements InvocationHandler {
         ....
         public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable {

              if ( method.isAnnotationPresent(AccessCheck.class) {
                    ....// do access check here and throw SecurityException()
         }
 }

I think AspectJ will do what you want it to do.我认为 AspectJ 会做你想做的事。 We have a whole bunch of methods which you need certain access rights for and we've created an AspectJ aspect which will check that and error out if the user does not have those permissions.我们有一大堆方法,您需要某些访问权限,我们创建了一个 AspectJ 方面,如果用户没有这些权限,它将检查并出错。

As a plus, because AspectJ is "woven" into the classes at compile time it cannot be disabled by configuration.另外,因为 AspectJ 在编译时被“编织”到类中,所以不能通过配置禁用它。

We also use Spring Security, it is possible to use both in harmony!我们还使用 Spring 安全性,可以两者和谐使用!

With Spring Security , you just have to add:使用Spring Security ,您只需添加:

@Secured("ADMINISTRATOR")
public static void secureMethod(){ ... }

And configure it properly, by:并通过以下方式正确配置它:

  1. use JdbcDaoImpl as your UserDetailsService使用JdbcDaoImpl作为您的UserDetailsService
  2. enable group support 启用组支持
  3. customize the queries (if you are using database credential storage)自定义查询(如果您使用数据库凭证存储)

If you are not using database credential storage, just configure your preferred UserDetailsService to add both user and group credentials to the authorities of the generated UserDetails .如果您不使用数据库凭据存储,只需配置您的首选UserDetailsService以将用户和组凭据添加到生成的UserDetails的权限。

Of couse, it is hard to understand it without checking the concepts at the documentation , but method level access checks is perfectly possible with spring security and it's my prefered technology for it.当然,如果不检查文档中的概念就很难理解它,但是使用 spring 安全性完全可以进行方法级别的访问检查,这是我最喜欢的技术。

In Spring Security, as the docs state, both @Secured and @PreAuthorize can be used at method level.在 Spring Security 中,作为文档state, @Secured@PreAuthorize都可以在方法级别使用。

To enable @PreAuthorize (if you haven't already...), you need to put <global-method-security pre-post-annotations="enabled" /> in your configuration XML;要启用@PreAuthorize (如果您还没有...),您需要将<global-method-security pre-post-annotations="enabled" />放入您的配置 XML;

For @Secured use <global-method-security secured-annotations="enabled" /> .对于@Secured使用<global-method-security secured-annotations="enabled" />

For more details, refer to this article .有关更多详细信息,请参阅这篇文章

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM