日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

在實(shí)際項(xiàng)目中,經(jīng)常需要用到角色權(quán)限區(qū)分,以此來(lái)為不同的角色賦予不同的權(quán)利,分配不同的任務(wù)。比如,普通用戶只能瀏覽;會(huì)員可以瀏覽和評(píng)論;超級(jí)會(huì)員可以瀏覽、評(píng)論和看視頻課等;實(shí)際應(yīng)用場(chǎng)景很多。毫不夸張的說(shuō),幾乎每個(gè)完整的項(xiàng)目都會(huì)涉及到權(quán)限管理。

因此,這篇文章,阿淼就帶大家將 shiro 權(quán)限框架整合到 SpringBoot 中,以達(dá)到快速的實(shí)現(xiàn)權(quán)限管理的功能。

在 Spring Boot 中做權(quán)限管理,一般來(lái)說(shuō),主流的方案是 Spring Security ,但是由于 Spring Security 過(guò)于龐大和復(fù)雜,只要能滿足業(yè)務(wù)需要,大多數(shù)公司還是會(huì)選擇 Apache Shiro 來(lái)使用。

一般來(lái)說(shuō),Spring Security 和 Shiro 的區(qū)別如下:

Spring SecurityApache Shiro重量級(jí)的安全管理框架輕量級(jí)的安全管理框架概念復(fù)雜,配置繁瑣概念簡(jiǎn)單、配置簡(jiǎn)單功能強(qiáng)大功能簡(jiǎn)單

這篇文章會(huì)首先帶大家了解 Apache Shiro ,然后再給出使用案例 Demo。

走進(jìn) Apache Shiro

官網(wǎng)認(rèn)知

照例又去官網(wǎng)扒了扒介紹:

Apache Shiro™ is a powerful and easy-to-use JAVA security framework that performs authentication, authorization, cryptography, and session management. With Shiro’s easy-to-understand API, you can quickly and easily secure any Application – from the smallest mobile applications to the largest web and enterprise applications. Apache Shiro™是一個(gè)強(qiáng)大且易用的Java安全框架,能夠用于身份驗(yàn)證、授權(quán)、加密和會(huì)話管理。Shiro擁有易于理解的API,您可以快速、輕松地獲得任何應(yīng)用程序——從最小的移動(dòng)應(yīng)用程序到最大的網(wǎng)絡(luò)和企業(yè)應(yīng)用程序。

簡(jiǎn)而言之,Apache Shiro 是一個(gè)強(qiáng)大靈活的開(kāi)源安全框架,可以完全處理身份驗(yàn)證、授權(quán)、加密和會(huì)話管理。

Shiro能到底能做些什么呢?

  • 驗(yàn)證用戶身份
  • 用戶訪問(wèn)權(quán)限控制,比如:1、判斷用戶是否分配了一定的安全角色。2、判斷用戶是否被授予完成某個(gè)操作的權(quán)限
  • 在非 Web 或 EJB 容器的環(huán)境下可以任意使用Session API
  • 可以響應(yīng)認(rèn)證、訪問(wèn)控制,或者 Session 生命周期中發(fā)生的事件
  • 可將一個(gè)或以上用戶安全數(shù)據(jù)源數(shù)據(jù)組合成一個(gè)復(fù)合的用戶 “view”(視圖)
  • 支持單點(diǎn)登錄(SSO)功能
  • 支持提供“Remember Me”服務(wù),獲取用戶關(guān)聯(lián)信息而無(wú)需登錄 ···

為什么今天還要使用Apache Shiro?

對(duì)此,官方給出了詳細(xì)的解釋:shiro.apache.org/

自2003年以來(lái),框架環(huán)境發(fā)生了很大變化,因此今天仍然有充分的理由使用Shiro。實(shí)際上有很多原因。Apache Shiro是:

  • 易于使用 -易于使用是該項(xiàng)目的最終目標(biāo)。應(yīng)用程序安全性可能非常令人困惑和沮喪,并被視為“必要的邪惡”。如果您使它易于使用,以使新手程序員可以開(kāi)始使用它,那么就不必再痛苦了。
  • 全面 -Apache Shiro聲稱沒(méi)有其他具有范圍廣度的安全框架,因此它可能是滿足安全需求的“一站式服務(wù)”。
  • 靈活 -Apache Shiro可以在任何應(yīng)用程序環(huán)境中工作。盡管它可以在Web,EJB和IoC環(huán)境中運(yùn)行,但并不需要它們。Shiro也不要求任何規(guī)范,甚至沒(méi)有很多依賴性。
  • 具有Web功能 -Apache Shiro具有出色的Web應(yīng)用程序支持,使您可以基于應(yīng)用程序URL和Web協(xié)議(例如REST)創(chuàng)建靈活的安全策略,同時(shí)還提供一組JSP庫(kù)來(lái)控制頁(yè)面輸出。
  • 可插拔 -Shiro干凈的API和設(shè)計(jì)模式使它易于與許多其他框架和應(yīng)用程序集成。您會(huì)看到Shiro與Spring,Grails,Wicket,Tapestry,Mule,Apache Camel,Vaadin等框架無(wú)縫集成。
  • 受支持 -Apache Shiro是Apache Software Foundation(Apache軟件基金會(huì))的一部分,該組織被證明以其社區(qū)的最大利益行事。項(xiàng)目開(kāi)發(fā)和用戶群體友好的公民隨時(shí)可以提供幫助。如果需要,像Katasoft這樣的商業(yè)公司也可以提供專業(yè)的支持和服務(wù)。

Shiro 核心概念

Apache Shiro 是一個(gè)全面的、蘊(yùn)含豐富功能的安全框架。

下圖為描述 Shiro 功能的框架圖:

玩轉(zhuǎn)SpringBoot之整合 shiro 權(quán)限框架

 

 

如圖所示,功能包括:

  • Authentication(認(rèn)證):用戶身份識(shí)別,通常被稱為用戶“登錄”
  • Authorization(授權(quán)):訪問(wèn)控制。比如某個(gè)用戶是否具有某個(gè)操作的使用權(quán)限。
  • Session Management(會(huì)話管理):特定于用戶的會(huì)話管理,甚至在非web 或 EJB 應(yīng)用程序。
  • Cryptography(加密):在對(duì)數(shù)據(jù)源使用加密算法加密的同時(shí),保證易于使用。

并且 Shiro 還有通過(guò)增加其他的功能來(lái)支持和加強(qiáng)這些不同應(yīng)用環(huán)境下安全領(lǐng)域的關(guān)注點(diǎn)。

特別是對(duì)以下的功能支持:

  • Web支持:Shiro 提供的 Web 支持 api ,可以很輕松的保護(hù) Web 應(yīng)用程序的安全。
  • 緩存:緩存是 Apache Shiro 保證安全操作快速、高效的重要手段。
  • 并發(fā):Apache Shiro 支持多線程應(yīng)用程序的并發(fā)特性。
  • 測(cè)試:支持單元測(cè)試和集成測(cè)試,確保代碼和預(yù)想的一樣安全。
  • "Run As":這個(gè)功能允許用戶假設(shè)另一個(gè)用戶的身份(在許可的前提下)。
  • "Remember Me":跨 session 記錄用戶的身份,只有在強(qiáng)制需要時(shí)才需要登錄。

注意: Shiro 不會(huì)去維護(hù)用戶、維護(hù)權(quán)限,這些需要我們自己去設(shè)計(jì)/提供,然后通過(guò)相應(yīng)的接口注入給 Shiro

使用案例 Demo

1.新建 maven 項(xiàng)目

為方便我們初始化項(xiàng)目,Spring Boot給我們提供一個(gè)項(xiàng)目模板生成網(wǎng)站。

  • 1、打開(kāi)瀏覽器,訪問(wèn):start.spring.io/
  • 2、根據(jù)頁(yè)面提示,選擇構(gòu)建工具,開(kāi)發(fā)語(yǔ)言,項(xiàng)目信息等。

2.導(dǎo)入 springboot 父依賴

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.2.RELEASE</version>
</parent>
復(fù)制代碼

3.相關(guān) jar 包

web 包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
復(fù)制代碼

shiro-spring 包就是此篇文章的核心

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.4.0</version>
</dependency>
shiro 注解會(huì)用到 aop<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
數(shù)據(jù)庫(kù)相關(guān)包使用的是mybatisplus<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.12</version>
</dependency>
<dependency>
    <groupId>MySQL</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.1.0</version>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.1.0</version>
</dependency>
    <dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.0</version>
</dependency>
復(fù)制代碼

4.數(shù)據(jù)庫(kù)

建表語(yǔ)句在項(xiàng)目中有,項(xiàng)目地址: github.com/mmzsblog/mm…

5.自定義 realm

public class MyShiroRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private PermissionService permissionService;
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        // HttpServletRequest request = (HttpServletRequest) ((WebSubject) SecurityUtils
        // .getSubject()).getServletRequest();//這個(gè)可以用來(lái)獲取在登錄的時(shí)候提交的其他額外的參數(shù)信息
        String username = (String) principals.getPrimaryPrincipal();
        // 受理權(quán)限
        // 角色
        Set<String> roles = new HashSet<String>();
        Role role = roleService.getRoleByUserName(username);
        System.out.println(role.getRoleName());
        roles.add(role.getRoleName());
        authorizationInfo.setRoles(roles);
        // 權(quán)限
        Set<String> permissions = new HashSet<String>();
        List<Permission> querypermissions = permissionService.getPermissionsByRoleId(role.getId());
        for (Permission permission : querypermissions) {
            permissions.add(permission.getPermissionName());
        }
        authorizationInfo.setStringPermissions(permissions);
        return authorizationInfo;
    }
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
            throws AuthenticationException {
        String loginName = (String) authcToken.getPrincipal();
        // 獲取用戶密碼
        User user = userService.getOne(new QueryWrapper<User>().eq("username", loginName));
        if (user == null) {
            // 沒(méi)找到帳號(hào)
            throw new UnknownAccountException();
        }
        String password = new String((char[]) authcToken.getCredentials());
        String inpass = (new Md5Hash(password, user.getUsername())).toString();
        if (!user.getPassword().equals(inpass)) {
            throw new IncorrectCredentialsException();
        }
        // 交給AuthenticatingRealm使用CredentialsMatcher進(jìn)行密碼匹配
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(loginName, user.getPassword(),
                ByteSource.Util.bytes(loginName), getName());
        return authenticationInfo;
    }
}
復(fù)制代碼

6.shiro 配置類

@Configuration
public class ShiroConfiguration {    private static final Logger logger = LoggerFactory.getLogger(ShiroConfiguration.class);    /**     * Shiro的Web過(guò)濾器Factory 命名:shiroFilter     */    @Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();        // Shiro的核心安全接口,這個(gè)屬性是必須的        shiroFilterFactoryBean.setSecurityManager(securityManager);        //需要權(quán)限的請(qǐng)求,如果沒(méi)有登錄則會(huì)跳轉(zhuǎn)到這里設(shè)置的url        shiroFilterFactoryBean.setLoginUrl("/login.html");
        //設(shè)置登錄成功跳轉(zhuǎn)url,一般在登錄成功后自己代碼設(shè)置跳轉(zhuǎn)url,此處基本沒(méi)用        shiroFilterFactoryBean.setSuccessUrl("/main.html");
        //設(shè)置無(wú)權(quán)限跳轉(zhuǎn)界面,此處一般不生效,一般自定義異常        shiroFilterFactoryBean.setUnauthorizedUrl("/error.html");
        Map<String, Filter> filterMap = new LinkedHashMap<>();        // filterMap.put("authc", new AjaxPermissionsAuthorizationFilter());
        shiroFilterFactoryBean.setFilters(filterMap);        /*         * 定義shiro過(guò)濾鏈 Map結(jié)構(gòu)         * Map中key(xml中是指value值)的第一個(gè)'/'代表的路徑是相對(duì)于HttpServletRequest.getContextPath()的值來(lái)的
         * anon:它對(duì)應(yīng)的過(guò)濾器里面是空的,什么都沒(méi)做,這里.do和.jsp后面的*表示參數(shù),比方說(shuō)login.jsp?main這種
         * authc:該過(guò)濾器下的頁(yè)面必須驗(yàn)證后才能訪問(wèn),它是Shiro內(nèi)置的一個(gè)攔截器org.apache.shiro.web.filter.authc.         * FormAuthenticationFilter         */        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();        /*         * 過(guò)濾鏈定義,從上向下順序執(zhí)行,一般將 /**放在最為下邊; authc:所有url都必須認(rèn)證通過(guò)才可以訪問(wèn);         * anon:所有url都都可以匿名訪問(wèn)         */        filterChainDefinitionMap.put("/login.html", "authc");
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/js/**", "anon");
        filterChainDefinitionMap.put("/css/**", "anon");
        filterChainDefinitionMap.put("/logout", "logout");
        filterChainDefinitionMap.put("/**", "authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);        return shiroFilterFactoryBean;
    }    /**     * 權(quán)限管理     */    @Bean    public SecurityManager securityManager() {
        logger.info("=======================shiro=======================");
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();        securityManager.setRealm(MyShiroRealm());        // securityManager.setRememberMeManager(rememberMeManager);        return securityManager;
    }    /**     * Shiro Realm 繼承自AuthorizingRealm的自定義Realm,即指定Shiro驗(yàn)證用戶登錄的類為自定義的     */    @Bean    public MyShiroRealm MyShiroRealm() {
        MyShiroRealm userRealm = new MyShiroRealm();        userRealm.setCredentialsMatcher(hashedCredentialsMatcher());        return userRealm;
    }    /**     * 憑證匹配器 密碼驗(yàn)證     */    @Bean(name = "credentialsMatcher")
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();        // 散列算法:這里使用MD5算法;        hashedCredentialsMatcher.setHashAlgorithmName("md5");
        // 散列的次數(shù),比如散列兩次,相當(dāng)于 md5(md5(""));
        hashedCredentialsMatcher.setHashIterations(1);        // storedCredentialsHexEncoded默認(rèn)是true,此時(shí)用的是密碼加密用的是Hex編碼;false時(shí)用Base64編碼
        hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);
        return hashedCredentialsMatcher;
    }    /**     * 開(kāi)啟Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP掃描使用Shiro注解的類,并在必要時(shí)進(jìn)行安全邏輯驗(yàn)證     */    @Bean    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());        return authorizationAttributeSourceAdvisor;
    }}復(fù)制代碼

7.考試類

@RestController
public class UserController {    @PostMapping("login")
    public String name(String username, String password) {        String result = "已登錄";
        Subject currentUser = SecurityUtils.getSubject();        UsernamePasswordToken token = new UsernamePasswordToken(username, password);        if (!currentUser.isAuthenticated()) {
            try {                currentUser.login(token);// 會(huì)觸發(fā)com.shiro.config.MyShiroRealm的doGetAuthenticationInfo方法
                result = "登錄成功";
            } catch (UnknownAccountException e) {                result = "用戶名錯(cuò)誤";
            } catch (IncorrectCredentialsException e) {                result = "密碼錯(cuò)誤";
            }        }        return result;
    }    @GetMapping("logout")
    public void logout() {        Subject currentUser = SecurityUtils.getSubject();        currentUser.logout();    }    @RequiresPermissions("role:update")
    @GetMapping("/role")
    public String name() {        return "hello";
    }    @RequiresPermissions("user:select")
    @GetMapping("/role2")
    public String permission() {        return "hello sel";
    }}復(fù)制代碼

7.1 登錄測(cè)試

數(shù)據(jù)庫(kù)賬號(hào)(密碼經(jīng)過(guò)md5加鹽加密)

玩轉(zhuǎn)SpringBoot之整合 shiro 權(quán)限框架

 


玩轉(zhuǎn)SpringBoot之整合 shiro 權(quán)限框架

 


玩轉(zhuǎn)SpringBoot之整合 shiro 權(quán)限框架

 

 

玩轉(zhuǎn)SpringBoot之整合 shiro 權(quán)限框架

 

 

玩轉(zhuǎn)SpringBoot之整合 shiro 權(quán)限框架

 

 

7.2 權(quán)限測(cè)試

玩轉(zhuǎn)SpringBoot之整合 shiro 權(quán)限框架

 


玩轉(zhuǎn)SpringBoot之整合 shiro 權(quán)限框架

 

8.說(shuō)明

8.1 無(wú)權(quán)限時(shí)的處理

無(wú)權(quán)限時(shí)自定義了一個(gè)異常。所以,權(quán)限測(cè)試的時(shí)候沒(méi)有權(quán)限就會(huì)提示配置的提示語(yǔ) “沒(méi)有權(quán)限”。

@ControllerAdvice
public class ShiroException {
    @ExceptionHandler(value = UnauthorizedException.class)
    @ResponseBody
    public String name() {
        return "沒(méi)有權(quán)限";
    }}復(fù)制代碼

8.2 角色權(quán)限測(cè)試與權(quán)限測(cè)試相同

權(quán)限設(shè)置可在shiro配置類中shiro過(guò)濾鏈設(shè)置,也可用注解方式設(shè)置,本文使用注解方式。

8.3 shiro 的 session 和 cache

shiro 的 session 和 cache 管理可以自定義,本文用的是默認(rèn)的,推薦自定義,方便管理。

小結(jié)

  • Apache Shiro是Java的一個(gè)安全框架
  • Shiro是一個(gè)強(qiáng)大的簡(jiǎn)單易用的Java安全框架,主要用來(lái)更便捷的認(rèn)證、授權(quán)、加密、會(huì)話管理、與Web集成、緩存等
  • Shiro使用起來(lái)小而簡(jiǎn)單
  • spring中有spring security ,是一個(gè)權(quán)限框架,它和spring依賴過(guò)于緊密,沒(méi)有shiro使用簡(jiǎn)單。
  • shiro不依賴于spring,shiro不僅可以實(shí)現(xiàn)web應(yīng)用的權(quán)限管理,還可以實(shí)現(xiàn)c/s系統(tǒng),分布式系統(tǒng)權(quán)限管理,
  • shiro屬于輕量框架,越來(lái)越多企業(yè)項(xiàng)目開(kāi)始使用shiro.

分享到:
標(biāo)簽:SpringBoot
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定