写在前面
思考:为什么需要鉴权呢?
系统开发好上线后,API接口会暴露在互联网上会存在一定的安全风险,例如:爬虫、恶意访问等。因此,我们需要对非开放API接口进行用户鉴权,鉴权通过之后再允许调用。
准备
spring-boot:2.1.4.RELEASE
spring-security-oauth2:2.3.3.RELEASE(如果要使用源码,不要随意改动这个版本号,因为2.4往上的写法不一样了)
mysql:5.7
效果展示
这边只用了postman做测试,暂时未使用前端页面来对接,下个版本角色菜单权限分配的会有页面的展示
1、访问开放接口 http://localhost:7000/open/hello

2、不带token访问受保护接口 http://localhost:7000/admin/user/info

3、登录后获取token,带上token访问,成功返回了当前的登录用户信息


实现
oauth2一共有四种模式,这边就不做讲解了,网上搜一搜,千篇一律
因为现在只考虑做单方应用的,所以使用的是密码模式。
后面会出一篇SpringCloud+Oauth2的文章,网关鉴权
讲一下几个点吧
1、拦截器配置动态权限

新建一个 MySecurityFilter类,继承AbstractSecurityInterceptor,并实现Filter接口
初始化,自定义访问决策管理器
@PostConstruct
public void init(){
super.setAuthenticationManager(authenticationManager);
super.setAccessDecisionManager(myAccessDecisionManager);
}
自定义 过滤器调用安全元数据源
@Override
public SecurityMetadataSource obtainSecurityMetadataSource() {
return this.mySecurityMetadataSource;
}
先来看一下自定义过滤器调用安全元数据源的核心代码
以下代码是用来获取到当前请求进来所需要的权限(角色)
/**
* 获得当前请求所需要的角色
* @param object
* @return
* @throws IllegalArgumentException
*/
@Override
public Collection getAttributes(Object object) throws IllegalArgumentException {
String requestUrl = ((FilterInvocation) object).getRequestUrl();
if (IS_CHANGE_SECURITY) {
loadResourceDefine();
}
if (requestUrl.indexOf("?") > -1) {
requestUrl = requestUrl.substring(0, requestUrl.indexOf("?"));
}
UrlPathMatcher matcher = new UrlPathMatcher();
List