13、SpringBoot------整合shiro

开发工具:STS

前言:

  shiro,一套简单灵活的安全权限管理框架。

      把所有对外暴露的服务API都看作是一种资源,那么shiro就是负责控制哪些可以获得资源,哪些不能获取。

一个比较不错的教程:https://www.w3cschool.cn/shiro/

一个简单的小实例:

1.引入依赖

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 4     <modelVersion>4.0.0</modelVersion>
 5 
 6     <groupId>com.xm</groupId>
 7     <artifactId>springboot_rbac</artifactId>
 8     <version>0.0.1-SNAPSHOT</version>
 9     <packaging>jar</packaging>
10 
11     <name>springboot_rbac</name>
12     <description>This is a Web about springcloud</description>
13 
14     <parent>
15         <groupId>org.springframework.boot</groupId>
16         <artifactId>spring-boot-starter-parent</artifactId>
17         <version>1.5.15.RELEASE</version>
18         <relativePath/> <!-- lookup parent from repository -->
19     </parent>
20 
21     <properties>
22         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
23         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
24         <java.version>1.8</java.version>
25     </properties>
26 
27     <dependencies>
28         <dependency>
29             <groupId>org.springframework.boot</groupId>
30             <artifactId>spring-boot-starter-web</artifactId>
31         </dependency>
32 
33         <dependency>
34             <groupId>org.springframework.boot</groupId>
35             <artifactId>spring-boot-starter-test</artifactId>
36             <scope>test</scope>
37         </dependency>
38        <dependency>
39            <groupId>org.apache.shiro</groupId>
40            <artifactId>shiro-spring</artifactId>
41            <version>1.2.2</version>
42        </dependency>
43        <!-- 配置shiro注解,需要用到aop -->
44        <dependency>
45             <groupId>org.springframework.boot</groupId>
46             <artifactId>spring-boot-starter-aop</artifactId>
47         </dependency>
48     </dependencies>
49 
50     <build>
51         <plugins>
52             <plugin>
53                 <groupId>org.springframework.boot</groupId>
54                 <artifactId>spring-boot-maven-plugin</artifactId>
55             </plugin>
56         </plugins>
57     </build>
58 
59 
60 </project>

2.配置文件application.yml

1 spring.aop.proxy-target-class=true

3.realm

 1 package com.xm.shiro.rbac;
 2 
 3 import java.util.HashMap;
 4 import java.util.Map;
 5 
 6 import org.apache.shiro.authc.AccountException;
 7 import org.apache.shiro.authc.AuthenticationException;
 8 import org.apache.shiro.authc.AuthenticationInfo;
 9 import org.apache.shiro.authc.AuthenticationToken;
10 import org.apache.shiro.authc.SimpleAuthenticationInfo;
11 import org.apache.shiro.authc.UsernamePasswordToken;
12 import org.apache.shiro.authz.AuthorizationInfo;
13 import org.apache.shiro.authz.SimpleAuthorizationInfo;
14 import org.apache.shiro.realm.AuthorizingRealm;
15 import org.apache.shiro.subject.PrincipalCollection;
16 
17 public class MyRealm extends AuthorizingRealm {
18     
19     String getRoles() {
20         System.out.println("查找权限!");
21         return "sun";
22     }
23 
24     /**
25      * 角色、权限认证
26      */
27     @Override
28     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
29         SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
30         //添加角色
31         info.addRole(getRoles());
32         //添加权限
33         //info.addStringPermission("hello");
34         return info;
35     }
36 
37     /**
38      * 身份认证
39      */
40     @Override
41     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
42         
43         UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
44         String password = new String(usernamePasswordToken.getPassword());
45         if(usernamePasswordToken.getUsername().equals("admin") && password.equals("123456")) {
46             Map<String, Object> user = new HashMap<>();
47             user.put("username", "admin");
48             user.put("password", "123456");
49             return new SimpleAuthenticationInfo(user, user.get("password").toString(), this.getName());
50         } else {
51             throw new AccountException("帐号或密码不正确!");
52         }
53     }
54 }

4.配置shiro

 1 package com.xm.shiro.rbac;
 2 
 3 import java.util.LinkedHashMap;
 4 import java.util.Map;
 5 
 6 import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
 7 import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
 8 import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
 9 import org.springframework.context.annotation.Bean;
10 import org.springframework.context.annotation.Configuration;
11 import org.apache.shiro.mgt.SecurityManager;
12 
13 @Configuration
14 public class ShiroConfig {
15     
16     @Bean
17     public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
18         ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
19 
20         // 必须设置 SecurityManager
21         shiroFilterFactoryBean.setSecurityManager(securityManager);
22 
23         // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
24         shiroFilterFactoryBean.setLoginUrl("/login");
25 
26         // 拦截器.
27         Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
28         // 配置不会被拦截的链接 顺序判断
29         filterChainDefinitionMap.put("/static/**", "anon");
30         filterChainDefinitionMap.put("/doLogin/**", "anon");
31 
32         // <!-- 过滤链定义,从上向下顺序执行,一般将 /**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
33         // <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
34         filterChainDefinitionMap.put("/**", "authc");
35 
36         shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
37         System.out.println("Shiro拦截器工厂类注入成功");
38         return shiroFilterFactoryBean;
39     }
40 
41     /**
42      * 注入MyRealm
43      * @return
44      */
45     @Bean
46     public SecurityManager securityManager() {
47         DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
48         // 设置realm.
49         securityManager.setRealm(myShiroRealm());
50         return securityManager;
51     }
52     
53     /**
54      * 配置注解
55      * @param securityManager
56      * @return
57      */
58     @Bean
59     public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
60         AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor
61             = new AuthorizationAttributeSourceAdvisor();
62         authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
63         return authorizationAttributeSourceAdvisor;
64     }
65     
66     public MyRealm myShiroRealm() {
67         return new MyRealm();
68     }
69 
70 }

5.controller

注解:

常用的就这两种

(1)@RequiresPermissions("hello") =>是否具有hello权限

(2)@@RequiresRoles("sun")=>是否有sun角色

 1 package com.xm.shiro.controller;
 2 
 3 import org.apache.shiro.SecurityUtils;
 4 import org.apache.shiro.authc.AuthenticationException;
 5 import org.apache.shiro.authc.IncorrectCredentialsException;
 6 import org.apache.shiro.authc.UsernamePasswordToken;
 7 import org.apache.shiro.authz.annotation.RequiresPermissions;
 8 import org.apache.shiro.subject.Subject;
 9 import org.springframework.web.bind.annotation.GetMapping;
10 import org.springframework.web.bind.annotation.PathVariable;
11 import org.springframework.web.bind.annotation.RequestMapping;
12 import org.springframework.web.bind.annotation.RestController;
13 
14 @RestController
15 public class UserController {
16     
17     @RequiresPermissions("hello")
18     @GetMapping("/hello")
19     public String hello() {
20         return "Hello Shiro!";
21     }
22     
23     @GetMapping("/login")
24     public String login() {
25         return "权限管理";
26     }
27     
28     @GetMapping("/doLogin/{username}/{password}")
29     public String doLogin(@PathVariable("username") String username,@PathVariable("password") String password) {
30         UsernamePasswordToken token = new UsernamePasswordToken(username, password);
31         Subject currentUser = SecurityUtils.getSubject();
32         try {
33             currentUser.login(token);
34             //此步将 调用realm的认证方法
35         } catch(IncorrectCredentialsException e){
36             //这最好把 所有的 异常类型都背会
37             return "密码错误";
38         } catch (AuthenticationException e) {
39             return "登录失败";
40         }        
41         
42         currentUser.hasRole("sun");
43         currentUser.hasRole("sun");
44         currentUser.hasRole("sun");
45         currentUser.hasRole("sun");
46         return token.getPrincipal()+":登录成功";
47     }
48     
49     @GetMapping("/logout")
50     public String logout() {
51         Subject currentUser = SecurityUtils.getSubject();
52         currentUser.logout();
53         return "退出登录";
54     }
55     
56     @GetMapping("/noUnauthorized")
57     public String error() {
58         return  "无权限";
59     }
60 
61 }
原文地址:https://www.cnblogs.com/TimerHotel/p/springboot13.html