Springboot集成shiro框架

前言

以前的项目代码,整理记录一下。

一、什么是shiro

官方:Shiro是一个功能强大且易于使用的Java安全框架,可以运行在JavaSE和JavaEE项目中,可执行身份验证、授权、加密和会话管理。

二、Shiro核心组件

1、UsernamePasswordToken,shiro用来封装用户登录信息,使用用户登录信息来创建令牌Token
2、SecurityManager,Shiro的核心部分,负责安全认证和授权
3、Subject,Shiro的一个抽象概念,代表一个用户实体或单独的个体对象
4、Realm,开发者自定义模块,根据业务逻辑进行认证和授权的逻辑设计
5、AuthenticationInfo,用户的角色信息集合,认证时使用
6、AuthorzationInfo,角色的权限信息集合,授权时使用
7、DefaultWebSecurityManager,安全管理器,开发者自定义的Realm模块需要注入到DefaultWebSecurityManager进行管理才能生效
8、ShiroFilterFactoryBean,过滤器工厂,Shiro的基本运行机制是开发者定制规则,Shiro去执行,具体的执行操作就是ShiroFilterFactoryBean创建的一个个filter对象来完成

三、Springboot集成Shiro

  • 引入Shiro依赖

 完整pom.xml依赖文件,参考最后的项目地址

<dependency>
	<groupId>org.apache.shiro</groupId>
	<artifactId>shiro-spring</artifactId>
	<version>2.0.0-alpha-3</version>
</dependency>
  • 创建一个ShiroConfig配置类

将自定义Realm注入 securityManager安全管理器;
过滤器工厂拦截请求;
开启对shior注解的支持

package com.rocky.springbootshiro.config;

import com.rocky.springbootshiro.shiro.CustomRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
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 {

    //将自己的验证方式加入容器,开发者自定义模块
    @Bean
    public CustomRealm myShiroRealm() {
        CustomRealm customRealm = new CustomRealm();
        customRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return customRealm;
    }

    /**
     * 将自定义Realm注入 securityManager安全管理器
     */
    @Bean(value = "securityManager")
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 设置自定义 realm.
        securityManager.setRealm(myShiroRealm());

        return securityManager;
    }

    /**
     * 过滤器工厂拦截请求
     * 使用Qualifier根据方法名获取实例
     * @param securityManager
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean factory(@Qualifier("securityManager") SecurityManager securityManager) {
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager);

        //必须使用LinkedHashMap有序集合,shiro根据配置的规则进行拦截认证时,是根据容器中的存储顺序决定的
        Map<String, String> filterRuleMap = new LinkedHashMap<>();
        filterRuleMap.put("/loginValidateCode","anon");
        filterRuleMap.put("/loginValidateCode*","anon");
        filterRuleMap.put("/listUsers","anon");
        filterRuleMap.put("/user/logout","anon");
        filterRuleMap.put("/login","anon");// 所有请求通过我们自己的JWT Filter
        filterRuleMap.put("/unauthorized/**", "anon");// 访问 /unauthorized/** 不通过JWTFilter
        filterRuleMap.put("/**", "authc");//其余接口一律拦截,主要这行代码必须放在所有权限设置的最后,不然会导致所有 url 都被拦截

        factoryBean.setFilterChainDefinitionMap(filterRuleMap);
        return factoryBean;
    }

    /**
     * 开启对shior注解的支持
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }

    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        //设置加密算法
        hashedCredentialsMatcher.setHashAlgorithmName("SHA1");
        //设置加密的次数
//        hashedCredentialsMatcher.setHashIterations(1);
        //true加密采用hex编码,false加密采用base64编码
//        hashedCredentialsMatcher.setStoredCredentialsHexEncoded(false);
        return hashedCredentialsMatcher;
    }


}
  • 编写自定义的Realm类

编写自己的Realm类继承AuthorizingRealm,实现doGetAuthenticationInfo(认证)和doGetAuthorizationInfo(授权)方法

package com.rocky.springbootshiro.shiro;

import com.rocky.springbootshiro.bean.Permissions;
import com.rocky.springbootshiro.bean.Role;
import com.rocky.springbootshiro.bean.User;
import com.rocky.springbootshiro.common.SignUtil;
import com.rocky.springbootshiro.pojo.Users;
import com.rocky.springbootshiro.service.LoginService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.lang.util.ByteSource;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class CustomRealm extends AuthorizingRealm {

    @Autowired
    private LoginService loginService;


    /**
     * 进行认证
     * @param authenticationToken
     * @return
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken){
        System.out.println("======认证=====");
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) authenticationToken;
        System.out.println(new String(usernamePasswordToken.getPassword()));
        Users u = loginService.selectUserByUserName(usernamePasswordToken.getUsername());
        if (u!=null){
            //加盐值
            return new SimpleAuthenticationInfo(u,u.getPassword(),ByteSource.Util.bytes(SignUtil.SALT_STR),getName());
        }
        return null;
    }


    /**
     * @MethodName doGetAuthorizationInfo
     * @Description 授权配置
     * 只有当需要检测用户权限的时候才会调用此方法,例如checkRole,checkPermission,@RequiresPermissions,@RequiresRoles之类的,有几个校验方法就调用几次
     */
    @Override
    public AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("========授权处理=======");
        //获取登录用户名
        Subject subject = SecurityUtils.getSubject();
        Users u = (Users) subject.getPrincipal();

        //添加角色和权限
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();

        //超级管理员
        if("admin".equals(u.getUsername())) {
            simpleAuthorizationInfo.addRole("admin");
            simpleAuthorizationInfo.addStringPermission("*:*:*");

            return simpleAuthorizationInfo;
        }
        //授权用户角色和权限
        User user = loginService.getUserByName(u.getUsername());
        for (Role role : user.getRoles()) {
            //添加角色
            simpleAuthorizationInfo.addRole(role.getRoleCode());
            //添加权限
            for (Permissions permissions : role.getPermissions()) {
                simpleAuthorizationInfo.addStringPermission(permissions.getPermissinsCode());
            }
        }
        return simpleAuthorizationInfo;
    }


}
  • 授权逻辑

这里涉及4张表:用户表,角色表,角色权限关联表,权限表。一个用户可能多个角色,一个角色可能绑定多个权限,都是一对多的关系,User类实体包含一个Role实体Set集合,Role类包含Permissions实体Set集合,授权时通过主外键关联查询出对应的角色和权限

 ==用户表==

DROP TABLE IF EXISTS `users`;
CREATE TABLE `users`  (
  `lid` int NOT NULL AUTO_INCREMENT,
  `username` varchar(255)  NOT NULL,
  `rolelid` varchar(500)  NULL DEFAULT NULL,
  `name` varchar(255)  NOT NULL,
  `password` varchar(64)  NOT NULL,
  `mobilephone` varchar(15)  NULL DEFAULT NULL,
  `email` varchar(60)  NULL DEFAULT NULL,
  `isuse` int NOT NULL DEFAULT 1,
  `isdelete` int NOT NULL DEFAULT 0,
  `operatorid` int NULL DEFAULT NULL,
  `address` varchar(255)  NULL DEFAULT NULL,
  `operatorname` varchar(20)  NULL DEFAULT NULL,
  `operatortime` varchar(20)  NULL DEFAULT NULL,
  `sex` int NULL DEFAULT NULL,
  `rolename` varchar(500)  NULL DEFAULT NULL,
  `telephone` varchar(15)  NULL DEFAULT NULL,
  `createname` varchar(60)  NULL DEFAULT NULL,
  `createtime` varchar(20)  NULL DEFAULT NULL,
  `age` int NULL DEFAULT NULL,
  PRIMARY KEY (`lid`) USING BTREE,
  UNIQUE INDEX `unique_user_username`(`username` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 30 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = DYNAMIC;

==角色权限关联表==

DROP TABLE IF EXISTS `sys_role_permission`;
CREATE TABLE `sys_role_permission`  (
  `id` int NOT NULL AUTO_INCREMENT,
  `role_id` int NULL DEFAULT NULL COMMENT '角色id',
  `permission_id` int NULL DEFAULT NULL COMMENT '权限id',
  `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `delete_status` varchar(1)  NULL DEFAULT '1' COMMENT '是否有效 1有效     2无效',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 20 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '角色-权限关联表' ROW_FORMAT = DYNAMIC;

==角色表==

DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role`  (
  `id` int NOT NULL AUTO_INCREMENT,
  `role_name` varchar(20)  NULL DEFAULT NULL COMMENT '角色名',
  `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `delete_status` varchar(1)  NULL DEFAULT '1' COMMENT '是否有效  1有效  2无效',
  `role_code` varchar(255)  NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '后台角色表' ROW_FORMAT = COMPACT;

==权限表==

DROP TABLE IF EXISTS `sys_permission`;
CREATE TABLE `sys_permission`  (
  `id` int NOT NULL DEFAULT 0 COMMENT '自定id,主要供前端展示权限列表分类排序使用.',
  `menu_code` varchar(255)  NULL DEFAULT '' COMMENT '归属菜单,前端判断并展示菜单使用,',
  `menu_name` varchar(255)  NULL DEFAULT '' COMMENT '菜单的中文释义',
  `permission_code` varchar(255)  NULL DEFAULT '' COMMENT '权限的代码/通配符,对应代码中@RequiresPermissions 的value',
  `permission_name` varchar(255)  NULL DEFAULT '' COMMENT '本权限的中文释义',
  `required_permission` tinyint(1) NULL DEFAULT 2 COMMENT '是否本菜单必选权限, 1.必选 2非必选 通常是\"列表\"权限是必选',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '后台权限表' ROW_FORMAT = COMPACT;
  • 登录校验

使用Subject对象调用login方法进行登录校验

@PostMapping("/login")
public ResultMap login(HttpServletRequest request, HttpServletResponse resp, User user) {
	ResultMap resultMap = new ResultMap();
	if (StringUtils.isEmpty(user.getUserName()) || StringUtils.isEmpty(user.getPassWord())) {
		return resultMap.fail().code(500).message("请输入用户名和密码!");
	}

	//用户认证信息
	Subject subject = SecurityUtils.getSubject();
	UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(
			user.getUserName(),
			user.getPassWord()
	);

	//进行登录验证,shiro默认登录过期时间是30分钟
	subject.login(usernamePasswordToken);

	Users u = loginService.selectUserByUserName(user.getUserName());
	return resultMap.success().code(200).ObjData("data", JSONObject.toJSON(u)).message("");
}
  • 方法权限绑定

 这里使用注解式来控制权限,也可以使用编程式来判断权限,获取Subject subject = SecurityUtils.getSubject(),
里面有hasRole()  hasRoles() checkPermission()等方法来检查权限,没有权限会报错,可使用一个全局的异常类来捕获Shiro的报错,然后自定义返回异常信息给到前端

/**
 * 拥有 user或admin 角色的用户可以访问下面的页面
 */
@RequiresRoles(logical = Logical.OR, value = {"user", "admin"})
@GetMapping("/getMessage")
public ResultMap getMessage() {
	Users u = (Users) SecurityUtils.getSubject().getPrincipal();
	System.out.println(u.getUsername());
	return resultMap.success().code(200).message("admin角色 和 user:list权限!");
}

/**
 * 拥有vip权限且,是user或admin角色
 */
@GetMapping("/getVipMessage")
@RequiresRoles(logical = Logical.OR, value = {"user","admin"})
@RequiresPermissions("vip")
public ResultMap getVipMessage() {
	return resultMap.success().code(200).message("user角色或者admin角色,和vip权限!");
}
  • 其它权限注解 

/**
 * @RequiresAuthentication
 * 已经通过subject登录认证
 *
 * @RequiresUser
 * subject已经身份验证或者通过记住我登录
 *
 * @RequiresRoles(logical = Logical.OR, value = {"user","admin"})
 * 拥有user角色或者admin角色
 *
 * @RequiresPermissions("user:list")
 * 拥有user:list权限
 *
 *@GetMapping("/getAuthMessage")
 * 已经通过subject登录认证
 */

  • 定义全局异常类ExceptionController 

@RestControllerAdvice注解将作用在所有注解了@RequestMapping的控制器的方法上

package com.rocky.springbootshiro.controller;

import com.rocky.springbootshiro.bean.ResultMap;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;

/**
 * @Author Mr.HPC
 * @Description 定义全局的异常处理类
 * @Date 23:46 2021/4/7
 */
@RestControllerAdvice
public class ExceptionController {
    private final ResultMap resultMap;

    @Autowired
    public ExceptionController(ResultMap resultMap) {
        this.resultMap = resultMap;
    }

    //没有权限
    @ExceptionHandler(AuthorizationException.class)
    public ResultMap handle401_1(Throwable ex) {
//        ex.printStackTrace();
        return resultMap.fail().code(401).message("ExceptionController:您没有权限访问!");
    }
    //账号密码错误
    @ExceptionHandler(AuthenticationException.class)
    public ResultMap handle401_2(Throwable ex){
        return resultMap.fail().code(401).message("ExceptionController:用户名或密码错误!");
    }
    //账号不存在
    @ExceptionHandler(UnknownAccountException.class)
    public ResultMap handle401_3(Throwable ex){
        return resultMap.fail().code(401).message("ExceptionController:账号不存在!");
    }



    // 捕捉其他所有异常
    @ExceptionHandler(Exception.class)
    public ResultMap globalException(HttpServletRequest request, Throwable ex) {
//        ex.printStackTrace();
        return resultMap.fail()
                .code(getStatus(request).value())
                .message("ExceptionController:访问出错,无法访问: " + ex.getMessage());
    }

    private HttpStatus getStatus(HttpServletRequest request) {
        Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
        if (statusCode == null) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
        return HttpStatus.valueOf(statusCode);
    }
}

四、Postman测试

登录成功

有权限

没权限 

登录失败 

五、实例项目代码地址 

码云:https://gitee.com/nevertouch/springboot-shiro.git

  • 27
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答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 Boot和Shiro框架: 1. 首先,需要在pom.xml文件中添加Shiro和Spring 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、付费专栏及课程。

余额充值