import java.util.Scanner,Spring Boot2整合Shiro(1):身份认证

 2023-09-26 阅读 31 评论 0

摘要:Spring Boot2整合Shiro(1):身份认证 前言 本文主要介绍了在Spring Boot2项目中整合Shiro实现登录认证。本文假设读者已经对Shiro和基于RBAC的权限控制系统有了基本的认识。 本项目没有数据库,也就没有dao层,所有的用户和密码均在Service层

Spring Boot2整合Shiro(1):身份认证

 

前言

本文主要介绍了在Spring Boot2项目中整合Shiro实现登录认证。本文假设读者已经对Shiro和基于RBAC的权限控制系统有了基本的认识。 
本项目没有数据库,也就没有dao层,所有的用户和密码均在Service层采用硬编码。

特别提醒:因为代码块中的@符号在博客发布过程中会导致代码格式混乱,所以@都是用双斜杠注释了。

创建工程

通过idea的Spring Initializr新建工程spring-boot2-shiro-project,选择web模块即可。在项目根目录添加servicecontrollerconfig文件夹,项目目录如下图所示: 
这里写图片描述

封装统一的返回值

这一步对于整合shiro不是必须的

import java.util.Scanner,为了在项目中返回统一的结果,我们新建一个泛型类,包含属性:结果代码code、结果信息message和结果数据data,其中data采用泛型,代码如下:

public class Result<T> {private ResultCodeEnum code;private String message;private  T data;public ResultCodeEnum getCode() {return code;}public Result() {}public Result setCode(ResultCodeEnum resultCode) {this.code = resultCode;return this;}public String getMessage() {return message;}public Result setMessage(String message) {this.message = message;return this;}public T getData() {return data;}public Result setData(T data) {this.data = data;return this;}
}

再新建一个枚举类ResultCodeEnum,列举所有的返回代码code

public enum ResultCodeEnum {SUCCESS(200),//成功FAIL(400),//失败UNAUTHORIZED(401),//未认证(签名错误)NOT_FOUND(404),//接口不存在INTERNAL_SERVER_ERROR(500);//服务器内部错误public int code;ResultCodeEnum(int code) {this.code = code;}public int getCode() {return this.code;}
}

再建一个结果生成类ResultGenerator,减少重复代码,保证返回值的统一性

public class ResultGenerator {private static final String DEFAULT_SUCCESS_MESSAGE = "SUCCESS";//成功public static Result genSuccessResult() {return new Result().setCode(ResultCodeEnum.SUCCESS).setMessage(DEFAULT_SUCCESS_MESSAGE);}public static <T> Result<T> genSuccessResult(T data) {return new Result().setCode(ResultCodeEnum.SUCCESS).setMessage(DEFAULT_SUCCESS_MESSAGE).setData(data);}public static Result genFailResult(String message) {return new Result().setCode(ResultCodeEnum.FAIL).setMessage(message);}public static Result genUnauthorizedResult() {return new Result().setCode(ResultCodeEnum.UNAUTHORIZED).setMessage("权限不足!");}
}

Hello World

新建IndexController

package top.zhaodongxx.controller;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import top.zhaodongxx.result.Result;
import top.zhaodongxx.result.ResultGenerator;/*** <P></P>** @author zhaodong* @version v1.0* @email zhaodongxx@outlook.com* @since 2018/3/30 21:55*/@RestController
public class IndexController {@GetMapping("/helloworld")public Result helloWorld() {return ResultGenerator.genSuccessResult("helloworld");}
}

运行SpringBoot2ShiroProjectApplication.java即可启动该Spring Boot项目。 
访问路径127.0.0.1:8080/helloworld 
这里写图片描述
项目运行成功!

整合 Shiro

在Spring Boot2项目中整合Shiro主要分为四步

  • 导入Shiro
  • 创建Shiro配置文件,并在其中配置DefaultWebSecurityManagerShiroFilterFactoryBean
  • 实现身份认证的具体逻辑Realm
  • 实现登录接口

导入 Shiro

beanpropertybindingresult,Shiro提供了一个启动器来完成与 Spring Boot 的集成。

<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring-boot-starter</artifactId><version>1.4.0</version>
</dependency>

配置 Shiro

因为本节只是介绍身份认证,所以只提供一个最简单的 Java Class 配置

package top.zhaodongxx.config;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;/*** <P></P>** @author zhaodong* @version v1.0* @email zhaodongxx@outlook.com* @since 2018/3/30 22:41*/
@Configuration
public class ShiroConfig {/*** 自定义的Realm*/@Bean(name = "myShiroRealm")public MyShiroRealm myShiroRealm(){MyShiroRealm myShiroRealm = new MyShiroRealm();return myShiroRealm;}@Beanpublic DefaultWebSecurityManager  securityManager(){DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();设置realm.securityManager.setRealm(myShiroRealm());return securityManager;}@Bean(name = "shiroFilter")public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();shiroFilterFactoryBean.setSecurityManager(securityManager);return shiroFilterFactoryBean;}
}

安全管理器DefaultWebSecurityManager是Shiro的核心模块,ShiroFilterFactoryBean用来配置需要被拦截的请求,被拦截下来的请求交给安全管理器管理。myShrioRealm在idea中现在还是红色的,因为我们还没有写。

自定义Shiro

新建一个服务,用来模拟从数据库中取出用户信息,


package top.zhaodongxx.service;import org.springframework.stereotype.Service;/*** @author zhaodong* @version v1.0* @email zhaodongxx@outlook.com* @since 2018/3/30 22:59*/
@Service
public class ShiroService {public String getPasswordByUsername(String username){switch (username){case "liming":return "123";case "hanli":return "456";default:return null;}}
}

Realm 是控制认证和授权的核心部分,也是开发人员必须自己实现的部分。 
自定义的Realm通过继承AuthorizingRealm类,实现它的两个方法:doGetAuthorizationInfodoGetAuthenticationInfo实现自己的认证和授权逻辑,其中doGetAuthenticationInfo处理授权逻辑暂时不实现。

package top.zhaodongxx.shiro;import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
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 top.zhaodongxx.service.ShiroService;import javax.annotation.Resource;/**** @author zhaodong* @version v1.0* @email zhaodongxx@outlook.com* @since 2018/3/30 22:55*/
public class MyShiroRealm extends AuthorizingRealm {@Resourcepublic ShiroService shiroService;/*** 授权*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();return authorizationInfo;}/*** 登录认证*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {//获取用户账号String username = token.getPrincipal().toString();String password = shiroService.getPasswordByUsername(username);if (password != null) {AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username,   //认证通过后,存放在session,一般存放user对象password,   //用户数据库中的密码getName());    //返回Realm名return authenticationInfo;}return null;}
}

实现登录接口

AuthenticationException是Shiro封装的异常,如果登录认证没有成功就会抛出这个异常。

package top.zhaodongxx.controller;import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import top.zhaodongxx.result.Result;
import top.zhaodongxx.result.ResultGenerator;/**** @author zhaodong* @version v1.0* @email zhaodongxx@outlook.com* @since 2018/3/30 23:05*/
@RestController
public class LoginController {@PostMapping("/doLogin")public Result doLogin(String username, String password) {Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken(username, password);try {subject.login(token);} catch (AuthenticationException e) {token.clear();return ResultGenerator.genFailResult("登录失败,用户名或密码错误!");}return ResultGenerator.genSuccessResult("登录成功");}
}

测试

@SpringBootApplication、重新启动项目。

通过postman访问127.0.0.1:8080/doLogin?username=liming&password=1231
登陆失败

这里写图片描述

访问127.0.0.1:8080/doLogin?username=liming&password=123
登录成功 
这里写图片描述

至此,通过Shiro实现了身份认证。

项目下载地址

  • github: spring-boot2-shiro-project

参考资料

  • springboot(十四):springboot整合shiro-登录认证和权限管理
  • Spring Boot + Shiro 集成
  • Spring Boot Shiro用户认证

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/2/97859.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息