国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - JAVA教程 - SpringBoot集成Shiro進行權限控制和管理的示例

SpringBoot集成Shiro進行權限控制和管理的示例

2021-04-09 11:47BlueKitty1210 JAVA教程

這篇文章主要介紹了SpringBoot集成Shiro進行權限控制和管理的示例,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

shiro

apache shiro 是一個輕量級的身份驗證與授權框架,與spring security 相比較,簡單易用,靈活性高,springboot本身是提供了對security的支持,畢竟是自家的東西。springboot暫時沒有集成shiro,這得自己配。

1 . 添加依賴

?
1
2
3
4
5
6
7
8
9
10
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-spring</artifactId>
  <version>1.2.5</version>
</dependency>
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-ehcache</artifactId>
  <version>1.2.5</version>
</dependency>

2 . 編寫Shiro配置類

?
1
2
3
4
5
6
7
8
9
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
package com.xbz.web.system.config; 
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.session.SessionListener;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn; 
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
/**
 * shiro配置類
 * ApacheShiro核心通過Filter來實現權限控制和攔截 , 就好像SpringMVC通過DispachServlet來主控制請求分發一樣 .
 * 既然是使用Filter , 即是通過URL規則來進行過濾和權限校驗 , 所以我們需要定義一系列關于URL的規則和訪問權限
 */
@Configuration
public class ShiroConfiguration {
  /**
   * DefaultAdvisorAutoProxyCreator , Spring的一個bean , 由Advisor決定對哪些類的方法進行AOP代理 .
   */
  @Bean
  @ConditionalOnMissingBean
  public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
    DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
    defaultAAP.setProxyTargetClass(true);
    return defaultAAP;
  }
 
  /**
   * ShiroFilterFactoryBean : 為了生成ShiroFilter , 處理攔截資源文件問題 .
   * 它主要保持了三項數據 , securityManager , filters , filterChainDefinitionManager .
   * 注意 : 單獨一個ShiroFilterFactoryBean配置是或報錯的 , 因為在初始化ShiroFilterFactoryBean的時候需要注入:SecurityManager
   *
   * FilterChain定義說明
   * 1 . 一個URL可以配置多個Filter , 使用逗號分隔
   * 2 . 當設置多個過濾器時 , 全部驗證通過 , 才視為通過
   * 3 . 部分過濾器可指定參數 , 如perms , roles
   *
   */
  @Bean
  public ShiroFilterFactoryBean shiroFilterFactoryBean() {
    ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    shiroFilterFactoryBean.setSecurityManager(securityManager());
    shiroFilterFactoryBean.setLoginUrl("/login");//不設置默認找web工程根目錄下的login.jsp頁面
    shiroFilterFactoryBean.setSuccessUrl("/index");//登錄成功之后要跳轉的連接
    shiroFilterFactoryBean.setUnauthorizedUrl("/403");//未授權跳轉頁面
    /* //自定義攔截器 , 多個filter的設置 */
//    Map<String, Filter> filters = new LinkedHashMap<>();
//    LogoutFilter logoutFilter = new LogoutFilter();//限制同一帳號同時在線的個數。或單點登錄等
//    logoutFilter.setRedirectUrl("/login");
//    filters.put("logout",null);
//    shiroFilterFactoryBean.setFilters(filters); 
    Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
    //filterChainDefinitionManager必須是LinkedHashMap因為它必須保證有序
    filterChainDefinitionMap.put("/css/**", "anon");//靜態資源不要求權限 , 若有其他目錄下文件(如js,img等)也依此設置
    filterChainDefinitionMap.put("/", "anon");
    filterChainDefinitionMap.put("/login", "anon");//配置不需要權限訪問的部分url
    filterChainDefinitionMap.put("/logout", "logout");
    filterChainDefinitionMap.put("/user/**", "authc,roles[ROLE_USER]");//用戶為ROLE_USER 角色可以訪問 . 由用戶角色控制用戶行為 . 
    filterChainDefinitionMap.put("/events/**", "authc,roles[ROLE_ADMIN]");
    //    filterChainDefinitionMap.put("/user/edit/**", "authc,perms[user:edit]");// 這里為了測試 , 固定寫死的值 , 也可以從數據庫或其他配置中讀取 , 此處是用權限控制
 
    filterChainDefinitionMap.put("/**", "authc");//需要登錄訪問的資源 , 一般將/**放在最下邊
 
    shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
    return shiroFilterFactoryBean;
  }
 
  //region Cookie及Session
  // ==================== Cookie及Session管理 begin ====================
  private static final String COOKIE_NAME = "rememberMe";
  /** cookie對象管理 */
  public SimpleCookie rememberMeCookie(){
    //這個參數是cookie的名稱,對應前端的checkbox的name = rememberMe
    SimpleCookie simpleCookie = new SimpleCookie(COOKIE_NAME);
    simpleCookie.setMaxAge(604800);//記住我cookie生效時間7天 ,單位秒
    return simpleCookie;
  }
 
  /** cookie管理對象 : 記住我功能 */
  public CookieRememberMeManager rememberMeManager(){
    CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
    cookieRememberMeManager.setCookie(rememberMeCookie());
    cookieRememberMeManager.setCipherKey(Base64.decode("3AvVhmFLUs0KTA3Kprsdag=="));//rememberMe cookie加密的密鑰 建議每個項目都不一樣 默認AES算法 密鑰長度(128 256 512 位)
    return cookieRememberMeManager;
  }
 
  @Bean
  SessionDAO sessionDAO() {
    return new MemorySessionDAO();
  }
 
  @Bean
  public SessionManager sessionManager() {
    DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
    Collection<SessionListener> listeners = new ArrayList<>();
    listeners.add(new BDSessionListener());
    sessionManager.setSessionListeners(listeners);
    sessionManager.setSessionDAO(sessionDAO());
    return sessionManager;
  }
  // ==================== Cookie及Session管理 end ====================
  //endregion
 
  /**
   * SecurityManager : 核心安全事務管理器 , 權限管理
   * 這個類組合了登陸 , 登出 , 權限 , session的處理 . 是個比較重要的類 .
   */
  @Bean(name = "securityManager")
  public DefaultWebSecurityManager securityManager() {
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    securityManager.setRealm(shiroRealm());
    securityManager.setCacheManager(ehCacheManager());////用戶授權/認證信息Cache, 采用EhCache 緩存
 
    // 自定義session管理 使用redis
    securityManager.setSessionManager(sessionManager());
 
    //注入記住我管理器;
    securityManager.setRememberMeManager(rememberMeManager());
    return securityManager;
  }
 
  /**
   * ShiroRealm , 這是個自定義的認證類 , 繼承自AuthorizingRealm ,
   * 負責用戶的認證和權限的處理 , 可以參考JdbcRealm的實現 .
   */
  @Bean
  @DependsOn("lifecycleBeanPostProcessor")
  public ShiroRealm shiroRealm(CredentialsMatcher matcher) {
    ShiroRealm realm = new ShiroRealm();
    realm.setCredentialsMatcher(matcher);//密碼校驗實現
    return realm;
  }
 
  /**
   * EhCacheManager , 緩存管理
   * 用戶登陸成功后 , 把用戶信息和權限信息緩存起來 , 然后每次用戶請求時 , 放入用戶的session中 , 如果不設置這個bean , 每個請求都會查詢一次數據庫 .
   */
  @Bean
  @DependsOn("lifecycleBeanPostProcessor")
  public EhCacheManager ehCacheManager() {
    EhCacheManager em = new EhCacheManager();
    em.setCacheManagerConfigFile("classpath:config/ehcache.xml");//配置文件路徑
    return em;
  }
 
  /**
   * LifecycleBeanPostProcessor , 這是個DestructionAwareBeanPostProcessor的子類 ,
   * 負責org.apache.shiro.util.Initializable類型bean的生命周期的 , 初始化和銷毀 .
   * 主要是AuthorizingRealm類的子類 , 以及EhCacheManager類 .
   */
  @Bean(name = "lifecycleBeanPostProcessor")
  public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
    return new LifecycleBeanPostProcessor();
  }
 
  /**
   * HashedCredentialsMatcher , 這個類是為了對密碼進行編碼的 ,
   * 防止密碼在數據庫里明碼保存 , 當然在登陸認證的時候 ,
   * 這個類也負責對form里輸入的密碼進行編碼
   * 處理認證匹配處理器:如果自定義需要實現繼承HashedCredentialsMatcher
   */
  @Bean(name = "hashedCredentialsMatcher")
  public HashedCredentialsMatcher hashedCredentialsMatcher() {
    HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
    credentialsMatcher.setHashAlgorithmName("MD5");//指定加密方式方式,也可以在這里加入緩存,當用戶超過五次登陸錯誤就鎖定該用戶禁止不斷嘗試登陸
    credentialsMatcher.setHashIterations(2);
    credentialsMatcher.setStoredCredentialsHexEncoded(true);
    return credentialsMatcher;
  }
 
  /**
   * AuthorizationAttributeSourceAdvisor , shiro里實現的Advisor類 ,
   * 內部使用AopAllianceAnnotationsAuthorizingMethodInterceptor來攔截用以下注解的方法 .
   */
  @Bean
  public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
    AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
    advisor.setSecurityManager(securityManager());
    return advisor;
  }
 
  //thymeleaf模板引擎和shiro整合時使用
  @Bean
  public ShiroDialect shiroDialect() {
    return new ShiroDialect();
  }
}

3 . 自定義Realm驗證類

?
1
2
3
4
5
6
7
8
9
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
package com.yiyun.web.system.config; 
import com.yiyun.dao.master.UserDao;
import com.yiyun.domain.UserDO;
import com.yiyun.web.common.utils.ShiroUtils;
import com.yiyun.web.system.service.MenuService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired; 
import java.util.*;
 
/**
 * 獲取用戶的角色和權限信息
 */
public class ShiroRealm extends AuthorizingRealm {
 
  // 一般這里都寫的是servic
  @Autowired
  private UserDao userMapper;
  @Autowired
  private MenuService menuService;
 
  /**
   * 登錄認證 一般情況下 , 登錄成功之后就給當前用戶進行權限賦予了
   * 根據用戶的權限信息做授權判斷,這一步是以doGetAuthenticationInfo為基礎的,只有在有用戶信息后才能根據用戶的角色和授權信息做判斷是否給用戶授權,因此這里的Roles和Permissions是用戶的兩個重點判斷依據
   * @param authenticationToken
   * @return
   * @throws AuthenticationException
   */
  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
    UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
    UserDo user = userMapper.findByName(token.getUsername());//查出是否有此用戶
 
    if(user != null){
      // 若存在,將此用戶存放到登錄認證info中,無需自己做密碼對比,Shiro會為我們進行密碼對比校驗
      List<URole> rlist = uRoleDao.findRoleByUid(user.getId());//獲取用戶角色
      List<UPermission> plist = uPermissionDao.findPermissionByUid(user.getId());//獲取用戶權限
      List<String> roleStrlist=new ArrayList<String>();////用戶的角色集合
      List<String> perminsStrlist=new ArrayList<String>();//用戶的權限集合
      for (URole role : rlist) {
        roleStrlist.add(role.getName());
      }
      for (UPermission uPermission : plist) {
        perminsStrlist.add(uPermission.getName());
      }
      user.setRoleStrlist(roleStrlist);
      user.setPerminsStrlist(perminsStrlist);
      Session session = SecurityUtils.getSubject().getSession();
      session.setAttribute("user", user);//成功則放入session
      // 若存在,將此用戶存放到登錄認證info中,無需自己做密碼對比,Shiro會為我們進行密碼對比校驗
      return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
    }
    return null;
  }
 
  /**
   * 權限認證
   * 獲取用戶的權限信息,這是為下一步的授權做判斷,獲取當前用戶的角色和這些角色所擁有的權限信息
   * @param principalCollection
   * @return
   */
  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    //獲取當前登錄輸入的用戶名,等價于(String) principalCollection.fromRealm(getName()).iterator().next();
//    String loginName = (String) super.getAvailablePrincipal(principalCollection);
    UserDo user = (UserDo) principalCollection.getPrimaryPrincipal();
//    //到數據庫查是否有此對象
//    User user = null;// 實際項目中,這里可以根據實際情況做緩存,如果不做,Shiro自己也是有時間間隔機制,2分鐘內不會重復執行該方法
//    user = userMapper.findByName(loginName);
    if (user != null) {
      //權限信息對象info,用來存放查出的用戶的所有的角色(role)及權限(permission)
      SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
      //用戶的角色集合
      info.addRoles(user.getRoleStrlist());
      //用戶的權限集合
      info.addStringPermissions(user.getPerminsStrlist());
 
      return info;
    }
    // 返回null的話,就會導致任何用戶訪問被攔截的請求時,都會自動跳轉到unauthorizedUrl指定的地址
    return null;
  }
}

4 . 最后看一下ehcache的配置文件

?
1
2
3
4
5
6
7
8
9
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
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
  updateCheck="false">
  <diskStore path="java.io.tmpdir/Tmp_EhCache" /> 
  <!--
    name:緩存名稱。
    maxElementsInMemory:緩存最大數目
    maxElementsOnDisk:硬盤最大緩存個數。
    eternal:對象是否永久有效,一但設置了,timeout將不起作用。
    overflowToDisk:是否保存到磁盤,當系統當機時
    timeToIdleSeconds:設置對象在失效前的允許閑置時間(單位:秒)。僅當eternal=false對象不是永久有效時使用,可選屬性,默認值是0,也就是可閑置時間無窮大。
    timeToLiveSeconds:設置對象在失效前允許存活時間(單位:秒)。最大時間介于創建時間和失效時間之間。僅當eternal=false對象不是永久有效時使用,默認是0.,也就是對象存活時間無窮大。
    diskPersistent:是否緩存虛擬機重啟期數據 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
    diskSpoolBufferSizeMB:這個參數設置DiskStore(磁盤緩存)的緩存區大小。默認是30MB。每個Cache都應該有自己的一個緩沖區。
    diskExpiryThreadIntervalSeconds:磁盤失效線程運行時間間隔,默認是120秒。
    memoryStoreEvictionPolicy:當達到maxElementsInMemory限制時,Ehcache將會根據指定的策略去清理內存。默認策略是LRU(最近最少使用)。你可以設置為FIFO(先進先出)或是LFU(較少使用)。
    clearOnFlush:內存數量最大時是否清除。
     memoryStoreEvictionPolicy:
      Ehcache的三種清空策略;
      FIFO,first in first out,這個是大家最熟的,先進先出。
      LFU, Less Frequently Used,就是上面例子中使用的策略,直白一點就是講一直以來最少被使用的。如上面所講,緩存的元素有一個hit屬性,hit值最小的將會被清出緩存。
      LRU,Least Recently Used,最近最少使用的,緩存的元素有一個時間戳,當緩存容量滿了,而又需要騰出地方來緩存新的元素的時候,那么現有緩存元素中時間戳離當前時間最遠的元素將被清出緩存。
  -->
 
  <defaultCache eternal="false" maxElementsInMemory="1000"
    overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0"
    timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU" />
  <!-- 登錄記錄緩存鎖定10分鐘 -->
  <cache name="passwordRetryCache"
      maxEntriesLocalHeap="2000"
      eternal="false"
      timeToIdleSeconds="3600"
      timeToLiveSeconds="0"
      overflowToDisk="false"
      statistics="true">
  </cache>
</ehcache>

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:http://blog.csdn.net/xingbaozhen1210/article/details/79470255

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 欧美日韩成人一区二区 | 欧美日韩一区二 | 午夜精品久久久久久久久久久久 | 久久九九国产精品 | 另类五月 | 国产成人精品一区二区三区视频 | 欧美高清com | 激情欧美一区二区三区中文字幕 | 亚洲一区二区久久 | 天天操天天干天天插 | 色噜噜狠狠一区二区三区狼国成人 | 精品一区二区三区四区五区 | 精品国产子伦久久久久久小说 | 一级黄色大片 | 97精品超碰一区二区三区 | 91性高湖久久久久久久久网站 | 不卡一区| 视频四区 | 欧美黄色一区 | 国产一区二区精品 | 国产亚洲精品久久久久久久久 | 性大毛片视频 | 日韩欧美精品一区二区 | 一区二区三区在线免费观看 | 日本天天色 | 亚洲精品a在线观看 | 午夜免费视频 | 97精品一区二区 | 亚洲精品福利 | 在线观看中文字幕 | 9191国产视频 | 中文免费字幕 | 婷婷综合久久 | 日韩国产一区二区三区 | 成人h视频 | 精品一区二区三区在线观看 | 中文字幕成人在线 | 中文字幕一区二区三区在线视频 | 亚洲三级在线 | 成人网址在线观看 | 成人午夜精品一区二区三区 |