shiro安全框架主要核心功能为认证和授权,认证即验证用户信息,是否能登陆,授权即用户是否有权限取执行该请求,方法等。
1、shiro本质是一条过滤器链:
anno :无需任何认证即可访问;
authc :必须认证后才可以访问;
perms:必须具有指定用户权限才可以访问,如perms[user],说明必须有user权限才能访问
user : 必须有记住我才能访问;
role :必须具有某个角色才能访问。
2、springBoot整合shiro
(1)创建对自定义认证和授权类,继承AuthorizingRealm类
重写认证方法AuthenticationInfo():
①获取登陆用户信息
②通过数据库查找对应用户信息
③用户名认证,若认证失败,返回null
④由shiro框架提供的SimpleAuthenticationInfo("","","")方法进行密码认证,第一个参数为获取用户对象,调用SecurityUtils.getSubject()方法便可以获取用户信息,第二个参数为用户密码,第三个参数为用户角色。
例:
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//取到登陆用户信息
UsernamePasswordToken user=(UsernamePasswordToken) authenticationToken;
//数据库查取
User user1 = userService.queryUserByName(user.getUsername());
//用户名认证
if (user1==null){
return null;//登陆失败
}
//密码认证
return new SimpleAuthenticationInfo(user1,user1.getPwd(),"");
}
重写授权方法:
①创建SimpleAuthorizationInfo对象,用于设置用户权限
② 从数据库获取对应用户的权限信息
③设置用户权限
例:
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//拿到当前用户登陆对象
Subject subject = SecurityUtils.getSubject();
User currentUser = (User) subject.getPrincipal();
//设置当前用户权限
info.addStringPermission(currentUser.getPerms());
return info;
}
(2)配置shrio配置类
①实例自定义Realm类
例:
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
②创建DefaultWebSecurityManager类,用于配置自定义Realm类,@Qualifier注解根据方法名注入对象
例:
@Bean
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
//关联
defaultWebSecurityManager.setRealm(userRealm);
return defaultWebSecurityManager;
}
③注入ShiroFilterFactoryBean方法
创建map集合用于存储认证以及授权的过滤器
设置认证方式以及对应拦截路径
设置授权权限和拦截路径
调用setLoginUrl()方法设置登陆路径
调用setUnauthorizedUrl()方法设置授权失败自定义界面路径
例:/add请求需要用户有user:add权限才可以访问
filterMap.put("/add","perms[user:add]");
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//设置安全管理器
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
//拦截
Map<String,String> filterMap=new LinkedHashMap<>();
//需要认证才能访问;
filterMap.put("/update","authc");
filterMap.put("/add","authc");
//授权,只有用户user:add才能访问
filterMap.put("/add","perms[user:add]");
filterMap.put("/update","perms[user:update]");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
//设置登陆跳转界面
shiroFilterFactoryBean.setLoginUrl("/login");
//设置未授权跳转页面
shiroFilterFactoryBean.setUnauthorizedUrl("/errors");
return shiroFilterFactoryBean;
}
(3)认证controller类
①调用SecurityUtils.getSubject()获取用户数据信息
②调用UsernamePasswordToken()封装用户登陆信息,对用户信息实现加密处理
③执行登陆方法,UnknownAccountException异常为用户名不存在时抛出,IncorrectCredentialsException异常为密码错误时抛出
例:
@RequestMapping("/logins")
public String login(String username,String password,Model model){
//获取当前用户
Subject subject = SecurityUtils.getSubject();
//封装用户登录数据
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password);
//执行登陆方法
try {
subject.login(usernamePasswordToken);
return "index";
} catch (UnknownAccountException e) {
model.addAttribute("msg","用户名不存在");
return "login";
}catch (IncorrectCredentialsException e){
model.addAttribute("msg","密码错误");
return "login";
}
}