一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

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

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

服務器之家 - 編程語言 - Java教程 - 詳解Spring Boot 集成Shiro和CAS

詳解Spring Boot 集成Shiro和CAS

2020-10-05 14:39catoop Java教程

這篇文章主要介紹了詳解Spring Boot 集成Shiro和CAS,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

請大家在看本文之前,先了解如下知識點:

1、Shiro 是什么?怎么用?

2、Cas 是什么?怎么用?

3、最好有spring基礎

首先看一下下面這張圖:

第一個流程是單純使用Shiro的流程。

第二個流程是單純使用Cas的流程。

第三個圖是Shiro集成Cas后的流程。

詳解Spring Boot 集成Shiro和CAS

PS:流程圖急急忙忙畫的,整體上應該沒有什么問題,具體細節問題還請大家留言指正。

如果你只是打算用到你的Spring Boot項目中,那么看著如下配置完成便可。

如果你想進一步了解其中的細節,還是建議大家單獨配置Shiro、單獨配置Cas,看看官方相關文檔。

Shiro在1.2版本開始提供了對cas的集成,按下面添加依賴到pom.xml中:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!--Apache Shiro所需的jar包 -->
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-spring</artifactId>
  <version>1.2.4</version>
</dependency>
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-ehcache</artifactId>
  <version>1.2.4</version>
</dependency>
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-cas</artifactId>
  <version>1.2.4</version>
</dependency>

shiro-cas 依賴 shiro-web,shiro-web 依賴 shiro-core,所以添加shiro-cas后shiro-web.jar和shiro-core.jar會自動被引用。
cas被shiro集成后,其原理就是shiro將casFilter加入到shiroFilter的filterChain中。

在SpringBoot工程中創建ShiroCasConfiguration.Java

?
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
package org.springboot.sample.config;
 
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
 
import javax.servlet.Filter;
 
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.cas.CasFilter;
import org.apache.shiro.cas.CasSubjectFactory;
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.DefaultWebSecurityManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springboot.sample.dao.IScoreDao;
import org.springboot.sample.security.MyShiroCasRealm;
import org.springboot.sample.service.StudentService;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.DelegatingFilterProxy;
 
/**
 * Shiro集成Cas配置
 *
 * @author  單紅宇(365384722)
 * @create  2016年1月17日
 */
@Configuration
public class ShiroCasConfiguration {
 
  private static final Logger logger = LoggerFactory.getLogger(ShiroCasConfiguration.class);
 
  // CasServerUrlPrefix
  public static final String casServerUrlPrefix = "https://localhost:8443/cas";
  // Cas登錄頁面地址
  public static final String casLoginUrl = casServerUrlPrefix + "/login";
  // Cas登出頁面地址
  public static final String casLogoutUrl = casServerUrlPrefix + "/logout";
  // 當前工程對外提供的服務地址
  public static final String shiroServerUrlPrefix = "http://localhost:9090/myspringboot";
  // casFilter UrlPattern
  public static final String casFilterUrlPattern = "/shiro-cas";
  // 登錄地址
  public static final String loginUrl = casLoginUrl + "?service=" + shiroServerUrlPrefix + casFilterUrlPattern;
 
  @Bean
  public EhCacheManager getEhCacheManager() {
    EhCacheManager em = new EhCacheManager();
    em.setCacheManagerConfigFile("classpath:ehcache-shiro.xml");
    return em;
  }
 
  @Bean(name = "myShiroCasRealm")
  public MyShiroCasRealm myShiroCasRealm(EhCacheManager cacheManager) {
    MyShiroCasRealm realm = new MyShiroCasRealm();
    realm.setCacheManager(cacheManager);
    return realm;
  }
 
  /**
   * 注冊DelegatingFilterProxy(Shiro)
   *
   * @param dispatcherServlet
   * @return
   * @author SHANHY
   * @create 2016年1月13日
   */
  @Bean
  public FilterRegistrationBean filterRegistrationBean() {
    FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
    filterRegistration.setFilter(new DelegatingFilterProxy("shiroFilter"));
    // 該值缺省為false,表示生命周期由SpringApplicationContext管理,設置為true則表示由ServletContainer管理
    filterRegistration.addInitParameter("targetFilterLifecycle", "true");
    filterRegistration.setEnabled(true);
    filterRegistration.addUrlPatterns("/*");
    return filterRegistration;
  }
 
  @Bean(name = "lifecycleBeanPostProcessor")
  public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
    return new LifecycleBeanPostProcessor();
  }
 
  @Bean
  public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
    DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
    daap.setProxyTargetClass(true);
    return daap;
  }
 
  @Bean(name = "securityManager")
  public DefaultWebSecurityManager getDefaultWebSecurityManager(MyShiroCasRealm myShiroCasRealm) {
    DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager();
    dwsm.setRealm(myShiroCasRealm);
//   <!-- 用戶授權/認證信息Cache, 采用EhCache 緩存 -->
    dwsm.setCacheManager(getEhCacheManager());
    // 指定 SubjectFactory
    dwsm.setSubjectFactory(new CasSubjectFactory());
    return dwsm;
  }
 
  @Bean
  public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
    AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
    aasa.setSecurityManager(securityManager);
    return aasa;
  }
 
  /**
   * 加載shiroFilter權限控制規則(從數據庫讀取然后配置)
   *
   * @author SHANHY
   * @create 2016年1月14日
   */
  private void loadShiroFilterChain(ShiroFilterFactoryBean shiroFilterFactoryBean, StudentService stuService, IScoreDao scoreDao){
    /////////////////////// 下面這些規則配置最好配置到配置文件中 ///////////////////////
    Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
 
    filterChainDefinitionMap.put(casFilterUrlPattern, "casFilter");// shiro集成cas后,首先添加該規則
 
    // authc:該過濾器下的頁面必須驗證后才能訪問,它是Shiro內置的一個攔截器org.apache.shiro.web.filter.authc.FormAuthenticationFilter
    filterChainDefinitionMap.put("/user", "authc");// 這里為了測試,只限制/user,實際開發中請修改為具體攔截的請求規則
    // anon:它對應的過濾器里面是空的,什么都沒做
    logger.info("##################從數據庫讀取權限規則,加載到shiroFilter中##################");
    filterChainDefinitionMap.put("/user/edit/**", "authc,perms[user:edit]");// 這里為了測試,固定寫死的值,也可以從數據庫或其他配置中讀取
 
    filterChainDefinitionMap.put("/login", "anon");
    filterChainDefinitionMap.put("/**", "anon");//anon 可以理解為不攔截
 
    shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
  }
 
  /**
   * CAS過濾器
   *
   * @return
   * @author SHANHY
   * @create 2016117
   */
  @Bean(name = "casFilter")
  public CasFilter getCasFilter() {
    CasFilter casFilter = new CasFilter();
    casFilter.setName("casFilter");
    casFilter.setEnabled(true);
    // 登錄失敗后跳轉的URL,也就是 Shiro 執行 CasRealm 的 doGetAuthenticationInfo 方法向CasServer驗證tiket
    casFilter.setFailureUrl(loginUrl);// 我們選擇認證失敗后再打開登錄頁面
    return casFilter;
  }
 
  /**
   * ShiroFilter<br/>
   * 注意這里參數中的 StudentService 和 IScoreDao 只是一個例子,因為我們在這里可以用這樣的方式獲取到相關訪問數據庫的對象,
   * 然后讀取數據庫相關配置,配置到 shiroFilterFactoryBean 的訪問規則中。實際項目中,請使用自己的Service來處理業務邏輯。
   *
   * @param myShiroCasRealm
   * @param stuService
   * @param scoreDao
   * @return
   * @author SHANHY
   * @create 2016年1月14日
   */
  @Bean(name = "shiroFilter")
  public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager, CasFilter casFilter, StudentService stuService, IScoreDao scoreDao) {
    ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    // 必須設置 SecurityManager
    shiroFilterFactoryBean.setSecurityManager(securityManager);
    // 如果不設置默認會自動尋找Web工程根目錄下的"/login.jsp"頁面
    shiroFilterFactoryBean.setLoginUrl(loginUrl);
    // 登錄成功后要跳轉的連接
    shiroFilterFactoryBean.setSuccessUrl("/user");
    shiroFilterFactoryBean.setUnauthorizedUrl("/403");
    // 添加casFilter到shiroFilter中
    Map<String, Filter> filters = new HashMap<>();
    filters.put("casFilter", casFilter);
    shiroFilterFactoryBean.setFilters(filters);
 
    loadShiroFilterChain(shiroFilterFactoryBean, stuService, scoreDao);
    return shiroFilterFactoryBean;
  }
 
}

創建權限認證的 MyShiroCasRealm.java

?
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
package org.springboot.sample.security;
 
import java.util.List;
 
import javax.annotation.PostConstruct;
 
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cas.CasRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springboot.sample.config.ShiroCasConfiguration;
import org.springboot.sample.dao.IUserDao;
import org.springboot.sample.entity.Role;
import org.springboot.sample.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
public class MyShiroCasRealm extends CasRealm{
 
  private static final Logger logger = LoggerFactory.getLogger(MyShiroCasRealm.class);
 
  @Autowired
  private IUserDao userDao;
 
  @PostConstruct
  public void initProperty(){
//   setDefaultRoles("ROLE_USER");
    setCasServerUrlPrefix(ShiroCasConfiguration.casServerUrlPrefix);
    // 客戶端回調地址
    setCasService(ShiroCasConfiguration.shiroServerUrlPrefix + ShiroCasConfiguration.casFilterUrlPattern);
  }
 
  /**
   * 權限認證,為當前登錄的Subject授予角色和權限
   * @see 經測試:本例中該方法的調用時機為需授權資源被訪問時
   * @see 經測試:并且每次訪問需授權資源時都會執行該方法中的邏輯,這表明本例中默認并未啟用AuthorizationCache
   * @see 經測試:如果連續訪問同一個URL(比如刷新),該方法不會被重復調用,Shiro有一個時間間隔(也就是cache時間,在ehcache-shiro.xml中配置),超過這個時間間隔再刷新頁面,該方法會被執行
   */
  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    logger.info("##################執行Shiro權限認證##################");
    //獲取當前登錄輸入的用戶名,等價于(String) principalCollection.fromRealm(getName()).iterator().next();
    String loginName = (String)super.getAvailablePrincipal(principalCollection);
    //到數據庫查是否有此對象
    User user=userDao.findByName(loginName);// 實際項目中,這里可以根據實際情況做緩存,如果不做,Shiro自己也是有時間間隔機制,2分鐘內不會重復執行該方法
    if(user!=null){
      //權限信息對象info,用來存放查出的用戶的所有的角色(role)及權限(permission)
      SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
      //用戶的角色集合
      info.setRoles(user.getRolesName());
      //用戶的角色對應的所有權限,如果只使用角色定義訪問權限,下面的四行可以不要
      List<Role> roleList=user.getRoleList();
      for (Role role : roleList) {
        info.addStringPermissions(role.getPermissionsName());
      }
      // 或者按下面這樣添加
      //添加一個角色,不是配置意義上的添加,而是證明該用戶擁有admin角色 
//      simpleAuthorInfo.addRole("admin");
      //添加權限
//      simpleAuthorInfo.addStringPermission("admin:manage");
//      logger.info("已為用戶[mike]賦予了[admin]角色和[admin:manage]權限");
      return info;
    }
    // 返回null的話,就會導致任何用戶訪問被攔截的請求時,都會自動跳轉到unauthorizedUrl指定的地址
    return null;
  }
 
}
 
在Controller中添加一個方法,用于將登錄URL簡單化,提供一個重定向功能
 
 
  @RequestMapping(value="/login",method=RequestMethod.GET)
  public String loginForm(Model model){
    model.addAttribute("user", new User());
//   return "login";
    return "redirect:" + ShiroCasConfiguration.loginUrl;
  }

本文主要是介紹如何在Spring Boot中集成Shiro+Cas,并非一個從零創建工程到整體完成的介紹。

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

原文鏈接:http://blog.csdn.net/catoop/article/details/50534006

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 青青在线香蕉国产精品 | 亚洲人成在线播放 | 日本xxx在线观看免费播放 | 色啊色| 国产欧美综合精品一区二区 | 99视频福利 | 亚洲品质自拍视频 | 国产日韩欧美综合在线 | 国产精品一区二区不卡的视频 | 日本黄色高清视频网站 | 国产视频二区 | 太大了轻点阿受不了小说h 四色6677最新永久网站 | 精品午夜寂寞影院在线观看 | 亚洲精品综合网 | 亚洲国产精品一区二区三区久久 | 精品成人一区二区三区免费视频 | 欧美四区 | 亚洲日韩精品欧美一区二区 | 免费一区在线观看 | 被强上后我成瘾了小说 | 色综色天天综合网 | 俄罗斯美女破苞 | 幻女free性zoz0交 | 国产九九在线 | 美女翘臀跪床被打屁股作文 | 91人人在线 | 91九色麻豆 | 动漫美女被吸乳羞羞小说 | 精品综合在线 | 四虎最新紧急更新地址 | 欧美1| 亚洲va精品中文字幕 | 国产精品林美惠子在线观看 | 久久视频这只精品99re6 | 门房秦大爷最新章节阅读 | 欧美特欧美特级一片 | 青柠影视在线播放观看高清 | 欧美视频一区二区三区四区 | 合欢视频免费 | 国产在线看片网站 | 欧美性一级交视频 |