springboot整合shiro

一、shiro簡介
Apache Shiro是一個強大且易用的Java安全框架,執行身份驗證、授權、密碼學和會話管理。相比較Spring Security,shiro有小巧、簡單、易上手等的優點。所以很多框架都在使用shiro。Shiro包含了三個核心組件:Subject, SecurityManager 和 Realms。
1.Subject代表了當前用戶的安全操作。
2.SecurityManager則管理所有用戶的安全操作。它是Shiro框架的核心,典型的Facade模式,Shiro通過SecurityManager來管理內部組件實例,並通過它來提供安全管理的各種服務。
3.Realm充當了Shiro與應用安全數據間的“橋樑”或者“連接器”。也就是說,當對用戶執行認證(登錄)和授權(訪問控制)驗證時,Shiro會從應用配置的Realm中查找用戶及其權限信息

二、springboot整合shiro

1.使用maven創建一個jar項目,在pom.xml文件中添加依賴

[XML] 純文本查看 複製代碼
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
  </properties>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </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-test</artifactId>
        <scope>test</scope>
        </dependency>
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.1.3</version>
    </dependency>
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-core</artifactId>
        <version>1.2.2</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.25</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>0.2.23</version>
    </dependency>
    <!-- shiro權限控制框架 -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.3.2</version>
        </dependency>
  </dependencies>


2.編寫MyShiroRealm類,實現AuthorizingRealm接口

[Java] 純文本查看 複製代碼
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class MyShiroRealm extends AuthorizingRealm {
 
    /**
     * 授權用戶權限
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(
            PrincipalCollection principals) {
        //獲取用戶
        User user = (User)SecurityUtils.getSubject().getPrincipal();
        SimpleAuthorizationInfo info =  new SimpleAuthorizationInfo();
        //獲取用戶角色
        Set<String> roleSet = new HashSet<String>();
        roleSet.add("100002");
        info.setRoles(roleSet);
 
        //獲取用戶權限
        Set<String> permissionSet = new HashSet<String>();
        permissionSet.add("權限添加");
        permissionSet.add("權限刪除");
        info.setStringPermissions(permissionSet);
 
 
        return info;
    }
 
    /**
     * 驗證用戶身份
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken authcToken) throws AuthenticationException {
 
        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
        String username = token.getUsername();
        String password = String.valueOf(token.getPassword());
 
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("nickname", username);
        //密碼進行加密處理  明文爲  password+name
        String paw = password+username;
        String pawDES = MyDES.encryptBasedDes(paw);
        map.put("pswd", pawDES);
 
        User user = new User();
        user.setId("112222");
        user.setUsername(username);
        user.setPassword(pawDES);
 
 
        return new SimpleAuthenticationInfo(user, password, getName());
    }
 
}


3.實現ShiroConfiguration

[Java] 純文本查看 複製代碼
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
@Configuration
public class ShiroConfiguration {
 
    /**
     * ShiroFilterFactoryBean 處理攔截資源文件問題。
     * 注意:單獨一個ShiroFilterFactoryBean配置是或報錯的,以爲在
     * 初始化ShiroFilterFactoryBean的時候需要注入:SecurityManager
     *
     * Filter Chain定義說明 1、一個URL可以配置多個Filter,使用逗號分隔 2、當設置多個過濾器時,全部驗證通過,才視爲通過
     * 3、部分過濾器可指定參數,如perms,roles
     *
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
 
        // 必須設置 SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
 
        // 如果不設置默認會自動尋找Web工程根目錄下的"/login.jsp"頁面
        shiroFilterFactoryBean.setLoginUrl("/login");
        // 登錄成功後要跳轉的鏈接
        shiroFilterFactoryBean.setSuccessUrl("/index");
        // 未授權界面;
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");
 
        //自定義攔截器
        Map<String, Filter> filtersMap = new LinkedHashMap<String, Filter>();
        //限制同一帳號同時在線的個數。
        //filtersMap.put("kickout", kickoutSessionControlFilter());
        shiroFilterFactoryBean.setFilters(filtersMap);
 
        // 權限控制map.
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
        // 配置不會被攔截的鏈接 順序判斷
        // 配置退出過濾器,其中的具體的退出代碼Shiro已經替我們實現了
        // 從數據庫獲取動態的權限
        // filterChainDefinitionMap.put("/add", "perms[權限添加]");
        // <!-- 過濾鏈定義,從上向下順序執行,一般將 /**放在最爲下邊 -->:這是一個坑呢,一不小心代碼就不好使了;
        // <!-- authc:所有url都必須認證通過纔可以訪問; anon:所有url都都可以匿名訪問-->
        //logout這個攔截器是shiro已經實現好了的。
        // 從數據庫獲取
        /*List<SysPermissionInit> list = sysPermissionInitService.selectAll();
 
        for (SysPermissionInit sysPermissionInit : list) {
            filterChainDefinitionMap.put(sysPermissionInit.getUrl(),
                    sysPermissionInit.getPermissionInit());
        }*/
 
        shiroFilterFactoryBean
                .setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }
 
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 設置realm.
        securityManager.setRealm(myShiroRealm());
        // 自定義緩存實現 使用redis
        //securityManager.setCacheManager(cacheManager());
        // 自定義session管理 使用redis
        //securityManager.setSessionManager(sessionManager());
        //注入記住我管理器;
        securityManager.setRememberMeManager(rememberMeManager());
        return securityManager;
    }
 
    public MyShiroRealm myShiroRealm(){
        return new MyShiroRealm();
    }
 
    /**
     * cookie對象;
     * @return
     */
    public SimpleCookie rememberMeCookie(){
       //這個參數是cookie的名稱,對應前端的checkbox的name = rememberMe
       SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
       //<!-- 記住我cookie生效時間30天 ,單位秒;-->
       simpleCookie.setMaxAge(2592000);
       return simpleCookie;
    }
 
    /**
     * cookie管理對象;記住我功能
     * @return
     */
    public CookieRememberMeManager rememberMeManager(){
       CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
       cookieRememberMeManager.setCookie(rememberMeCookie());
       //rememberMe cookie加密的密鑰 建議每個項目都不一樣 默認AES算法 密鑰長度(128 256 512 位)
       cookieRememberMeManager.setCipherKey(Base64.decode("3AvVhmFLUs0KTA3Kprsdag=="));
       return cookieRememberMeManager;
    }
 
}


4.編寫LoginController類測試Shiro

[Java] 純文本查看 複製代碼
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
@RestController
public class LoginController {
 
    @RequestMapping(value="/login",method=RequestMethod.POST)
    public String login(String username, String password,String vcode,Boolean rememberMe){
        System.out.println(username);
        UsernamePasswordToken token = new UsernamePasswordToken(username, password,rememberMe);
        SecurityUtils.getSubject().login(token);
 
        return "loginSuccess";
    }
 
    @RequestMapping(value="/index",method=RequestMethod.GET)
    public String home(){
        Subject subject = SecurityUtils.getSubject();
        User principal = (User)subject.getPrincipal();
 
        return "Home";
    }
 
}


引自博客:https://blog.csdn.net/u012343297/article/details/78919966

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章