Shiro安全框架的学习

212 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第29天,点击查看活动详情

1. shiro的相关的学习

1.shiro官网

shiro.apache.org/

Apache Shiro 是一个强大易用的 Java 安全框架,提供了认证、授权、加密和session会话管理等功能,对于任何一个应用程序,Shiro 都可以提供全面的安全管理服务。并且相对于其他安全框架spring security,Shiro 要简单的多。

2.源码下载地址

github.com/apache/shir…

1.1 什么是权限管理

基本上涉及到用户参与的系统都要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资源。

1.2 什么是身份认证

身份认证,就是判断一个用户是否为合法用户的处理过程。最常用的简单身份认证方式是系统通过核对用户输入的用户名和口令,看其是否与系统中存储的该用户的用户名和口令一致,来判断用户身份是否正确。对于采用指纹等系统,则出示指纹;对于硬件Key等刷卡系统,则需要刷卡。

2. 10分钟入门shiro

    1. pom的导入

注意:我们要想使用首先的就是依赖的导入,因为我们使用的是SpringBoot框架所以后续减少了很多的Spring Bean的配置,这对于开发者是十分友好的.所以我们在项目启动的时候将shiro的相关的依赖进行导入

<dependencies>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.5.3</version>
        </dependency>

        <!-- configure logging -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.7.26</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.26</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>
    1. 日志配置文件

注意:此处配合使用日志的目的大家应该都了解,方便之后遇到异常或者其他情况下可以进行追溯哦

log4j.rootLogger=INFO, stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n

# General Apache libraries
log4j.logger.org.apache=WARN

# Spring
log4j.logger.org.springframework=WARN

# Default Shiro logging
log4j.logger.org.apache.shiro=INFO

# Disable verbose logging
log4j.logger.org.apache.shiro.util.ThreadContext=WARN
log4j.logger.org.apache.shiro.cache.ehcache.EhCache=WARN

    1. 在Quickstart中用到的相关重要代码
Subject currentUser = SecurityUtils.getSubject();
Session session = currentUser.getSession();
currentUser.isAuthenticated()
currentUser.getPrincipal()
currentUser.hasRole("schwartz")
currentUser.isPermitted("lightsaber:wield")
currentUser.logout();

image.png

2.使用shiro完成工作

2.1 shiro中认证的关键对象

Subject:主体访问系统的用户,主体可以是用户、程序等,进行认证的都称为主体;

Principal:身份信息----账号是主体(subject)进行身份认证的标识,标识必须具有唯一性,如用户名、手机号、邮箱地址等,一个主体可以有多个身份,但是必须有一个主身份(Primary Principal)。

credential:凭证信息---密码是只有主体自己知道的安全信息,如密码、证书等。

2.2 编写配置类

1.第一个文件为ShiroConfig文件:

package com.whx.config;


import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;


@Configuration
public class ShiroConfig {

//    1. shiroFilterFactoryBean  2. DefaultWebSecurityManager  3. realm对象  需要自定义类


//第三步   shiroFilterFactoryBean  然后关联DefaultWebSecurityManager
   @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){

        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();

//设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);
//内置过滤器
//       anno:无需认证即可访问
//       authc:必须认证才可访问
//       user:必须拥有记住我功能才可以使用
//       perms:拥有对某个资源的权限才可以访问
//       role:拥有某个角色权限才可以访问
       Map<String, String> filterMap=new LinkedHashMap<>();
//       给add页面添加权限
       filterMap.put("/user/add","authc");
       filterMap.put("/user/*","authc");
       bean.setFilterChainDefinitionMap(filterMap);
//如果没有权限则返回登录页面
       bean.setLoginUrl("/toLogin");
       return  bean;
    }
//第二步 DefaultWebSecurityManager然后对realm进行关联,通过(@Qualifier("userRealm") UserRealm userRealm)将UserRealm关联起来

    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联 UserRealm
        securityManager.setRealm(userRealm);


        return securityManager;
    }
//    第一步,将自定义类UserRealm拿过来用
    @Bean
    public UserRealm userRealm(){
        return new UserRealm();
    }
}

2.第一个文件为UserRealm文件:

package com.whx.config;


import com.whx.pojo.User;
import com.whx.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

public class UserRealm  extends AuthorizingRealm {

    @Autowired
    UserService userService;
//    授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了>=doGetAuthorizationInfo()");
        return null;
    }


//    认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("执行了>=doGetAuthenticationInfo()");

        用户名和密码从数据库中取,此处先伪造一些数据方便验证
//        String name="root";
//        String password="123456";
//        UsernamePasswordToken userToken=(UsernamePasswordToken)authenticationToken;
用户名验证
//        if(!userToken.getUsername().equals(name)){
//            return null;
//        }


//        通过数据库连接
        UsernamePasswordToken userToken=(UsernamePasswordToken)authenticationToken;
        User user = userService.queryUserByName(userToken.getUsername());
        if(user==null){
            return null;
        }

//        密码验证,有shiro自己做,可以加密MD5以及MD5延值加密
        return new SimpleAuthenticationInfo("",user.getPwd(),"");
    }
}

用假数据写用户名和密码时,可以通过以下进行测试是否书写正确。

package com.whx;

import com.whx.service.UserServiceImpl;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class SpringbootShiro1ApplicationTests {

    @Autowired
    UserServiceImpl userService;
    @Test
    void contextLoads() {

        System.out.println(userService.queryUserByName("小儿"));

    }

}

在shiro配置文件中设置了权限,怎么赋值给用户呐?

image.png

死数据取值:

image.png

通过从数据库取值,在数据库中添加一条perms属性:

image.png