CAS 5.3.1系列之自定義Shiro認證策略(四)

      網友投稿 791 2025-04-01

      CAS 5.3.1系列之自定義Shiro認證策略(四)

      CAS官方文檔是介紹基于配置實現shiro認證的,可以參考官方文檔,不過我們也可以通過自定義認證策略的方式實現jdbc認證,pom先加入相關jar

      org.apereo.cas cas-server-core-authentication-api ${cas.version} org.apereo.cas cas-server-core-configuration-api ${cas.version} org.apereo.cas cas-server-support-generic ${cas.version}

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      如果要用公網提供的基于配置實現的,需要加入:

      org.apereo.cas cas-server-support-shiro-authentication ${cas.version}

      1

      2

      3

      4

      5

      6

      要自定義shiroRealm的,加入shiro相關jar:

      org.apache.shiro shiro-spring 1.4.0

      1

      2

      3

      4

      5

      實現一個Shiro Realm類,僅供參考:

      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.apache.shiro.subject.Subject; import org.muses.jeeplatform.cas.user.model.User; import org.muses.jeeplatform.cas.user.service.UserService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DriverManagerDataSource; /** *

       * * 
      * *
       * @author mazq * 修改記錄 * 修改后版本: 修改人: 修改日期: 2020/04/26 11:33 修改內容: * 
      */ public class ShiroAuthorizingRealm extends AuthorizingRealm { Logger LOG = LoggerFactory.getLogger(ShiroAuthorizingRealm.class); /**注解引入業務類**/ //@Autowired //UserService userService; /** * 登錄信息和用戶驗證信息驗證(non-Javadoc) * @see org.apache.shiro.realm.AuthenticatingRealm#doGetAuthenticationInfo(AuthenticationToken) */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String username = (String)token.getPrincipal(); //得到用戶名 String password = new String((char[])token.getCredentials()); //得到密碼 LOG.info("Shiro doGetAuthenticationInfo>> username:{},password:{}",username,password); //User user = userService.findByUsername(username); // JDBC模板依賴于連接池來獲得數據的連接,所以必須先要構造連接池 DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://192.168.0.152:33306/jeeplatform"); dataSource.setUsername("root"); dataSource.setPassword("minstone"); // 創建JDBC模板 JdbcTemplate jdbcTemplate = new JdbcTemplate(); jdbcTemplate.setDataSource(dataSource); String sql = "SELECT * FROM sys_user WHERE username = ?"; User user = (User) jdbcTemplate.queryForObject(sql, new Object[]{username}, new BeanPropertyRowMapper(User.class)); Subject subject = getCurrentExecutingSubject(); //獲取Shiro管理的Session Session session = getShiroSession(subject); //Shiro添加會話 session.setAttribute("username", username); session.setAttribute(ShiroConsts.SESSION_USER, user); /**檢測是否有此用戶 **/ if(user == null){ throw new UnknownAccountException();//沒有找到賬號異常 } /**檢驗賬號是否被鎖定 **/ if(Boolean.TRUE.equals(user.getLocked())){ throw new LockedAccountException();//拋出賬號鎖定異常 } /**AuthenticatingRealm使用CredentialsMatcher進行密碼匹配**/ if(null != username && null != password){ return new SimpleAuthenticationInfo(username, password, getName()); }else{ return null; } } /** * 授權查詢回調函數, 進行鑒權但緩存中無用戶的授權信息時調用,負責在應用程序中決定用戶的訪問控制的方法(non-Javadoc) * @see AuthorizingRealm#doGetAuthorizationInfo(PrincipalCollection) */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) { String username = (String)pc.getPrimaryPrincipal(); SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); // authorizationInfo.setRoles(userService.getRoles(username)); // authorizationInfo.setStringPermissions(userService.getPermissions(username)); System.out.println("Shiro授權"); return authorizationInfo; } @Override public void clearCachedAuthorizationInfo(PrincipalCollection principals) { super.clearCachedAuthorizationInfo(principals); } @Override public void clearCachedAuthenticationInfo(PrincipalCollection principals) { super.clearCachedAuthenticationInfo(principals); } @Override public void clearCache(PrincipalCollection principals) { super.clearCache(principals); } protected Subject getCurrentExecutingSubject(){ return SecurityUtils.getSubject(); } protected Session getShiroSession(Subject subject){ return subject.getSession(); } }

      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

      CAS 5.3.1系列之自定義Shiro認證策略(四)

      114

      115

      116

      117

      118

      119

      120

      121

      122

      123

      124

      125

      126

      127

      128

      自定義授權handler類實現AbstractUsernamePasswordAuthenticationHandler抽象類:

      package org.muses.jeeplatform.cas.authentication.handler; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.*; import org.apache.shiro.session.Session; import org.apache.shiro.subject.Subject; import org.apereo.cas.authentication.*; import org.apereo.cas.authentication.AuthenticationException; import org.apereo.cas.authentication.exceptions.AccountDisabledException; import org.apereo.cas.authentication.handler.support.AbstractPreAndPostProcessingAuthenticationHandler; import org.apereo.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler; import org.apereo.cas.authentication.principal.PrincipalFactory; import org.apereo.cas.services.ServicesManager; import javax.security.auth.login.AccountLockedException; import javax.security.auth.login.AccountNotFoundException; import javax.security.auth.login.CredentialExpiredException; import javax.security.auth.login.FailedLoginException; import java.security.GeneralSecurityException; /** *

       * * 
      * *
       * @author mazq * 修改記錄 * 修改后版本: 修改人: 修改日期: 2020/04/26 11:03 修改內容: * 
      */ public class ShiroAuthenticationHandler extends AbstractUsernamePasswordAuthenticationHandler { public ShiroAuthenticationHandler(String name, ServicesManager servicesManager, PrincipalFactory principalFactory, Integer order) { super(name, servicesManager, principalFactory, order); } @Override protected AuthenticationHandlerExecutionResult authenticateUsernamePasswordInternal(UsernamePasswordCredential credential, String originalPassword) throws GeneralSecurityException, PreventedException { try { UsernamePasswordToken token = new UsernamePasswordToken(credential.getUsername(), credential.getPassword()); if (credential instanceof RememberMeUsernamePasswordCredential) { token.setRememberMe(RememberMeUsernamePasswordCredential.class.cast(credential).isRememberMe()); } Subject subject = getCurrentExecutingSubject(); subject.login(token); //獲取Shiro管理的Session //Session session = getShiroSession(subject); final String username = subject.getPrincipal().toString(); return createHandlerResult(credential, this.principalFactory.createPrincipal(username)); } catch (final UnknownAccountException uae) { throw new AccountNotFoundException(uae.getMessage()); } catch (final IncorrectCredentialsException ice) { throw new FailedLoginException(ice.getMessage()); } catch (final LockedAccountException | ExcessiveAttemptsException lae) { throw new AccountLockedException(lae.getMessage()); } catch (final ExpiredCredentialsException eae) { throw new CredentialExpiredException(eae.getMessage()); } catch (final DisabledAccountException eae) { throw new AccountDisabledException(eae.getMessage()); } catch (final AuthenticationException e) { throw new FailedLoginException(e.getMessage()); } } protected Subject getCurrentExecutingSubject(){ return SecurityUtils.getSubject(); } protected Session getShiroSession(Subject subject){ return subject.getSession(); } @Override public boolean supports(Credential credential) { return false; } }

      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

      同理實現一個Shiro配置類:

      package org.muses.jeeplatform.cas.authentication.config; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.apereo.cas.authentication.AuthenticationEventExecutionPlan; import org.apereo.cas.authentication.AuthenticationEventExecutionPlanConfigurer; import org.apereo.cas.authentication.AuthenticationHandler; import org.apereo.cas.authentication.PrePostAuthenticationHandler; import org.apereo.cas.authentication.principal.DefaultPrincipalFactory; import org.apereo.cas.configuration.CasConfigurationProperties; import org.apereo.cas.services.ServicesManager; import org.muses.jeeplatform.cas.authentication.handler.ShiroAuthenticationHandler; import org.muses.jeeplatform.cas.authentication.handler.UsernamePasswordAuthenticationHandler; import org.muses.jeeplatform.cas.authentication.shiro.ShiroAuthorizingRealm; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.config.MethodInvokingFactoryBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.LinkedHashMap; import java.util.Map; /** *

       * * 
      * *
       * @author mazq * 修改記錄 * 修改后版本: 修改人: 修改日期: 2020/04/26 16:35 修改內容: * 
      */ @Configuration("ShiroAuthenticationConfiguration") @EnableConfigurationProperties(CasConfigurationProperties.class) public class ShiroAuthenticationConfiguration implements AuthenticationEventExecutionPlanConfigurer { @Autowired private CasConfigurationProperties casProperties; @Autowired @Qualifier("servicesManager") private ServicesManager servicesManager; //@Bean public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); //-. Map filterChainDefinitionMap = new LinkedHashMap<>(); // 配置不會被攔截的鏈接 順序判斷 filterChainDefinitionMap.put("/static/**", "anon"); filterChainDefinitionMap.put("/upload/**", "anon"); filterChainDefinitionMap.put("/plugins/**", "anon"); filterChainDefinitionMap.put("/code", "anon"); filterChainDefinitionMap.put("/login", "anon"); filterChainDefinitionMap.put("/logincheck", "anon"); filterChainDefinitionMap.put("/**", "authc"); shiroFilterFactoryBean.setLoginUrl("/login"); shiroFilterFactoryBean.setSuccessUrl("/index"); shiroFilterFactoryBean.setUnauthorizedUrl("/login"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } @Bean public ShiroAuthorizingRealm shiroAuthorizingRealm(){ ShiroAuthorizingRealm myShiroRealm = new ShiroAuthorizingRealm(); //myShiroRealm.setCachingEnabled(false); //啟用身份驗證緩存,即緩存AuthenticationInfo信息,默認false myShiroRealm.setAuthenticationCachingEnabled(false); //啟用授權緩存,即緩存AuthorizationInfo信息,默認false myShiroRealm.setAuthorizationCachingEnabled(false); return myShiroRealm; } @Bean public SecurityManager securityManager(){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(shiroAuthorizingRealm()); return securityManager; } /** * Spring靜態注入 * @return */ @Bean public MethodInvokingFactoryBean getMethodInvokingFactoryBean(){ MethodInvokingFactoryBean factoryBean = new MethodInvokingFactoryBean(); factoryBean.setStaticMethod("org.apache.shiro.SecurityUtils.setSecurityManager"); factoryBean.setArguments(new Object[]{securityManager()}); return factoryBean; } @Bean public AuthenticationHandler myAuthenticationHandler() { return new ShiroAuthenticationHandler(ShiroAuthenticationHandler.class.getName(), servicesManager, new DefaultPrincipalFactory(), 1); } @Override public void configureAuthenticationExecutionPlan(AuthenticationEventExecutionPlan plan) { plan.registerAuthenticationHandler(myAuthenticationHandler()); } }

      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

      在META-INF文件夾,新增一個命名為spring.factories的文件

      org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.muses.jeeplatform.cas.authentication.config.ShiroAuthenticationConfiguration

      1

      2

      3

      為什么要這樣做?因為這樣做才能將配置類加載到spring容器,詳情需要跟下源碼,可以參考我博客:SpringBoot源碼學習系列之自動配置原理簡介

      代碼例子參考:github下載鏈接

      詳情可以參考官方文檔:https://apereo.github.io/cas/5.3.x/installation/Configuration-Properties.html

      優質參考博客:

      https://www.cnblogs.com/jpeanut/tag/CAS/

      https://blog.csdn.net/anumbrella/category_7765386.html

      Spring

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:wps如何制作表格(wps如何制作表格并且打印出來是表格形式)
      下一篇:FusionInsight MRS配置機架策略最佳實踐
      相關文章
      亚洲一区二区三区不卡在线播放 | 亚洲精品无码99在线观看 | 91亚洲国产成人久久精品网站| 在线观看亚洲天天一三视| 亚洲AV无码片一区二区三区| 亚洲中文字幕久久精品蜜桃| 中文字幕乱码亚洲精品一区| 亚洲毛片基地4455ww| 亚洲中文字幕一二三四区苍井空| 亚洲中文字幕久久精品无码2021| 亚洲国产精品成人精品软件 | 亚洲精品亚洲人成在线观看下载| 日韩精品成人亚洲专区| 亚洲色欲色欱wwW在线| 亚洲日本久久一区二区va| 国产成人精品日本亚洲专一区| 亚洲一区免费在线观看| 亚洲人成网站色在线观看| 国内精品久久久久影院亚洲| 在线亚洲午夜片AV大片| 亚洲一线产品二线产品| 亚洲国产精品成人午夜在线观看 | 亚洲最大的成人网站| 亚洲精品美女久久7777777| 亚洲av无码有乱码在线观看| 婷婷亚洲综合五月天小说在线 | 亚洲AV无码第一区二区三区| 亚洲国产香蕉碰碰人人| 亚洲精品电影天堂网| 亚洲一卡2卡4卡5卡6卡在线99 | 亚洲成a人片在线观看日本| 亚洲精品免费视频| 亚洲综合激情另类小说区| 亚洲一级毛片在线播放| 亚洲色欲啪啪久久WWW综合网| 337P日本欧洲亚洲大胆精品| 亚洲美女在线国产| 亚洲精品国产精品乱码不99 | 亚洲精品99久久久久中文字幕| 亚洲综合精品网站| 久久久久亚洲精品成人网小说|