一.依赖导入
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.1</version>
</dependency>
<!-- 若前端引擎为thymeleaf,则需要更改为3.x并导入依赖 -->
<thymeleaf-spring5.version>3.0.9.RELEASE</thymeleaf-spring5.version>
<thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version>
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
二.基本使用步骤
1.创建UserRealm
类
public class UserRealm extends AuthorizingRealm {
//授权,当访问需要权限的页面时将调用此函数
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("授权");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
Subject subject = SecurityUtils.getSubject();
User currentUser = (User) subject.getPrincipal();//拿到user对象
//设置当前用户权限
info.addStringPermission(currentUser.getPermission());
return info;
}
//认证,当调用Subject.login函数时将调用此函数
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("认证");
//点击登录则会执行此方法
//用户名,密码,数据库中取得
String name = "root";
String password = "123456";
String permission = "user:add";
User user = new User(name,password,permission);//假设为从数据库内取出的数据信息
UsernamePasswordToken userToken = (UsernamePasswordToken) token;//将token转换为子类UsernamePasswordToken
if(!userToken.getUsername().equals(name)){
return null;//抛出异常,即用户名不存在等
}
//密码可以加密
//密码认证,shiro做
return new SimpleAuthenticationInfo(user,password,"");//自动比对密码,防止密码泄露,传入user作为参数可以在授权函数内取出
}
}
2.创建ShiroConfig
类
@Configuration
public class ShiroConfig {
//ShiroFilterFactoryBean
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
//设置安全管理器
bean.setSecurityManager(defaultWebSecurityManager);
//添加shiro内置过滤器
/*
anon:无需认证
authc:必须认证才能访问
user:必须拥有记住我功能才能用
perms:拥有对某个资源的权限才能访问
role:拥有某个角色权限才能访问
*/
Map<String,String> filterMap = new LinkedHashMap<>();
/*filterMap.put("/add","authc");
filterMap.put("/update","authc");*/
//filterMap.put("/*","anon");//使用通配符
filterMap.put("/add","perms[user:add]");//只有拥有user:add权限才能访问
bean.setFilterChainDefinitionMap(filterMap);
//设置登录界面,则权限不满足自动跳转至login页面
bean.setLoginUrl("/login");
//未授权页面
bean.setUnauthorizedUrl("/noauth");//未经授权自动跳转的页面
return bean;
}
//DefaultWebSecurityManager
@Bean
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();
}
//整合ShiroDialect:用于整合shiro thymeleaf
@Bean
public ShiroDialect getShiroDialect(){
return new ShiroDialect();
}
}
3.实现认证登录
@RequestMapping("/solve")
public String login(String username,String password,Model model){
//获取当前用户
Subject subject = SecurityUtils.getSubject();
//封装用户登录数据
UsernamePasswordToken token = new UsernamePasswordToken(username,password);//将用户账号信息封装为token
try{
subject.login(token);//执行登录方法,若无异常则登录完成
return "index";
}catch (UnknownAccountException e){
//用户名不存在
model.addAttribute("msg","用户名不存在");
return "login";
}catch (IncorrectCredentialsException e){
model.addAttribute("msg","密码错误");
return "login";
}
}
4.基于thymeleaf的前端响应
(1)引入名字空间
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
(2)示例代码
<div shiro:hasPermission="user:add">
<a href="/add">add</a>
</div>
则add标签仅当用户拥有 user:add权限时才可见
Comment