shiro中给某个接口添加权限的两种方法,若没有权限则返回特定值

shiro中给某个接口添加权限的两种方法,若没有权限则返回特定值

1、在ShiroConfig中的ShiroFilterFactoryBean这个bean中添加过滤器,在过滤器中对接口添加访问权限

1> 添加访问权限

Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/user/add", "perms[user:add]");   //授权
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);

/user/add接口需要有user:add权限才可访问

2> 对用户授权

realmdoGetAuthorizationInfo方法中授予用户user:add权限

SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addStringPermission("user:add");   //授予用户权限

3> 未授权时返回error

用户访问/user/add接口时,若没有授予该权限,则返回为
在这里插入图片描述通过写一个拦截器,发现访问请求会被转移到/error请求,这是shiro内置的一个错误请求接口

地址栏没变,但是返回值显示这是一个/error请求,由于Unauthorized引发的错误,并且通过写一个拦截器,发现这个请求的确被定向到/error

4> 设置未授权时返回值接口

没有权限时,我们想要将返回值改为自己定义的返回值,所以在ShiroFilterFactoryBean这个bean中设置未授权时返回值接口

// 设置未授权返回值接口
shiroFilterFactoryBean.setUnauthorizedUrl("/noauth");

/noauth接口

@RequestMapping("/noauth")
@ResponseBody
public String unauthorized(){
    return "未经授权, 无法访问此接口";
}

若没有权限,返回值为
在这里插入图片描述
直接被重定向到/noauth

2、通过注解@RequiresPermissions对接口添加访问权限

1> 添加访问权限

@RequiresPermissions(value = {"user:add"})
@RequestMapping({"/user/add"})
public String add(){
    return "user/add";
}

像1中一样给用户授予user:add权限之后即可正常访问

2> 未授权时抛出异常

但是未给用户授予此权限时
在这里插入图片描述
请求同样转移到了/error接口,但是返回值并不是Unauthorized,而是服务器内部错误,并且后台报异常如下,这个异常表示的又是Not authorized,说明我们在ShiroFilterFactoryBean这个bean中设置未授权时返回值接口并没有起作用
在这里插入图片描述
这是由于shiro注解模式下,登录失败或者是没有权限都是抛出异常,并且默认的没有对异常做处理,所以我们可以对这个异常进行统一捕获处理,让这个异常返回特定值

3> 统一异常捕获处理

添加NoPermissionException.java

import org.apache.shiro.authz.AuthorizationException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

@ControllerAdvice
public class NoPermissionException {

    @ResponseBody
    @ExceptionHandler(AuthorizationException.class)
    public String AuthorizationException(Exception ex) {
        return "权限认证失败";
    }
}

我们没有权限时再去访问/user/add接口时,返回值就是权限认证失败
在这里插入图片描述
并且由于我们统一全局捕获了这个异常并处理,所以后台也不会抛出异常。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,针对您的问题,您可以使用Shiro提供的权限注解 `@RequiresPermissions`,并通过自定义注解来实现权限控制。 以下是一个示例代码,其实现了一个自定义注解 `@ApiPermission`,并在 `ShiroFilterFactoryBean` 添加了该注解,用于控制开放接口的访问权限: ```java @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface ApiPermission { String[] value() default {}; } public class ApiPermissionFilter extends AuthorizationFilter { @Override protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception { Subject subject = getSubject(request, response); String[] permissions = (String[]) mappedValue; if (permissions == null || permissions.length == 0) { return true; } for (String permission : permissions) { if (subject.isPermitted(permission)) { return true; } } return false; } } @Configuration public class ShiroConfig { @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) { ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean(); factoryBean.setSecurityManager(securityManager); Map<String, Filter> filterMap = new LinkedHashMap<>(); filterMap.put("apiPermission", new ApiPermissionFilter()); factoryBean.setFilters(filterMap); Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>(); filterChainDefinitionMap.put("/login", "anon"); filterChainDefinitionMap.put("/logout", "logout"); filterChainDefinitionMap.put("/api/**", "apiPermission[api:read]"); filterChainDefinitionMap.put("/**", "authc"); factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return factoryBean; } } @RestController public class ApiController { @GetMapping("/api/test") @ApiPermission("api:read") public String test() { return "Hello, World!"; } } ``` 在上述代码,我们定义了一个 `ApiPermissionFilter`,用于判断用户是否具有访问开放接口权限。然后,在 `ShiroFilterFactoryBean` 添加了该过滤器,并在 `filterChainDefinitionMap` 使用 `apiPermission[api:read]` 来控制 `/api/**` 下的所有请求的访问权限。 最后,在 `ApiController` 使用 `@ApiPermission("api:read")` 注解来标识需要具有 `api:read` 权限才能访问的接口

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值