系統城裝機大師 - 唯一官網:www.farandoo.com!

當前位置:首頁 > 數據庫 > Mysql > 詳細頁面

Shiro+SpringBoot認證

時間:2020-08-13來源:www.farandoo.com作者:電腦系統城

一、引入依賴

    shiro-all包含shiro所有的包、shiro-core是核心包、shiro-web是與web整合、shiro-spring是與spring整合、shiro-ehcache是與EHCache整合、shiro-quartz是與任務調度quartz整合等等。這里我們只需要引入shiro-spring即可。

 

1 <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring -->
2 <dependency>
3      <groupId>org.apache.shiro</groupId>
4      <artifactId>shiro-spring</artifactId>
5      <version>1.5.3</version>
6 </dependency>

 二、Controller層

復制代碼
@RestController
@RequestMapping("/account")
public class AccountController {

/**
 * 登錄
 * @param username
 * @param password
 * @return
 */
  @PostMapping(path = "/login")
    public ResultMsg login(
            @RequestParam(value = "aaccount")String username,
            @RequestParam(value = "apassword")String pwd,
            @RequestParam("check") Integer check ) {
        ResultMsg resultMsg = new ResultMsg();
        //        獲取當前用戶
        Subject subject = SecurityUtils.getSubject();
        /**
         * 判斷當前用戶是否已經認證過
         */
//        System.out.println("是否記住我==="+subject.isRemembered());
        if (!subject.isAuthenticated()) {
    //            封裝用戶的登錄數據
            UsernamePasswordToken token = new UsernamePasswordToken(username,pwd);
            Boolean rememberMe = check == 1 ? true:false;
            System.out.println(rememberMe);
            token.setRememberMe(rememberMe); //記住我
            try {
                subject.login(token); //登錄認證
                resultMsg.setState(200);
                resultMsg.setMsg("登錄成功");
                return resultMsg;
            } catch (UnknownAccountException u) {
                System.err.println("用戶不存在");
                resultMsg.setState(412);
                resultMsg.setMsg("用戶不存在");
                return resultMsg;
            } catch (IncorrectCredentialsException i) {
                System.err.println("密碼錯誤");
                resultMsg.setState(412);
                resultMsg.setMsg("密碼錯誤");
                return resultMsg;
            } catch (LockedAccountException l) {
                System.err.println("賬戶鎖定");
                resultMsg.setState(412);
                resultMsg.setMsg("賬戶鎖定");
                return resultMsg;
            }
        } else {
            resultMsg.setState(403);
            resultMsg.setMsg("此賬戶已在其他地方登錄,是否強制下線?");
            return resultMsg;
        }
    }
  
  /**
     * 退出登錄
     * @param num
     * @return
     */
    @GetMapping(path = "/loginout")
    public ResultMsg loginOut(Integer num) {
        ResultMsg resultMsg = new ResultMsg();
//        獲取當前用戶
        Subject subject = SecurityUtils.getSubject();
        subject.logout();//退出當前登錄
        resultMsg.setState(200);
        if (num == 1) {
            resultMsg.setMsg("已下線!");
        } else {
            resultMsg.setMsg("當前用戶已退出!");
        }
        return resultMsg;

    }
  
  /**
   * 未認證返回登錄頁面
   * @return
   */
  @GetMapping(path = "/login")
  public ModelAndView login() {
      ModelAndView mv = new ModelAndView("/user/login");
      return mv;
  }


}
復制代碼

Shiro核心配置

Shiro配置類

ShiroConfig.java

主要創建三大Bean對象

  • ShiroFilterFactoryBean(攔截一切請求)3
  • DefaultSecurityManager(安全管理器)2
  • 自定義Realm 繼承 AuthorizingRealm(主要用于認證和授權)1

建議創建順序逆行

復制代碼
package com.hk.aefz.shiro.config;

@Configuration
public class ShiroConfig {

    //    ShiroFliterFactoryBean 3
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(
            @Qualifier("securityManager") DefaultWebSecurityManager securityManager
    ) {
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
//        設置安全管理器
        factoryBean.setSecurityManager(securityManager);
//        添加Shiro內置過濾器
    /*
            anon:無需認證就可以訪問
            authc:必須認證才可以訪問
            user:必須擁有記住我功能才可以訪問
            perms:擁有對某個資源的權限才能訪問
            role:擁有某個角色權限才可以訪問
         */

        Map<String, String> filterMap = new LinkedHashMap<>();
//        匿名訪問
        filterMap.put("/navigation/index","anon");
        filterMap.put("/navigation/blogdetails","anon");
        filterMap.put("/navigation/login","anon");
        filterMap.put("/navigation/register","anon");
//        需要角色
        filterMap.put("/navigation/personblog","authc,roles[blogger]");
        filterMap.put("/navigation/admin-blog","authc,roles[blogger]");
        filterMap.put("/navigation/**","user");
        factoryBean.setFilterChainDefinitionMap(filterMap);
//        攔截后返回登錄頁面
        factoryBean.setLoginUrl("/navigation/login");return factoryBean;
    }

    //  DefaultWebSecurityManager 2 安全管理器
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(
            @Qualifier("userRealm") UserRealm userRealm,
    ) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//        關聯UserRealm
        securityManager.setRealm(userRealm);
        return securityManager;
    }
    //    創建UserRealm類 需要自定義 1
    @Bean
    public UserRealm  userRealm() {
        UserRealm userRealm = new UserRealm();
   
        return userRealm;
    }
    }
}
復制代碼

自定義Relam類

繼承AuthorizingRealm類

復制代碼
/**
 * 自定義UserRealm
 */
public class UserRealm extends AuthorizingRealm {

//    注入AccountController
    @Autowired
    private AccountController accountController;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private AccountService accountService;

//    授權
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        System.err.println("執行了授權.........");return null;
    }

//    認證
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.err.println("執行了認證...........");
//        獲取當前登錄賬戶
        UsernamePasswordToken accountToken = (UsernamePasswordToken) token;
        String username = accountToken.getUsername(); // 獲取當前賬號
//        連接數據庫進行登錄驗證
        Account account = accountController.selectByName(username);
        System.out.println(account);
        if (account == null) {
            return null; //拋出 UnknownAccountException 異常
        }
//         密碼認證 shiro做 存在泄密
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(account, account.getApassword(), account.getAaccount());return info;
    }

}
復制代碼

測試

使用PostMan進行登錄測試

 

分享到:

相關信息

系統教程欄目

欄目熱門教程

人氣教程排行

站長推薦

熱門系統下載

jlzzjlzz亚洲乱熟在线播放