工程结构
1.在pom.xml中引入jar
<!--druid jar-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.21</version>
</dependency>
<!--springboot 整合mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<!--springboot 整合shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.7.0</version>
</dependency>
<!--lombook-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--加入 thymeleaf模板-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--使用shiro标签库-->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
2.application.properties
#数据源
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.url=jdbc:mysql://localhost:3306/shiro?serverTimezone=Asia/Shanghai&characterEncoding=UTF8
spring.datasource.druid.username=root
spring.datasource.druid.password=654123
#日志
logging.level.com.ganin.dao=debug
3.dao,entity,service,controller…
entity:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer userid;
private String username;
private String userpwd;
private String sex;
private String address;
private String salt;//加盐
}
dao
//用mybatis-plus 必须继承BaseMapper
public interface UserDao extends BaseMapper<User> {
}
/**
* 根据id找权限
* @param userid
* @return
*/
public List<String> findPermissionByUserId(Integer userid);
service
public interface UserService {
/**
* 根据用户名找权限
* @param username
* @return
*/
public User findUserByUserName(String username);
}
@Service
public class UserServiceImpl implements UserService {
@Resource
private UserDao userDao;
@Override
public User findUserByUserName(String username) {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("username",username);
User user = userDao.selectOne(wrapper);
return user;
}
}
public interface PermissionService {
/**
* 根据id找权限
* @param userid
* @return
*/
public List<String> queryPermissionByUserId(Integer userid);
}
@Service
public class PermissionServiceImpl implements PermissionService {
@Resource
private PermissionDao permissionDao;
@Override
public List<String> queryPermissionByUserId(Integer userid) {
List<String> permission = permissionDao.findPermissionByUserId(userid);
return permission;
}
}
<mapper namespace="com.ganin.dao.PermissionDao">
<select id="findPermissionByUserId" resultType="java.lang.String">
select percode from user_role ur,
role_permission rp,
permission p
where ur.roleid=rp.roleid and
rp.perid=p.perid and
ur.userid=#{userid}
</select>
</mapper>
controller
@Controller
public class LoginController {
@PostMapping("/login")
public String login(String username,String userpwd){
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, userpwd);
try {
subject.login(token);
return "success";
} catch (AuthenticationException e) {
return "login";
}
}
}
@Controller
public class PageController {
@GetMapping("tologin")
public String tologin(){
return "login";
}
}
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("/query")
@RequiresPermissions("user:query")
public String query(){
return "user:query";
}
@GetMapping("/delete")
@RequiresPermissions("user:delete")
public String delete(){
return "user:delete";
}
@GetMapping("/update")
@RequiresPermissions("user:update")
public String update(){
return "user:update";
}
@GetMapping("/insert")
@RequiresPermissions("user:insert")
public String insert(){
return "user:insert";
}
@GetMapping("/export")
@RequiresPermissions("user:export")
public String export(){
return "user:export";
}
}
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>登陆页码</h1>
<form action="/login" method="post">
账号:<input type="text" name="username"/><br>
密码:<input type="text" name="userpwd"/><br>
<input type="submit" value="登陆"/>
<input type="button" value="注册" onclick="location.href='regist'"/>
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>成功!!!</h2>
<shiro:hasPermission name="user:query">
<a href="/user/query" >查询所有的用户</a>
</shiro:hasPermission>
<shiro:hasPermission name="user:delete">
<a href="/user/delete" >删除用户</a>
</shiro:hasPermission>
<shiro:hasPermission name="user:insert">
<a href="/user/insert" >插入用户</a>
</shiro:hasPermission>
<shiro:hasPermission name="user:update">
<a href="/user/update" >更新用户</a>
</shiro:hasPermission>
<shiro:hasPermission name="user:export">
<a href="/user/export" >导出用户</a>
</shiro:hasPermission>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
无权限 damn
</body>
</html>
tips:默认thymeleaf不支持shiro标签库。使用如下方式来解决
<!--thymeleaf支持shiro的依赖-->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
//使shiro标签库可以在thymeleaf中使用(自己定义的配置文件中加)
@Bean
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}
4.整合shiro
@Configuration
public class ConfigClassHHH {
/*安全管理*/
@Bean("securityManager") //安全管理
public DefaultWebSecurityManager securityManager(MyRealm myRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myRealm);
return securityManager;
}
@Bean("myRealm") //密码匹配器
public MyRealm myRealm(CredentialsMatcher credentialsMatcher){
MyRealm myRealm = new MyRealm();
myRealm.setCredentialsMatcher(credentialsMatcher);
return myRealm;
}
@Bean("credentialsMatcher")
public CredentialsMatcher credentialsMatcher(){
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
matcher.setHashAlgorithmName("MD5");
matcher.setHashIterations(1024);
return matcher;
}
/*过滤规则*/
@Bean("shiroFilterFactoryBean")
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setLoginUrl("/tologin"); //未认证返回的界面
shiroFilterFactoryBean.setSuccessUrl("/success.html"); //认证成功后返回
HashMap<String, String> map = new HashMap<>();
map.put("/login","anon"); //匿名访问
map.put("/static/**","anon");
map.put("/**","authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
return shiroFilterFactoryBean;
}
//使shiro标签库可以在thymeleaf中使用
@Bean
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}
}
测试: