Shiro与SpringBoot整和

「这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战

什么是Shiro

Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。

Shiro基本结构

在这里插入图片描述

其三个核心组件:Subject, SecurityManagerRealms

Subject:即“当前操作用户”

SecurityManager:它是Shiro框架的核心,负责管理所有用户的安全操作。典型的Facade 模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。 Realm: Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。

快速在SpringBoot上应用Shiro

  1. 导入shiro与spring的整和依赖

		<!--导入连接数据库mybatis依赖-->
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.1.3</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>

		<!--导入shiro与spring的整和依赖-->
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-spring</artifactId>
			<version>1.4.0</version>
		</dependency>

		
复制代码

2、配置用户的realm

当配置Shiro时,你必须至少指定一个Realm,用于认证和(或)授权。配置多个Realm是可以的,但是至少需要一个。

继承了AuthorizingRealm接口的实现类可以被称为realm。继承后要实现两个方法:doGetAuthorizationInfo(PrincipalCollection principalCollection)doGetAuthenticationInfo(AuthenticationToken authenticationToken) 一个是用来完成授权操作,一个是用来完成认证操作。

public class UserRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了授权操作");
        
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
        User user=(User)SecurityUtils.getSubject().getPrincipal();
        info.addStringPermission(user.getPerms());//添加相应的用户权限

        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        System.out.println("执行了认证操作");

        UsernamePasswordToken token=(UsernamePasswordToken) authenticationToken;
        //认证用户名,密码
        User user=userService.getUserByName(token.getUsername());

        if(!token.getUsername().equals(user.getUsername())){
            return null;//抛出异常UnknowAccountException
        }

        //密码认证
        return  new SimpleAuthenticationInfo(user,user.getPwd(),"");

    }
}
复制代码

3、 配置自己的配置类

  • 创建用户个性化的realme
  • 创建DefaultWebSercurityManger默认网络安全管理器
  • 创建ShirofilterFactoryBean
@Configuration
public class ShiroConfig {

    //ShirofilterFactoryBean
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean();
        bean.setSecurityManager(securityManager);
        Map<String,String> map=new LinkedHashMap<>();
        /**
         * anon:无需认证就可以访问
         * authc:认证了才能访问
         * user:必须有记住我功能才能访问
         * perms:拥有对某个资源的权限才能访问
         * role:拥有某个角色权限才能访问
         */

        map.put("/level1/*","perms[vip1]");//设置对应的访问权限集合:vip1可以访问
        map.put("/level2/*","perms[vip2]");
        map.put("/level3/*","perms[vip3]");
        bean.setFilterChainDefinitionMap(map);

        bean.setUnauthorizedUrl("/unauthoriz");
        //设置登陆页面
        bean.setLoginUrl("/toLogin");


        return bean;

    }

    //DefaultWebSercurityManger
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){
        DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
        securityManager.setRealm(userRealm);
        return  securityManager;


    }



    //realme
    @Bean(name="userRealm")
    public UserRealm userRealm(){
        return new UserRealm();
    }

    @Bean
    public ShiroDialect shiroDialect(){
        //thymeleaf与shiro整和
        return new ShiroDialect();
    }

}

复制代码

创建的realm必须添加@Bean注解,交给spring托管,后面需要注入给DefaultWebSercurityManger

创建ShiroFilterFactoryBean 时你可以设置过滤请求以及相应的访问权限。通过LinkedHashMap<>()放入ShiroFilterFactoryBean 中。

完成以上操作之后,就可以达到访问指定界面先要登陆获得相应的权限。

Shiro与Thymleaf

shiro与Thymleaf也有着良好的整和。用户结合两者可以达到:不同权限用户在同一界面看到不同的内容。比如 vip1看到: 在这里插入图片描述

vip2用户可以看到: 在这里插入图片描述 vip3用户看到: 在这里插入图片描述 导入相关依赖即可使用:

<!--导入Thymeleaf依赖-->
		<dependency>
			<groupId>org.thymeleaf</groupId>
			<artifactId>thymeleaf-spring5</artifactId>
		</dependency>
		<dependency>
			<groupId>org.thymeleaf.extras</groupId>
			<artifactId>thymeleaf-extras-java8time</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
<!--thymeleaf与shiro整和-->
		<dependency>
			<groupId>com.github.theborakompanioni</groupId>
			<artifactId>thymeleaf-extras-shiro</artifactId>
			<version>2.0.0</version>
		</dependency>
复制代码

只需在前端页面加上标签即可:shiro:hasPermission="" 例如:

 <div class="column" shiro:hasPermission="vip1">
                <div class="ui raised segment">
                    <div class="ui">
                        <div class="content">
                            <h5 class="content">Level 1</h5>
                            <hr>
                            <div><a th:href="@{/level1/1}"><i class="bullhorn icon"></i> Level-1-1</a></div>
                            <div><a th:href="@{/level1/2}"><i class="bullhorn icon"></i> Level-1-2</a></div>
                            <div><a th:href="@{/level1/3}"><i class="bullhorn icon"></i> Level-1-3</a></div>
                        </div>
                    </div>
                </div>
            </div>

复制代码

设置登录用户才能看得到的内容:在对应的标签上加上shiro:Authenticated 设置没登入用户看的到的内容:在对应的标签上加上shiro:NotAuthenticated

猜你喜欢

转载自juejin.im/post/7031157436128067615
今日推荐