Version: Next
Shiro实现请求授权
修改ShiroConfig配置类
- 修改Shiro配置类,在
ShiroFilterFactoryBean
中添加权限 - 例如:必须是user用户且拥有add权限,才能访问/user/add路由
filterChainDefinitionMap.put("/user/add","perms[user:add]");
具有user:update权限的用户才能访问/user/update路由
//具有user:update权限的用户才能访问/user/update路由
filterChainDefinitionMap.put("/user/update", "perms[user:update]");
@Configuration
public class ShiroConfig {
//注入自定义realm,方法名即Bean名
@Bean
public UserRealm userRealm() {
return new UserRealm();
}
//DefaultWebSecurityManager
@Bean
public DefaultSecurityManager defaultSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
DefaultWebSecurityManager defaultSecurityManager = new DefaultWebSecurityManager();
//关联Realm
defaultSecurityManager.setRealm(userRealm);
return defaultSecurityManager;
}
// 可以添加的过滤器:
// - anon:无需认真,直接可以访问
// - authc:必须认证才能访问
// - user:必须用户"记住我"功能才能用
// - perms:拥有对某个资源的权限,才能访问
// - role:拥有某个角色权限才可以访问
//shiroFilterFactoryBean
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultSecurityManager defaultSecurityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(defaultSecurityManager);
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
//让/user/add路由能被所有人访问
filterChainDefinitionMap.put("/user/add", "anon");
//授权 拥有user身份,add权限的人才能访问/user/add
filterChainDefinitionMap.put("/user/add","perms[user:add]");
//认证过后才允许访问/user/update
filterChainDefinitionMap.put("/user/update", "authc");
//具有user:update权限的用户才能访问/user/update路由
filterChainDefinitionMap.put("/user/update", "perms[user:update]");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
//设置登录路由
shiroFilterFactoryBean.setLoginUrl("/user/toLogin");
return shiroFilterFactoryBean;
}
}
新建未授权路由
@RequestMapping("/unauthorized")
@ResponseBody
public String unauthorized(){
return "未经授权,无法访问此页面";
}
- 在ShiroConfig的
ShiroFilterFactoryBean
中,设置未授权页面
//设置未授权页面
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
// 可以添加的过滤器:
// - anon:无需认真,直接可以访问
// - authc:必须认证才能访问
// - user:必须用户"记住我"功能才能用
// - perms:拥有对某个资源的权限,才能访问
// - role:拥有某个角色权限才可以访问
//shiroFilterFactoryBean
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultSecurityManager defaultSecurityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(defaultSecurityManager);
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
//让/user/add路由能被所有人访问
filterChainDefinitionMap.put("/user/add", "anon");
//授权 拥有user身份,add权限的人才能访问/user/add
filterChainDefinitionMap.put("/user/add","perms[user:add]");
//认证过后才允许访问/user/update
filterChainDefinitionMap.put("/user/update", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
//设置登录路由
shiroFilterFactoryBean.setLoginUrl("/user/toLogin");
//设置未授权页面
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
return shiroFilterFactoryBean;
}
授予用户权限
添加数据库权限信息
- 在数据库层面添加权限信息
ALTER TABLE USER ADD perms VARCHAR(100)
- pojo添加
perms
属性
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private String password;
private String perms;
}
授予用户权限
在自定义
UserRealm
的AuthorizationInfo
方法中,创建SimpleAuthorizationInfo
对象获取当前用户
在
AuthenticationInfo
方法返回SimpleAuthenticationInfo
对象时,设置第一个参数principal
,将从数据库查询到的用户发出去return new SimpleAuthenticationInfo(user, user.getPassword(), "");在
AuthorizationInfo
方法中- 使用
SecurityUtils.getSubject();
就可以获得当前用户 subject.getPrincipal();
,就可以获取上面返回时设置的第一个参数principal
,即currentUser
// 获取当前用户Subject subject = SecurityUtils.getSubject();User currentUser = (User) subject.getPrincipal();- 使用
查询数据库,将数据库中的权限信息添加到当前用户上
authorizationInfo.addStringPermission(currentUser.getPerms());
public class UserRealm extends AuthorizingRealm {
@Autowired
UserServiceImpl userServiceImpl;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了<<授权>>方法");
// 获取当前用户
Subject subject = SecurityUtils.getSubject();
User currentUser = (User) subject.getPrincipal();
//给当前用户授予权限
//从数据库读用户权限,设置上去
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.addStringPermission(currentUser.getPerms());
return authorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("执行了<<认证>>方法");
//查询数据库获得用户数据
//伪造用户名密码
// String username = "root";
// String password = "123456";
//通过Mybatis查询数据库
// if (!token.getUsername().equals(username)) {
// return null; //Shiro自动抛出 UnknownAccountException
// }
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
User user = userServiceImpl.queryUserByName(token.getUsername());
if (user == null) {
return null; //Shiro自动抛出 UnknownAccountException
}
//密码认证,shiro会自动做
return new SimpleAuthenticationInfo(user, user.getPassword(), "");
}
}