1、进行权限拦截和进行授权
在shiroConfig中配置内置过滤,进行设置安全管理器,然后进行配置shiro的内置过滤器,filterMap.put("/user/update","perms[user:update]");
,且进行拦截时,跳转到未授权页面:bean.setUnauthorizedUrl("/unauth");
,代码如下所示:
package com.ygl.config;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author ygl
* @description
* @date 2020/11/6 10:37
*/
@Configuration
public class ShiroConfig {
//ShiroFilterFactoryBean 过滤 (第三步:连接到前端)
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
//设置安全管理器
bean.setSecurityManager(defaultWebSecurityManager);
//配置shiro的内置过滤器
/*
anon:匿名拦截器,不需要登录即可访问的资源,匿名用户或游客,一般用于过滤静态资源。
authc:需要认证登录才能访问
user:用户拦截器,表示必须存在用户
perms:权限授权拦截器,验证用户是否拥有权限
参数可写多个,表示需要某些权限才能通过,多个参数时写 perms[“user, admin”],当有多个参数时必须每个参数都通过才算可以
roles:角色授权拦截器,验证用户是或否拥有角色。
参数可写多个,表示某些角色才能通过,多个参数时写 roles[“admin,user”],当有多个参数时必须每个参数都通过才算通过
*/
//拦截
Map<String, String> filterMap = new LinkedHashMap();
//授权,正常情况下,没有授权的会跳到未授权页面 添加某个权限才可以
// filterMap.put("/user/add","perms[user:add]");
// filterMap.put("/user/update","perms[user:update]");
//授权 添加某个角色才可以
filterMap.put("/user/add","roles[admin]");
//拦截
filterMap.put("/toLogin","anon");
// filterMap.put("/user/add","authc");
// filterMap.put("/user/update","authc");
filterMap.put("/user/*","authc");
bean.setFilterChainDefinitionMap(filterMap);
//被拦截时 设置登录的请求
bean.setLoginUrl("/toLogin");
//跳转到未授权页面
bean.setUnauthorizedUrl("/unauth");
return bean;
}
//DafaultWebSecurityManager 安全对象 (第二步:接管对象)
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联userRealm
securityManager.setRealm(userRealm);
return securityManager;
}
//创建Realm对象 需要自定义 (第一步:创建对象)
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
}
主要修改代码在这里,perms 代表赋予权限
然后在Realm中的授权中设置拥有这些权限的可以进行授权,代码分析如下:
package com.ygl.config;
import com.ygl.pojo.User;
import com.ygl.service.UserSevice;
import com.ygl.utils.PasswordUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @author ygl
* @description
* @date 2020/11/6 10:41
*/
//自定义的 UserRealm
public class UserRealm extends AuthorizingRealm {
@Autowired
private UserSevice userSevice;
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了授权功能=》doGetAuthorizationInfo!");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//进行授权
// info.addStringPermission("user:add");
//获取当前对象
Subject subject = SecurityUtils.getSubject();
//从认证中拿到当前登录的user对象
User currentUser = (User) subject.getPrincipal();
//设置当前用户的权限
info.addStringPermission(currentUser.getPerms());
//设置角色
// info.addRole(currentUser.getRole());
return info;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("执行了认证功能=》doGetAuthorizationInfo!");
UsernamePasswordToken userToken = (UsernamePasswordToken)token;
//连接真实数据库
User user = userSevice.queryByName(userToken.getUsername());
//pwd代表是用户输入的密码数据
String pwd ="";
for (int i = 0; i < userToken.getPassword().length; i++) {
pwd =pwd +userToken.getPassword()[i];
}
if (user == null){
return null;
}
/*
System.out.println("密码:"+user.getPwd());
*/
// 获取盐值
String salt = user.getSalt();
String password = PasswordUtils.getMd5(pwd, user.getName(), salt);
char[] chars = password.toCharArray();
userToken.setPassword(chars);
System.out.println("password:"+password);
//密码认证 shiro来进行操作,防止获取到密码
return new SimpleAuthenticationInfo(user,user.getPwd(),user.getName());
}
}
主要更改内容如下图所示:
注意: 在realm中,如果需要从认证中查询到的用户信息传到授权中时,需要在认证代码中的密码验证中进行将用户信息传值过来,如下图所示:
2、进行角色授权
角色的授权拦截和权限的授权拦截基本上一致,只是在filterMap.put("/user/update","perms[user:update]");
代码中的perms更改成roles,也就是更改成filterMap.put("/user/add","roles[admin]");
,如下图所示:
在shiroConfig类中更改为进行角色授权,也就是由info.addStringPermission(currentUser.getPerms());
更改为info.addRole(currentUser.getRole());
,代码修改如下图所示:
注意:
角色和权限这两个是从数据库中查询到的,在实体类中大家记得添加属性。