shiro
一、概述
1.shiro简介
- Apache Shiro是一个Java安全权限框架
- Shiro不仅可以用在JavaSE环境,也可以用在JavaEE环境
- Shiro可以完成,认证,授权,加密,会话管理,Web集成,缓存等。
2.快速入门(SpringBoot+mybatisPlus集成)
实现登录拦截
1、导入依赖
<!--Web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--启动-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--测试-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--log4j-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!--数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-core</artifactId>
<version>3.4.2</version>
<scope>compile</scope>
</dependency>
<!--Shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
<scope>compile</scope>
</dependency>
<!--导入thymeleaf模板-->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>
2、编写Shiro配置文件:ShiroConfig
@Configuration
public class ShiroConfig {
//ShiroFilterFactoryBean
@Bean
public ShiroFilterFactoryBean factoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean factoryBean=new ShiroFilterFactoryBean();
//将security放入bean中
factoryBean.setSecurityManager(securityManager);
/*
1.anon:无需验证就可访问
2.authc:必须认证才可以访问
3.user:必须拥有”记住我“才能用
4.perms:拥有对某个资源的权限才能访问
5.role:拥有某个角色权限才能访问
*/
//拦截页面
Map filterMap=new LinkedHashMap();
filterMap.put("/user/login","anon");
filterMap.put("/user/add","authc");
filterMap.put("/user/update","authc");
//使用通用符
// filterMap.put("/user/*","authc");
factoryBean.setFilterChainDefinitionMap(filterMap);
//设置登录的请求
factoryBean.setLoginUrl("/user/toLogin");
factoryBean.setSuccessUrl("index");
return factoryBean;
}
//DefaultWebSecurityManager
@Bean(name = "securityManager")
public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
//关联Realm
securityManager.setRealm(userRealm);
return securityManager;
}
@Bean(name = "userRealm")
public UserRealm realm(){
return new UserRealm();
}
}
3、编写Realm配置文件:RealmConfig
public class UserRealm extends AuthorizingRealm {
@Autowired
private UserMapper userMapper;
/*
授权
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
/*
登录认证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//获取当前用户名/账号
UsernamePasswordToken token=(UsernamePasswordToken)authenticationToken;
String username = token.getUsername();
//连接数据库,通过用户名得到密码
Map<String,Object> map=new HashMap<>();
map.put("username",username);
List<UserShiro> users = userMapper.selectByMap(map);
UserShiro userShiro=null;
for (UserShiro user : users) {
userShiro=user;
}
//得到密码
String password=userShiro.getPassword();
//密码认证,shiro做
return new SimpleAuthenticationInfo("",password,"");
}
}
4、登录时需要将账号密码放入token中
@RequestMapping("/user/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 "user/login";
}catch (UnknownAccountException e){
//用户名不存在
model.addAttribute("msg","用户名不存在");
return "user/login";
}catch (IncorrectCredentialsException e){
//密码错误
model.addAttribute("msg","密码错误");
return "index";
}
}