国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Spring Boot [集成-Shiro]

gclove / 1065人閱讀

摘要:后面的文章將圍繞著集成來進(jìn)行展開。表示當(dāng)前已經(jīng)身份驗證或者通過記住我登錄的。表示當(dāng)前需要角色和。參考資料系列十五安全框架一基本功能權(quán)限管理學(xué)習(xí)資料使用手冊跟開濤學(xué)博客版跟開濤學(xué)版官方文檔

導(dǎo)讀:

在閱讀這篇文章之前假設(shè)你已經(jīng)對Apache Shiro(后面統(tǒng)一用Shiro作為代指)有了一定的了解,如果你還對Shiro不熟悉的話在這篇文章的結(jié)尾附有相關(guān)的學(xué)習(xí)資料,關(guān)于Shiro是用來做什么的這里有個不錯的介紹,在后面的文章中就不在對其進(jìn)行描述了。后面的文章將圍繞著 Spring Boot 集成Shiro 來進(jìn)行展開。

快速上手: 1.引入pom依賴

</>復(fù)制代碼

  1. org.apache.shiro
  2. shiro-spring
  3. 1.2.5
2.實(shí)現(xiàn)相關(guān)的 用戶,角色,權(quán)限等代碼的編寫:

由于篇幅原因這里不進(jìn)行展開 提供一個參考

3.實(shí)現(xiàn)Realm:

AbstractUserRealm繼承AuthorizingRealm,并重寫doGetAuthorizationInfo(用于獲取認(rèn)證成功后的角色、權(quán)限等信息) 和 doGetAuthenticationInfo(驗證當(dāng)前登錄的Subject)方法:

</>復(fù)制代碼

  1. public abstract class AbstractUserRealm extends AuthorizingRealm {
  2. private static final Logger logger = LoggerFactory.getLogger(AbstractUserRealm.class);
  3. @Autowired
  4. private UserRepository userRepository;
  5. //獲取用戶組的權(quán)限信息
  6. public abstract UserRolesAndPermissions doGetGroupAuthorizationInfo(User userInfo);
  7. //獲取用戶角色的權(quán)限信息
  8. public abstract UserRolesAndPermissions doGetRoleAuthorizationInfo(User userInfo);
  9. /**
  10. * 獲取授權(quán)信息
  11. */
  12. @Override
  13. protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
  14. String currentLoginName = (String) principals.getPrimaryPrincipal();
  15. Set userRoles = new HashSet<>();
  16. Set userPermissions = new HashSet<>();
  17. //從數(shù)據(jù)庫中獲取當(dāng)前登錄用戶的詳細(xì)信息
  18. User userInfo = userRepository.findByLoginName(currentLoginName);
  19. if (null != userInfo) {
  20. UserRolesAndPermissions groupContainer = doGetGroupAuthorizationInfo(userInfo);
  21. UserRolesAndPermissions roleContainer = doGetGroupAuthorizationInfo(userInfo);
  22. userRoles.addAll(groupContainer.getUserRoles());
  23. userRoles.addAll(roleContainer.getUserRoles());
  24. userPermissions.addAll(groupContainer.getUserPermissions());
  25. userPermissions.addAll(roleContainer.getUserPermissions());
  26. } else {
  27. throw new AuthorizationException();
  28. }
  29. //為當(dāng)前用戶設(shè)置角色和權(quán)限
  30. SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
  31. authorizationInfo.addRoles(userRoles);
  32. authorizationInfo.addStringPermissions(userPermissions);
  33. logger.info("###【獲取角色成功】[SessionId] => {}", SecurityUtils.getSubject().getSession().getId());
  34. return authorizationInfo;
  35. }
  36. /**
  37. * 登錄認(rèn)證
  38. */
  39. @Override
  40. protected AuthenticationInfo doGetAuthenticationInfo(
  41. AuthenticationToken authenticationToken) throws AuthenticationException {
  42. //UsernamePasswordToken對象用來存放提交的登錄信息
  43. UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
  44. //查出是否有此用戶
  45. User user = userRepository.findByLoginName(token.getUsername());
  46. if (user != null) {
  47. // 若存在,將此用戶存放到登錄認(rèn)證info中,無需自己做密碼對比,Shiro會為我們進(jìn)行密碼對比校驗
  48. return new SimpleAuthenticationInfo(user.getLoginName(), user.getPassword(), getName());
  49. }
  50. return null;
  51. }
  52. protected class UserRolesAndPermissions {
  53. Set userRoles;
  54. Set userPermissions;
  55. public UserRolesAndPermissions(Set userRoles, Set userPermissions) {
  56. this.userRoles = userRoles;
  57. this.userPermissions = userPermissions;
  58. }
  59. public Set getUserRoles() {
  60. return userRoles;
  61. }
  62. public Set getUserPermissions() {
  63. return userPermissions;
  64. }
  65. }

</>復(fù)制代碼

  1. @Component
  2. public class UserRealm extends AbstractUserRealm {
  3. @Override
  4. public UserRolesAndPermissions doGetGroupAuthorizationInfo(User userInfo) {
  5. Set userRoles = new HashSet<>();
  6. Set userPermissions = new HashSet<>();
  7. //TODO 獲取當(dāng)前用戶下?lián)碛械乃薪巧斜?及權(quán)限
  8. return new UserRolesAndPermissions(userRoles, userPermissions);
  9. }
  10. @Override
  11. public UserRolesAndPermissions doGetRoleAuthorizationInfo(User userInfo) {
  12. Set userRoles = new HashSet<>();
  13. Set userPermissions = new HashSet<>();
  14. //TODO 獲取當(dāng)前用戶下?lián)碛械乃薪巧斜?及權(quán)限
  15. return new UserRolesAndPermissions(userRoles, userPermissions);
  16. }
  17. }
4.創(chuàng)建Shiro配置類:

這是最重要的一步等價于常規(guī)的Spring web應(yīng)用的配置文件,將相關(guān)的配置托管給Spring 管理。

</>復(fù)制代碼

  1. @Configuration
  2. public class ShiroConfiguration {
  3. private static final Logger logger = LoggerFactory.getLogger(ShiroConfiguration.class);
  4. /**
  5. * Shiro的Web過濾器Factory 命名:shiroFilter
    * * @param securityManager * @return
  6. */
  7. @Bean(name = "shiroFilter")
  8. public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
  9. logger.info("注入Shiro的Web過濾器-->shiroFilter", ShiroFilterFactoryBean.class);
  10. ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
  11. //Shiro的核心安全接口,這個屬性是必須的
  12. shiroFilterFactoryBean.setSecurityManager(securityManager);
  13. //要求登錄時的鏈接(可根據(jù)項目的URL進(jìn)行替換),非必須的屬性,默認(rèn)會自動尋找Web工程根目錄下的"/login.jsp"頁面
  14. shiroFilterFactoryBean.setLoginUrl("/login");
  15. //登錄成功后要跳轉(zhuǎn)的連接,邏輯也可以自定義,例如返回上次請求的頁面
  16. shiroFilterFactoryBean.setSuccessUrl("/index");
  17. //用戶訪問未對其授權(quán)的資源時,所顯示的連接
  18. shiroFilterFactoryBean.setUnauthorizedUrl("/403");
  19. /*定義shiro過濾器,例如實(shí)現(xiàn)自定義的FormAuthenticationFilter,需要繼承FormAuthenticationFilter **本例中暫不自定義實(shí)現(xiàn),在下一節(jié)實(shí)現(xiàn)驗證碼的例子中體現(xiàn) */
  20. /*定義shiro過濾鏈 Map結(jié)構(gòu) * Map中key(xml中是指value值)的第一個"/"代表的路徑是相對于HttpServletRequest.getContextPath()的值來的 * anon:它對應(yīng)的過濾器里面是空的,什么都沒做,這里.do和.jsp后面的*表示參數(shù),比方說login.jsp?main這種 * authc:該過濾器下的頁面必須驗證后才能訪問,它是Shiro內(nèi)置的一個攔截器org.apache.shiro.web.filter.authc.FormAuthenticationFilter */
  21. Map filterChainDefinitionMap = new LinkedHashMap();
  22. // 配置退出過濾器,其中的具體的退出代碼Shiro已經(jīng)替我們實(shí)現(xiàn)了
  23. filterChainDefinitionMap.put("/logout", "logout");
  24. // :這是一個坑呢,一不小心代碼就不好使了;
  25. //
  26. filterChainDefinitionMap.put("/login", "anon");//anon 可以理解為不攔截
  27. filterChainDefinitionMap.put("/reg", "anon");
  28. filterChainDefinitionMap.put("/plugins/**", "anon");
  29. filterChainDefinitionMap.put("/pages/**", "anon");
  30. filterChainDefinitionMap.put("/api/**", "anon");
  31. filterChainDefinitionMap.put("/dists/img/*", "anon");
  32. filterChainDefinitionMap.put("/**", "authc");
  33. shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
  34. return shiroFilterFactoryBean;
  35. }
  36. @Bean
  37. public EhCacheManager ehCacheManager() {
  38. EhCacheManager cacheManager = new EhCacheManager();
  39. return cacheManager;
  40. }
  41. /**
  42. * 不指定名字的話,自動創(chuàng)建一個方法名第一個字母小寫的bean * @Bean(name = "securityManager") * @return
  43. */
  44. @Bean
  45. public SecurityManager securityManager(UserRealm userRealm) {
  46. logger.info("注入Shiro的Web過濾器-->securityManager", ShiroFilterFactoryBean.class);
  47. DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
  48. securityManager.setRealm(userRealm);
  49. //注入緩存管理器;
  50. securityManager.setCacheManager(ehCacheManager());//這個如果執(zhí)行多次,也是同樣的一個對象;
  51. return securityManager;
  52. }
  53. /**
  54. * Shiro生命周期處理器 * @return
  55. */
  56. @Bean
  57. public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
  58. return new LifecycleBeanPostProcessor();
  59. }
  60. /**
  61. * 開啟Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP掃描使用Shiro注解的類,并在必要時進(jìn)行安全邏輯驗證 * 配置以下兩個bean(DefaultAdvisorAutoProxyCreator(可選)和AuthorizationAttributeSourceAdvisor)即可實(shí)現(xiàn)此功能 * @return
  62. */
  63. @Bean
  64. @DependsOn({"lifecycleBeanPostProcessor"})
  65. public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
  66. DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
  67. advisorAutoProxyCreator.setProxyTargetClass(true);
  68. return advisorAutoProxyCreator;
  69. }
  70. @Bean
  71. public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
  72. AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
  73. authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
  74. return authorizationAttributeSourceAdvisor;
  75. }
  76. }
5.實(shí)現(xiàn)登錄/退出等操作:

</>復(fù)制代碼

  1. @Controller
  2. public class SecurityController {
  3. private static final Logger logger = LoggerFactory.getLogger(SecurityController.class);
  4. @Autowired
  5. private UserService userService;
  6. @GetMapping("/login")
  7. public String loginForm() {
  8. return "login";
  9. }
  10. @PostMapping("/login")
  11. public String login(@Valid User user, BindingResult bindingResult, RedirectAttributes redirectAttributes) {
  12. if (bindingResult.hasErrors()) {
  13. return "login";
  14. }
  15. String loginName = user.getLoginName();
  16. logger.info("準(zhǔn)備登陸用戶 => {}", loginName);
  17. UsernamePasswordToken token = new UsernamePasswordToken(loginName,user.getPassword());
  18. //獲取當(dāng)前的Subject
  19. Subject currentUser = SecurityUtils.getSubject();
  20. try {
  21. //在調(diào)用了login方法后,SecurityManager會收到AuthenticationToken,并將其發(fā)送給已配置的Realm執(zhí)行必須的認(rèn)證檢查
  22. //每個Realm都能在必要時對提交的AuthenticationTokens作出反應(yīng)
  23. //所以這一步在調(diào)用login(token)方法時,它會走到MyRealm.doGetAuthenticationInfo()方法中,具體驗證方式詳見此方法
  24. logger.info("對用戶[" + loginName + "]進(jìn)行登錄驗證..驗證開始");
  25. currentUser.login(token);
  26. logger.info("對用戶[" + loginName + "]進(jìn)行登錄驗證..驗證通過");
  27. } catch (UnknownAccountException uae) {
  28. logger.info("對用戶[" + loginName + "]進(jìn)行登錄驗證..驗證未通過,未知賬戶");
  29. redirectAttributes.addFlashAttribute("message", "未知賬戶");
  30. } catch (IncorrectCredentialsException ice) {
  31. logger.info("對用戶[" + loginName + "]進(jìn)行登錄驗證..驗證未通過,錯誤的憑證");
  32. redirectAttributes.addFlashAttribute("message", "密碼不正確");
  33. } catch (LockedAccountException lae) {
  34. logger.info("對用戶[" + loginName + "]進(jìn)行登錄驗證..驗證未通過,賬戶已鎖定");
  35. redirectAttributes.addFlashAttribute("message", "賬戶已鎖定");
  36. } catch (ExcessiveAttemptsException eae) {
  37. logger.info("對用戶[" + loginName + "]進(jìn)行登錄驗證..驗證未通過,錯誤次數(shù)過多");
  38. redirectAttributes.addFlashAttribute("message", "用戶名或密碼錯誤次數(shù)過多");
  39. } catch (AuthenticationException ae) {
  40. //通過處理Shiro的運(yùn)行時AuthenticationException就可以控制用戶登錄失敗或密碼錯誤時的情景
  41. logger.info("對用戶[" + loginName + "]進(jìn)行登錄驗證..驗證未通過,堆棧軌跡如下");
  42. ae.printStackTrace();
  43. redirectAttributes.addFlashAttribute("message", "用戶名或密碼不正確");
  44. }
  45. //驗證是否登錄成功
  46. if (currentUser.isAuthenticated()) {
  47. logger.info("用戶[" + loginName + "]登錄認(rèn)證通過(這里可以進(jìn)行一些認(rèn)證通過后的一些系統(tǒng)參數(shù)初始化操作)");
  48. return "redirect:/index";
  49. } else {
  50. token.clear();
  51. return "redirect:/login";
  52. }
  53. }
  54. @GetMapping("/logout")
  55. public String logout(RedirectAttributes redirectAttributes) {
  56. //使用權(quán)限管理工具進(jìn)行用戶的退出,跳出登錄,給出提示信息
  57. SecurityUtils.getSubject().logout();
  58. redirectAttributes.addFlashAttribute("message", "您已安全退出");
  59. return "redirect:/login";
  60. }
  61. @GetMapping("/reg")
  62. @ResponseBody
  63. public Result reg(@Valid User user, BindingResult bindingResult) {
  64. if (bindingResult.hasErrors()) {
  65. return Result.error("用戶信息填寫不完整");
  66. }
  67. userService.save(user);
  68. return Result.ok();
  69. }
  70. }
6.前端頁面編寫:

一個簡單 form表單提交的demo

</>復(fù)制代碼

擴(kuò)展:

權(quán)限注解:

</>復(fù)制代碼

  1. @RequiresAuthentication
  2. 表示當(dāng)前Subject已經(jīng)通過login進(jìn)行了身份驗證;即Subject. isAuthenticated()返回true
  3. @RequiresUser
  4. 表示當(dāng)前Subject已經(jīng)身份驗證或者通過記住我登錄的。
  5. @RequiresGuest
  6. 表示當(dāng)前Subject沒有身份驗證或通過記住我登錄過,即是游客身份。
  7. @RequiresRoles(value={“admin”, “user”}, logical= Logical.AND)
  8. 表示當(dāng)前Subject需要角色admin和user。
  9. @RequiresPermissions (value={“user:a”, “user:b”}, logical= Logical.OR)
  10. 表示當(dāng)前Subject需要權(quán)限user:auser:b

標(biāo)簽
代碼驗證:
(暫時忽略)留待補(bǔ)充

結(jié)語:

Shiro 作為一款安全框架為我們提供了常用的功能,已經(jīng)足夠應(yīng)對絕大多數(shù)的業(yè)務(wù)需要,在下一篇文章中將介紹一款更加強(qiáng)大的安全框架 Spring Security。

參考資料:

Spring Boot系列(十五) 安全框架Apache Shiro(一)基本功能
Spring Boot Shiro 權(quán)限管理

學(xué)習(xí)資料:

Apache Shiro 使用手冊
《跟開濤學(xué)Shiro》 - 博客版
跟開濤學(xué) Shiro - wiki版
官方文檔

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/11245.html

相關(guān)文章

  • Spring Boot [集成-Shiro]

    摘要:后面的文章將圍繞著集成來進(jìn)行展開。表示當(dāng)前已經(jīng)身份驗證或者通過記住我登錄的。表示當(dāng)前需要角色和。參考資料系列十五安全框架一基本功能權(quán)限管理學(xué)習(xí)資料使用手冊跟開濤學(xué)博客版跟開濤學(xué)版官方文檔 導(dǎo)讀: 在閱讀這篇文章之前假設(shè)你已經(jīng)對Apache Shiro(后面統(tǒng)一用Shiro作為代指)有了一定的了解,如果你還對Shiro不熟悉的話在這篇文章的結(jié)尾附有相關(guān)的學(xué)習(xí)資料,關(guān)于Shiro是用來做什...

    superw 評論0 收藏0
  • 《 Kotlin + Spring Boot : 下一代 Java 服務(wù)端開發(fā) 》

    摘要:下一代服務(wù)端開發(fā)下一代服務(wù)端開發(fā)第部門快速開始第章快速開始環(huán)境準(zhǔn)備,,快速上手實(shí)現(xiàn)一個第章企業(yè)級服務(wù)開發(fā)從到語言的缺點(diǎn)發(fā)展歷程的缺點(diǎn)為什么是產(chǎn)生的背景解決了哪些問題為什么是的發(fā)展歷程容器的配置地獄是什么從到下一代企業(yè)級服務(wù)開發(fā)在移動開發(fā)領(lǐng)域 《 Kotlin + Spring Boot : 下一代 Java 服務(wù)端開發(fā) 》 Kotlin + Spring Boot : 下一代 Java...

    springDevBird 評論0 收藏0
  • springmvc項目轉(zhuǎn)為springboot

    摘要:說明如果你的項目連項目都不是,請自行轉(zhuǎn)為項目,在按照本教程進(jìn)行。本教程適用于的項目。處理攔截資源文件問題。 說明 如果你的項目連maven項目都不是,請自行轉(zhuǎn)為maven項目,在按照本教程進(jìn)行。本教程適用于spring+springmvc+mybatis+shiro的maven項目。1.修改pom文件依賴 刪除之前的spring依賴,添加springboot依賴 or...

    wqj97 評論0 收藏0
  • Spring Security

    摘要:框架具有輕便,開源的優(yōu)點(diǎn),所以本譯見構(gòu)建用戶管理微服務(wù)五使用令牌和來實(shí)現(xiàn)身份驗證往期譯見系列文章在賬號分享中持續(xù)連載,敬請查看在往期譯見系列的文章中,我們已經(jīng)建立了業(yè)務(wù)邏輯數(shù)據(jù)訪問層和前端控制器但是忽略了對身份進(jìn)行驗證。 重拾后端之Spring Boot(四):使用JWT和Spring Security保護(hù)REST API 重拾后端之Spring Boot(一):REST API的搭建...

    keelii 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<