前言
SpringSecurity是一个用于Java 企业级应用程序的安全框架,主要包含用户认证和用户授权两个方面.相比较Shiro而言,Security功能更加的强大,它可以很容易地扩展以满足更多安全控制方面的需求,但也相对它的学习成本会更高,两种框架各有利弊.实际开发中还是要根据业务和项目的需求来决定使用哪一种。
JWT是在Web应用中安全传递信息的规范,从本质上来说是Token的演变,是一种生成加密用户身份信息的Token,特别适用于分布式单点登陆的场景,无需在服务端保存用户的认证信息,而是直接对Token进行校验获取用户信息,使单点登录更为简单灵活。
项目环境
- SpringBoot版本:2.1.6
- SpringSecurity版本: 5.1.5
- MyBatis-Plus版本: 3.1.0
- JDK版本:1.8
- 数据表(SQL文件在项目中):数据库中测试号的密码进行了加密,密码皆为123456
Maven依赖如下:
<
配置如下:
#
编写项目基础类
Entity,Dao,Service,及等SpringSecurity用户的Entity,Service类等在这里省略,请参考源码。
编写JWT工具类。
/**
编写暂无权限处理类。
/**
编写用户未登录处理类。
/**
编写登录失败处理类。
/**
编写登录成功处理类。
/**
编写登出成功处理类。
/**
编写Security核心类
编写自定义登录验证类。
/**
编写自定义PermissionEvaluator注解验证。
/**
编写SpringSecurity核心配置类。
/**
编写JWT拦截类
编写JWT接口请求校验拦截器。
/**
权限注解和hasPermission权限扩展
Security允许我们在定义URL方法访问所应有的注解权限时使用SpringEL表达式,在定义所需的访问权限时如果对应的表达式返回结果为true则表示拥有对应的权限,反之则没有权限,会进入到我们配置的。UserAuthAccessDeniedHandler(暂无权限处理类)中进行处理.这里举一些例子,代码中注释有对应的描述。
/**
通常情况下使用hasRole和hasAnyRole基本可以满足大部分鉴权需求,但是有时候面对更复杂的场景上述常规表示式无法完成权限认证,Security也为我们提供了解决方案.通过hasPermission()来扩展表达式.使用hasPermission()首先要实现PermissionEvaluator接口。
/**
在请求方法上添加hasPermission示例。
/**
hasPermission可以也可以和其他表达式联合使用。
/**
测试
创建账户这里用户加密使用了Security推荐的bCryptPasswordEncoder方法。
/**
登录USER角色账号,登录成功后我们会获取到身份认证的Token。
访问USER角色的接口,把上一步获取到的Token设置在Headers中,Key为Authorization,我们之前实现的JWTAuthenticationTokenFilter拦截器会根据请求头中的Authorization获取并解析Token。
使用USER角色Token访问ADMIN角色的接口,会被拒绝,告知未授权(暂无权限会进入我们定义的UserAuthAccessDeniedHandler这个类进行处理)。
更换ADMIN角色进行登录并访问ADMIN接口。
项目源码
码云
https://gitee.com/liselotte/spring-boot-security-demo
GitHub:
https://github.com/xuyulong2017/my-java-dem