shiro简单总结
代码框架
首先需要一个自定义类继承AuthorizingRealm达成shiro的realm对象
在这里我们可以去实现自定义的授权和认证
//自定义UserRealm类需要继承该类
public class UserRealm extends AuthorizingRealm {
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了授权方法");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
return info;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("执行了认证方法");
return null;
}
}
之后我们需要编写shiro控制类 来实现shiro的另外两个对象
@Configuration
public class ShiroConfig {
@Bean
//如果我们在某个注入点需要另一个 bean,我们需要专门指出它。我们可以通过 @Qualifier 注解来做到这一点。
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean();
//设置安全管理器
bean.setSecurityManager(defaultWebSecurityManager);
//添加过滤器
Map<String, String> filterMap = new LinkedMap();
return bean;
}
@Bean
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
//关联realm对象
securityManager.setRealm(userRealm);
return securityManager;
}
//创建realm对象 需要自定义类
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
}
shiro权限规则
/*
anon: 无需认证就可以访问
authc: 必须认证才能访问
user: 必需拥有记住我功能才能用
perms: 拥有对某个资源的权限才能访问
role: 拥有某个角色权限才能访问
*/
实现登录验证
我们使用authc规则
在过滤器添加上你要设置权限对应的路径
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean();
//设置安全管理器
bean.setSecurityManager(defaultWebSecurityManager);
//添加过滤器
Map<String, String> filterMap = new LinkedMap();
filterMap.put("/user/*","authc");
bean.setFilterChainDefinitionMap(filterMap);
//设置登录请求
bean.setLoginUrl("/toLogin");
return bean;
}
同时我们要在登录页面提交时去调用shiro提供的登录方法
@RequestMapping("/login")
public String login(String username,String password,Model model){
//获取当前用户
Subject subject= SecurityUtils.getSubject();
//封装当前用户数据
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
//执行登录方法
subject.login(token);
return "index";
}//用户名不存在异常
catch (UnknownAccountException e){
model.addAttribute("msg","用户名错误");
return "login";
}
catch (IncorrectCredentialsException e){
model.addAttribute("msg","密码错误");
return "login";
}
}
还要完善认证方法
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("执行了认证方法");
//连接真实数据库
UsernamePasswordToken usertoken=(UsernamePasswordToken) token;
HashMap<String,Object> map=new HashMap<>();
//在前面我们调用subject.login(token); 时吧token传进去了
//所以可以通过token对象获得密码和用户名
map.put("name",usertoken.getUsername());
List<User> users = userMapper.selectByMap(map);
if(users.size()==0){
return null;
}
//第一个参数将user对象传进去 使得后续授权可以获得user对象
//第二个参数要吧密码传进去 让shiro做密码验证
//第三个参数可以为空
return new SimpleAuthenticationInfo(users.get(0),users.get(0).getPassword(),"");
}
这样简单的登录功能就实现了(点击要权限的网页如果没有权限就会跳到登录页面 登录成功后即可访问权限页面)
实现自定义授权
首先要在数据库有对应的权限字段(这里我们只考虑只有一种权限的情况)

为页面授权 授权的字符串一定要同名!
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean();
//设置安全管理器
bean.setSecurityManager(defaultWebSecurityManager);
//添加过滤器
Map<String, String> filterMap = new LinkedMap();
//perms: 拥有对某个资源的权限才能访问
//设置一个自定义权限字符串 没有权限访问会跳到401页面
filterMap.put("/user/add","perms[user:add]");
filterMap.put("/user/update","perms[user:update]");
filterMap.put("/user/*","authc");
bean.setFilterChainDefinitionMap(filterMap);
//设置登录请求
bean.setLoginUrl("/toLogin");
//设置未授权页面
bean.setUnauthorizedUrl("/noauth");
return bean;
}
之后我们要完善授权方法
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了授权方法");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
Subject subject= SecurityUtils.getSubject();
//获得当前用户
User currentuser = (User) subject.getPrincipal();
//添加权限 名字对应自己设置的字符串
info.addStringPermission(currentuser.getPerms());
//info.addStringPermission("user:add");
return info;
}
即可实现授权

浙公网安备 33010602011771号