SpringBoot整合Shiro許可權管理框架
阿新 • • 發佈:2018-11-10
專案目錄結構
1.pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.wpf</groupId> <artifactId>shiro-springboot</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.6.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.4</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> </dependencies> </project>
2.application.yml
server: port: 8080 spring: datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/spring_shiro?useUnicode=true&characterEncoding=UTF-8 username: root password: root type: com.alibaba.druid.pool.DruidDataSource freemarker: suffix: .html cache: false template-loader-path: classpath:/templates mybatis: #mapper-locations: classpath:mapper/*.xml type-aliases-package: com.wpf.pojo configuration: map-underscore-to-camel-case: true
3.3個實體類 使用者,角色,許可權
package com.wpf.pojo; /** * 使用者 */ public class User { private Long id; private String name; private Integer password; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getPassword() { return password; } public void setPassword(Integer password) { this.password = password; } }
package com.wpf.pojo;
/**
* 角色
*/
public class Role {
private Long id;
private String roleName;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
}
package com.wpf.pojo;
/**
* 許可權
*/
public class Permission {
private Long id;
private String permission;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getPermission() {
return permission;
}
public void setPermission(String permission) {
this.permission = permission;
}
}
4.dao層 3個對應實體類 用來查詢使用者,角色,和許可權
@Repository
public interface UserDao {
@Select("select * from user where name = #{name}")
User findByName(String name);
}
@Repository
public interface RoleDao {
@Select("select * from role where user_id = #{id}")
List<Role> findByUserId(Long id);
}
@Repository
public interface PermissionDao {
@Select("select * from permission where role_id = #{id}")
List<Permission> findByRoleId(Long id);
}
5.自定義 Realm 用於測試直接呼叫了Dao層,跳過了service層,LoginService可替換為UserDao
//實現AuthorizingRealm介面使用者使用者認證
public class MyShiroRealm extends AuthorizingRealm {
//用於使用者查詢
@Autowired
private LoginServiceImpl loginService;
//使用者角色查詢
@Autowired
private RoleDao roleDao;
//用於許可權查詢
@Autowired
private PermissionDao permissionDao;
//角色許可權和對應許可權新增
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//獲取登入使用者名稱
String name= (String) principalCollection.getPrimaryPrincipal();
//查詢使用者名稱稱
User user = loginService.findByName(name);
//新增角色和許可權
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
//通過使用者查尋角色
List<Role> roles = roleDao.findByUserId(user.getId());
for (Role role:roles) {
//新增角色
simpleAuthorizationInfo.addRole(role.getRoleName());
//通過角色查詢許可權
List<Permission> permissions = permissionDao.findByRoleId(role.getId());
for (Permission permission:permissions){
//新增角色許可權
simpleAuthorizationInfo.addStringPermission(permission.getPermission());
}
}
return simpleAuthorizationInfo;
}
//使用者認證
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//加這一步的目的是在Post請求的時候會先進認證,然後在到請求
if (authenticationToken.getPrincipal() == null) {
return null;
}
//獲取使用者資訊
String name = authenticationToken.getPrincipal().toString();
User user = loginService.findByName(name);
if (user == null) {
//這裡返回後會報出對應異常
return null;
} else {
//這裡驗證authenticationToken和simpleAuthenticationInfo的資訊
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, user.getPassword().toString(), getName());
return simpleAuthenticationInfo;
}
}
}
6.將自定義Realm配置進Shiro,配置過濾條件
@Configuration
public class ShiroConfiguration {
//將自己的驗證方式加入容器
@Bean
public MyShiroRealm myShiroRealm() {
MyShiroRealm myShiroRealm = new MyShiroRealm();
return myShiroRealm;
}
//許可權管理,配置主要是Realm的管理認證
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
return securityManager;
}
//Filter工廠,設定對應的過濾條件和跳轉條件
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String,String> map = new HashMap<String, String>();
//登出
map.put("/logout","logout");
//對所有使用者認證
map.put("/**","authc");
//管理員,需要角色許可權 “admin” 訪問admin下面的路徑需要admin角色
map.put("/admin/**", "roles[admin]");
//登入
shiroFilterFactoryBean.setLoginUrl("/login");
//首頁
shiroFilterFactoryBean.setSuccessUrl("/index");
//錯誤頁面,認證不通過跳轉
shiroFilterFactoryBean.setUnauthorizedUrl("/error");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
return shiroFilterFactoryBean;
}
//加入註解的使用,不加入這個註解不生效
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
}
7.controller層 測試登入,退出,和許可權
@Controller
public class LoginResource {
//進入登入頁面
@RequestMapping(value = "/login",method = RequestMethod.GET)
public String login(){
return "/logins";
}
//post登入
@RequestMapping(value = "/login",method = RequestMethod.POST)
@ResponseBody
public String login(String username,String password){
//新增使用者認證資訊
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(
username,
password);
//進行驗證,這裡可以捕獲異常,然後返回對應資訊
subject.login(usernamePasswordToken);
if(subject.hasRole("admin")){
System.out.println("admin角色");
}
if(subject.isPermitted("create")){
System.out.println("有create許可權");
}
return "登入成功";
}
//跳轉到主頁
@RequestMapping(value = "/index")
public String index(){
return "indexx";
}
//退出登入
@RequestMapping(value = "/logout")
public String logout(){
return "logout";
}
//錯誤頁面展示
@RequestMapping(value = "/error",method = RequestMethod.POST)
@ResponseBody
public String error(){
return "error ok!";
}
//註解的使用
@RequiresRoles("admin")
@RequiresPermissions("create")
@RequestMapping(value = "/create")
@ResponseBody
public String create(){
return "Create success!";
}
}
8.基本的登入,主頁 頁面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/login" method="post">
使用者名稱:<input type="text" name="username"><br>
密碼:<input type="text" name="password"><br>
<input type="submit" value="登入">
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
主頁
</body>
</html>
9.資料庫資料
使用者表
角色表
許可權表
專案原始碼:https://download.csdn.net/download/weixin_42460179/10728459