关于注解@RequiresPermissions和@RequiresRoles注解中的value含有多个时不起作用的问题
1、先来看一下这两个注解的源码
(1)
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.shiro.authz.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* Requires the current executor's Subject to imply a particular permission in
* order to execute the annotated method. If the executor's associated
* {@link org.apache.shiro.subject.Subject Subject} determines that the
* executor does not imply the specified permission, the method will not be executed.
* </p>
*
* <p>For example, this declaration:
* <p/>
* <code>@RequiresPermissions( {"file:read", "write:aFile.txt"} )<br/>
* void someMethod();</code>
* <p/>
* indicates the current user must be able to both <tt>read</tt> and <tt>write</tt>
* to the file <tt>aFile.txt</tt> in order for the <tt>someMethod()</tt> to execute, otherwise
* an {@link org.apache.shiro.authz.AuthorizationException AuthorizationException} will be thrown.
*
* @see org.apache.shiro.subject.Subject#checkPermission
* @since 0.1
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresPermissions {
/**
* The permission string which will be passed to {@link org.apache.shiro.subject.Subject#isPermitted(String)}
* to determine if the user is allowed to invoke the code protected by this annotation.
*/
String[] value();
/**
* The logical operation for the permission checks in case multiple roles are specified. AND is the default
* @since 1.1.0
*/
Logical logical() default Logical.AND;
}
package org.apache.shiro.authz.annotation;
/**
* An enum for specifying a logical operation that can be used for
* interpreting authorization annotations
*
* @since 1.1.0
*/
public enum Logical {
AND, OR
}
可以看到,源码中,RequiresPermissions 是有两个属性的。
第一个String[] value呢,就是存放访问所需要的权限的,可以这样写【最好是放在Controller层的类或方法上】
@RequiresPermissions("user:add")
//或者
@RequiresPermissions({"user:add","user:delete"})
//但是这种会发现,假如这时的用户只有"user:add"或者"user:delete"的时候,访问不了,
//Logical logical() default Logical.AND;
//从源码中可以看到默认是AND,也就是说默认需要这个用户同时拥有这两个权限才能访问
//如果说用户只含有其中一个权限时,则需要如下写法
@RequiresRoles(value = {"user:add","user:delete"}, logical = Logical.OR)
//将其默认的AND改为OR就行了
2、@RequiresRoles和@RequiresPermissions是同一个道理,就不多说了
package org.apache.shiro.authz.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Requires the currently executing {@link org.apache.shiro.subject.Subject Subject} to have all of the
* specified roles. If they do not have the role(s), the method will not be executed and
* an {@link org.apache.shiro.authz.AuthorizationException AuthorizationException} is thrown.
* <p/>
* For example,
* <p/>
* <code>@RequiresRoles("aRoleName");<br/>
* void someMethod();</code>
* <p/>
* means <tt>someMethod()</tt> could only be executed by subjects who have been assigned the
* 'aRoleName' role.
*
* <p><b>*Usage Note*:</b> Be careful using this annotation if your application has a <em>dynamic</em>
* security model where roles can be added and deleted at runtime. If your application allowed the
* annotated role to be deleted during runtime, the method would not be able to
* be executed by anyone (at least until a new role with the same name was created again).
*
* <p>If you require such dynamic functionality, only the
* {@link RequiresPermissions RequiresPermissions} annotation makes sense - Permission
* types will not change during runtime for an application since permissions directly correspond to how
* the application's functionality is programmed (that is, they reflect the application's functionality only, not
* <em>who</em> is executing the the functionality).
*
* @see org.apache.shiro.subject.Subject#hasRole(String)
* @since 0.1
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresRoles {
/**
* A single String role name or multiple comma-delimited role names required in order for the method
* invocation to be allowed.
*/
String[] value();
/**
* The logical operation for the permission check in case multiple roles are specified. AND is the default
* @since 1.1.0
*/
Logical logical() default Logical.AND;
}
package org.apache.shiro.authz.annotation;
/**
* An enum for specifying a logical operation that can be used for
* interpreting authorization annotations
*
* @since 1.1.0
*/
public enum Logical {
AND, OR
}