前后端分离项目中 springboot 集成 shiro 实现权限控制
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前后端分离项目中 springboot 集成 shiro 实现权限控制相关的知识,希望对你有一定的参考价值。
文章目录
- 使用注解控制鉴权授权
- 使用 url配置控制鉴权授权
- 表结构
- jar 包依赖
- 代码说明
- 身份认证
- 权限认证
- 跨域问题解决
- 登录验证不进行重定向改为设置http状态
- 项目源码
- Reference
使用注解控制鉴权授权
注解 | 功能 |
@RequiresGuest | 只有游客可以访问 |
@RequiresAuthentication | 需要登录才能访问 |
@RequiresUser | 已登录的用户或“记住我”的用户能访问 |
@RequiresRoles | 已登录的用户需具有指定的角色才能访问 |
@RequiresPermissions | 已登录的用户需具有指定的权限才能访问 |
使用 url配置控制鉴权授权
配置缩写 | 对应的过滤器 | 功能 |
anon | AnonymousFilter | 指定url可以匿名访问 |
authc | FormAuthenticationFilter | 指定url需要form表单登录,默认会从请求中获取 |
authcBasic | BasicHttpAuthenticationFilter | 指定url需要basic登录 |
logout | LogoutFilter | 登出过滤器,配置指定url就可以实现退出功能,非常方便 |
noSessionCreation | NoSessionCreationFilter | 禁止创建会话 |
perms | PermissionsAuthorizationFilter | 需要指定权限才能访问 |
port | PortFilter | 需要指定端口才能访问 |
rest | HttpMethodPermissionFilter | 将http请求方法转化成相应的动词来构造一个权限字符串,这个感觉意义不大,有兴趣自己看源码的注释 |
roles | RolesAuthorizationFilter | 需要指定角色才能访问 |
ssl | SslFilter | 需要https请求才能访问 |
user | UserFilter | 需要已登录或“记住我”的用户才能访问 |
表结构
表 | 注释 |
sys_user | 用户表 |
sys_role | 角色表 |
sys_user_role | 用户角色关联表 |
sys_role_permission | 角色权限关联表 |
sys_permission | 权限表 |
jar 包依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
代码说明
身份认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
// 根据用户名获取用户密码
User user = userService.findUserByLoginName(token.getUsername());
if (user == null)
throw new AuthenticationException(String.valueOf(ResponseEnum.ERROR_INCORRECT_UNAME_OR_PWD.code()));
ByteSource salt = ByteSource.Util.bytes(user.getSalt());
String password = user.getPassword();
String saltPassword = ShiroUtil.saltEncrypt(token.getPassword(), user.getSalt());
if (null == password)
throw new AuthenticationException(String.valueOf(ResponseEnum.INVALID_USER.code()));
else if (!password.equals(saltPassword))
throw new AuthenticationException(String.valueOf(ResponseEnum.PASSWORD_ERROR.code()));
return new SimpleAuthenticationInfo(token.getPrincipal(), token.getPassword(), salt, getName());
在执行
subject.login(token)
时 会调用 doGetAuthenticationInfo
方法代码
权限认证
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection)
String username = (String) principalCollection.getPrimaryPrincipal();
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
// 根据 用户名称 获取用户的 角色信息
Set<String> roles = userService.findUserRolesByLoginName(username);
// 设置该用户拥有的角色 @RequiresRoles
if (roles.size() > 0)
simpleAuthorizationInfo.setRoles(roles);
// 设置用户的权限列表 @RequiresPermissions
Set<String> userPermissions = userService.findUserPermissionsByLoginName(username);
if (userPermissions.size() > 0)
simpleAuthorizationInfo.setStringPermissions(userPermissions);
return simpleAuthorizationInfo;
在接口标明注解
@RequiresPermissions
或 @RequiresRoles
时会调用 doGetAuthorizationInfo
方法
// `/admin/**` 下的接口需要管理员权限, 等同于在对应接口上加 @RequiresRoles(value = "admin", "user", logical = Logical.OR)
filterChainDefinitionMap.put("/admin/**", "roles[admin,user]");
// `/user/**` 下的接口需要的权限, 等同于在对应接口上加 @RequiresPermissions("order:query")
filterChainDefinitionMap.put("/user/**", "perms[user:query]");
或者
ShiroConfig
中 ShiroFilterFactoryBean
对象中配置了以上权限代码时也会调用 doGetAuthorizationInfo
方法
跨域问题解决
@Configuration
public class CorsConfig
@Bean
public FilterRegistrationBean corsFilter()
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowCredentials(true);
// 指定运行地址
corsConfiguration.setAllowedOrigins(Lists.newArrayList("http://192.168.10.1:8080"));
// 允许任何域名
// corsConfiguration.addAllowedOrigin(CorsConfiguration.ALL);
// 允许任何头部信息
corsConfiguration.addAllowedHeader(CorsConfiguration.ALL);
// 允许所有请求类型
corsConfiguration.addAllowedMethod(CorsConfiguration.ALL);
corsConfiguration.addExposedHeader("Authorization");
source.registerCorsConfiguration("/**", corsConfiguration);
FilterRegistrationBean bean = new FilterRegistrationBean<>(new CorsFilter(source));
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
登录验证不进行重定向改为设置http状态
public class AiAuthenticationFilter extends FormAuthenticationFilter
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response)
throws Exception
WebUtils.toHttp(response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
return false;
// 修改 ShiroConfig 的 shiroFilter 方法
@Configuration
public class ShiroConfig
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager)
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
Map<String, Filter> filterMap = shiroFilterFactoryBean.getFilters();
filterMap.put("authc", new AiAuthenticationFilter());
shiroFilterFactoryBean.setFilters(filterMap);
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setLoginUrl("/unauth");
// 设置重定向接口地址
// shiroFilterFactoryBean.setLoginUrl("/api/user/v1/notLogin");
shiroFilterFactoryBean.setUnauthorizedUrl("/api/user/v1/notPerms");
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/api/external/**", "anon");
filterChainDefinitionMap.put("/api/user/v1/login", "anon");
filterChainDefinitionMap.put("/api/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
项目源码
项目源码 Github 地址
: springboot-shiro
Reference
- Shiro用starter方式优雅整合到SpringBoot中
- 教你 Shiro 整合 SpringBoot,避开各种坑
以上是关于前后端分离项目中 springboot 集成 shiro 实现权限控制的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot+Vue+AntDesign前后端分离项目脚手架
CentOS7/8系统下,使用Jenkins实现SpringBoot+Vue前后端分离项目持续集成,一键编译打包跨设备部署,完整详细教学演示
CentOS7/8系统下,使用Jenkins实现SpringBoot+Vue前后端分离项目持续集成,一键编译打包跨设备部署,完整详细教学演示
CentOS7/8系统下,使用Jenkins实现SpringBoot+Vue前后端分离项目持续集成,一键编译打包跨设备部署,完整详细教学演示
CentOS7/8系统下,使用Jenkins实现SpringBoot+Vue前后端分离项目持续集成,一键编译打包跨设备部署,完整详细教学演示