SpringBoot集成Shiro框架

1.简介

Shiro 是一个强大、简单易用的 Java 安全框架,可使认证、授权、加密,会话过程更便捷,并可为应用提供安全保障。本节课重点介绍下 Shiro 的认证和授权功能。

2.Shiro的三大组件

Shiro 有三大核心组件,即 Subject、SecurityManager 和 Realm。先来看一下它们之间的关系。
在这里插入图片描述

2.1 Subject 为认证主体

包含 Principals 和 Credentials 两个信息。我们看下两者的具体含义。

Principals:代表身份。可以是用户名、邮件、手机号码等等,用来标识一个登录主体的身份。

Credentials:代表凭证。常见的有密码,数字证书等等。

说白了,两者代表了需要认证的内容,最常见的便是用户名、密码了。比如用户登录时,通过 Shiro 进行身份认证,其中就包括主体认证。

2.2 SecurityManager 为安全管理员

这是 Shiro 架构的核心,是 Shiro 内部所有原件的保护伞。项目中一般都会配置 SecurityManager,开发人员将大部分精力放在了 Subject 认证主体上,与 Subject 交互背后的安全操作,则由 SecurityManager 来完成。

2.3 Realm 是一个域

它是连接 Shiro 和具体应用的桥梁。当需要与安全数据交互时,比如用户账户、访问控制等,Shiro 将会在一个或多个 Realm 中查找。我们可以把 Realm 看作 DataSource,即安全数据源。一般,我们会自己定制 Realm

2.4 SpringBoot导入Shiro依赖

<!--      shiro整合Spring的包 -->
        <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.7.1</version>
        </dependency>

2.5编写ShiroConfig

使用Shiro框架,需要自己写一个Config配置 添加一下拦截、授权、跳转、关联、使用Thymeleaf一些配置

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
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 {

    //ShiroFilterFactoryBean  3
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);
        //添加shiro的内置过滤器
        /*
            anon: 无需认证就可以访问
            authc: 必须认证才能访问
            user: 必须拥有 记住我 才能访问
            perms: 拥有对某个资源的权限才能访问
            role: 拥有某个角色权限才能访问
        * */
        //拦截
        Map<String,String> filterMap= new LinkedHashMap<String,String>();
        //需要认证才能访问以下页面
//        filterMap.put("/user/add","authc");
//        filterMap.put("/user/update","authc");

        //授权,正常会跳转 未授权页面
        filterMap.put("/user/add","perms[user:add]");
        filterMap.put("/user/*","authc");
        bean.setFilterChainDefinitionMap(filterMap);
        //设置登录的请求
        bean.setLoginUrl("/toLogin");
        //跳转未授权页面
        bean.setUnauthorizedUrl("/noauth");
        return  bean;
    }
    //DefaultWebSecurityManager 2
    @Bean(name="securityManager")
    public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRelam")UserRelam userRelam){
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        //关联Relam
        defaultWebSecurityManager.setRealm(userRelam);
        return defaultWebSecurityManager;
    }
    //创建realm对象,需要自定义类 1
    @Bean
    public UserRelam userRelam(){
        return  new UserRelam();
    }

    //整个ShiroDiaLect 用来整合shiro thymeleaf
    @Bean
    public ShiroDialect getShiroDialect(){
        return  new ShiroDialect();
    }
}

2.6编写用户认证类Relam

自己个人写一个用户认证类Relam,配置自己一些基础信息。
这里doGetAuthenticationInfo方法中,我使用的用户名、密码都是直接写死的,一般来说都是从数据库中取,然后再跟前端传来的token来校验

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;

//自定义Relam extends AuthorizingRealm
public class UserRelam  extends AuthorizingRealm {
    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了=>授权doGetAuthorizationInfo");
        //SimpleAuthorizationInfo
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addStringPermission ("user:add");

        //拿到当前登录的对象
        Subject subject = SecurityUtils.getSubject();
        String principal = (String)subject.getPrincipal(); //可以拿到加密的时候用户对象
        //设置当前用户权限,一般权限从数据库读
        info.addStringPermission(principal);
        return info;
    }
    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("执行了=>认证doGetAuthorizationInfo");

        //用户名、密码 ~数据中取
        String name="root";
        String password="123456";
        UsernamePasswordToken userToken = (UsernamePasswordToken) token;
        //用户认证
        if(!userToken.getUsername().equals(name)){
            return  null;//抛出异常 UnknownAccountException
        }

        //密码认证Shiro来做
        //可以加密 MD5  MD5盐值加密
        return new SimpleAuthenticationInfo(name,password,"");
    }
}

2.7 Shiro一些方法

2.7.1角色验证

hasRole(String roleName)  
      返回true,当前Subject(登陆工号)有该角色权限,false,没有
hasRoles(List<String> roleNames)
      返回true,至少在集合中存在一个角色权限,false一个都没有
hasAllRoles(Collection<String> roleNames)
      返回true,当前工号拥有列表所有角色,否则返回false

2.7.2角色检查

checkRole(String roleName)
      若当前Subject(工号)有该角色不抛出异常,若没有抛出AuthorizationException
checkRoles(Collection<String> roleNames)
      若当前Subject(工号)拥有所有该集合角色不抛出异常,若没有抛出AuthorizationException
checkRoles(String... roleNames)
      同上,只不过采用java5的新特性

2.7.3权限校验

isPermitted(Permission p)/isPermitted(String perm)
     返回true,当前Subject(工号)拥有该权限,否则false 
isPermitted(List<Permission> perms)/isPermitted(String... perms)
    有集合中的一个以上,即返回true,否则false
isPermittedAll(Collection<Permission> perms)/isPermittedAll(String... perms)
     有集合中的所有权限,才返回true,否则false

2.7.4权限检查

 checkPermission(Permission p)	
 checkPermission(String perm)
 checkPermissions(Collection<Permission> perms)
 checkPermissions(String... perms)

2.8Shiro注解使用

@RequiresAuthentication  
    是否经过认证或者登陆,若没有的话会抛出异常UnauthenticatedException
   @RequiresGuest
   未认证或者叫未登陆,可能在remember me状态下,否则抛出异常UnauthenticatedException
   @RequiresPermissions
   检查是否有该权限,没有抛出异常AuthorizationException
   @RequiresRoles
   检查是否有该角色,没有抛出异常AuthorizationException
   @RequiresUser
   这个刚好跟@RequiresGuest相反,这个必须经过认证,或者从rememberme进行登陆,
   这个没有RequiresAuthentication严格但类似,否则抛出异常AuthorizationException

以上是我学习Shiro中一些基础的心得,希望能帮助到一些刚学的朋友,具体更详细的东西,可以参考其他博客

### 回答1: Spring Boot 集成 Shiro 框架可以实现在应用中实现安全认证、权限控制等功能。下面是大致的集成步骤: 1. 添加 Shiro 依赖 在 `pom.xml` 文件中添加 Shiro 的依赖。可以选择适合自己项目的版本号。 ```xml <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-starter</artifactId> <version>1.7.1</version> </dependency> ``` 2. 配置 Shiro 在 `application.properties` 或 `application.yml` 文件中添加 Shiro 的相关配置,如 Shiro 的过滤器、安全管理器、Realm 等。 ```yaml # 配置 Shiro 的过滤器 shiro: filter: anon: anon authc: authc # 配置 Shiro 的安全管理器和 Realm shiro: securityManager: realm: myRealm ``` 3. 实现 Realm Realm 是 Shiro 的核心组件之一,需要实现自己的 Realm 类,用于提供认证和授权数据。 ```java public class MyRealm extends AuthorizingRealm { // 认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { // 实现认证逻辑 } // 授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { // 实现授权逻辑 } } ``` 4. 使用 Shiro 在需要进行安全认证、权限控制的地方,可以使用 Shiro 提供的 API 进行操作。 ```java // 获取当前用户的信息 Subject subject = SecurityUtils.getSubject(); Object principal = subject.getPrincipal(); // 判断当前用户是否具有某个角色 boolean hasRole = subject.hasRole("admin"); // 判断当前用户是否具有某个权限 boolean hasPermission = subject.isPermitted("user:update"); ``` 这是一个大致的 Spring Boot 集成 Shiro 的步骤,具体实现方式可以根据自己的需求进行调整。 ### 回答2: Spring Boot 是一个快速开发框架Shiro 是一个安全框架,它们的集成可以帮助开发人员快速构建安全的 Web 应用程序。 为了将 Shiro 集成Spring Boot 中,首先需要在 Maven POM 文件中引入 Shiro 的依赖库。例如,以下 POM 文件中添加了 Shiro Spring Boot 的 Starter 依赖库: ``` <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-starter</artifactId> <version>1.5.0</version> </dependency> ``` 集成过程中,需要在应用程序中添加一个 Shiro 配置类,该类可以加载各种 Shiro 过滤器,用于对 URL 是否需要进行授权认证等操作,示例代码如下: ```java @Configuration public class ShiroConfig { @Bean public ShiroFilterFactoryBean shiroFilter(@Autowired SecurityManager securityManager){ ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); bean.setSecurityManager(securityManager); Map<String, String> chains = new HashMap<>(); chains.put("/login", "anon"); chains.put("/css/**", "anon"); chains.put("/js/**", "anon"); chains.put("/**", "authc"); bean.setFilterChainDefinitionMap(chains); return bean; } @Bean public SecurityManager securityManager(@Autowired UserRealm userRealm){ DefaultWebSecurityManager manager = new DefaultWebSecurityManager(); manager.setRealm(userRealm); return manager; } @Bean public UserRealm userRealm(){ return new UserRealm(); } } ``` 在这个例子中,我们为登录页、CSS、JS 等 URL 设置了“anon”过滤器,表示这些 URL 不需要进行认证,而其他 URL 都需要进行认证。此外,我们还提供了一个 UserRealm,用于提供用户的认证和授权。 最后,我们需要在应用程序中启用 Shiro,例如在启动主类里加入 @EnableShiro 注解: ```java @EnableShiro @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` 这样,我们就完成了 Shiro集成。使用 Shiro,开发人员可以方便地进行用户认证和授权,保障 Web 应用程序的安全性。 ### 回答3: Spring Boot是一个非常流行的Java Web框架,它可以通过添加各种插件来轻松集成许多其他框架和库。Shiro是一个全面的安全框架,提供了身份验证、授权、密码编码等功能,与Spring Boot集成也非常容易。 下面是一些简要的步骤来集成Spring BootShiro框架: 1. 首先,需要在pom.xml文件中添加ShiroSpring Boot Starter Web的依赖: ``` <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.3.2.RELEASE</version> </dependency> ``` 2. 然后,在应用程序的主类中添加@EnableWebSecurity注解,启用Spring Security的Web安全性支持,同时在configure(HttpSecurity http)方法中配置Shiro的安全过滤器链: ``` @Configuration @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .csrf() .disable() .authorizeRequests() .antMatchers("/login").permitAll() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/**").authenticated() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login").permitAll() .defaultSuccessUrl("/home.html") .and() .logout() .logoutUrl("/logout").permitAll() .deleteCookies("JSESSIONID") .logoutSuccessUrl("/login"); } @Bean public Realm realm() { return new MyRealm(); } @Bean public DefaultWebSecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(realm()); return securityManager; } @Bean public ShiroFilterFactoryBean shiroFilter() { ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); shiroFilter.setSecurityManager(securityManager()); shiroFilter.setLoginUrl("/login"); shiroFilter.setSuccessUrl("/home.html"); shiroFilter.setUnauthorizedUrl("/403.html"); Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>(); filterChainDefinitionMap.put("/login", "anon"); filterChainDefinitionMap.put("/logout", "logout"); filterChainDefinitionMap.put("/admin/**", "authc, roles[admin]"); filterChainDefinitionMap.put("/**", "user"); shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilter; } } ``` 3. 编写自定义的Realm类,用于实现Shiro的身份验证和授权逻辑: ``` public class MyRealm extends AuthorizingRealm { @Autowired private UserService userService; @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); User user = (User) principals.getPrimaryPrincipal(); for (Role role : user.getRoles()) { authorizationInfo.addRole(role.getName()); for (Permission permission : role.getPermissions()) { authorizationInfo.addStringPermission(permission.getPermission()); } } return authorizationInfo; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { UsernamePasswordToken upToken = (UsernamePasswordToken) token; String username = upToken.getUsername(); User user = userService.findByUsername(username); if (user != null) { return new SimpleAuthenticationInfo(user, user.getPassword(), getName()); } else { throw new UnknownAccountException(); } } } ``` 4. 最后,在Controller中使用Shiro提供的Subject来实现身份验证和授权: ``` @Controller public class HomeController { @RequestMapping(value = "/home.html", method = RequestMethod.GET) public String home() { Subject currentUser = SecurityUtils.getSubject(); if (currentUser.isAuthenticated()) { return "home"; } else { return "redirect:/login"; } } @RequestMapping(value = "/admin/index.html", method = RequestMethod.GET) public String admin() { Subject currentUser = SecurityUtils.getSubject(); if (currentUser.isAuthenticated() && currentUser.hasRole("admin")) { return "admin"; } else { return "redirect:/login"; } } @RequestMapping(value = "/login", method = RequestMethod.GET) public String login() { return "login"; } } ``` 使用以上步骤实现了Spring Boot集成Shiro框架,完成了基本的身份验证和授权操作。实现后就可以进行测试,通过Shiro的身份验证和授权功能保证系统的安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值