代码地址与接口看总目录;【学习笔记】记录冷冷-pig项目的学习过程;大概包括Authorization Server、springcloud、Mybatis Plus~~~_清晨敲代码的博客-CSDN博客
目录
A1.框架搭建
A2.代码实现
B1.配置类
B2.accesstoken认证核心类
B3.端点类
首先;请求接口时只携带并解析accesstoken;使用授权服务端默认的OAuth2TokenIntrospectionEndpointFilter过滤器;无用户持久化操作;仅认证无鉴权;
仅作为最基本的资源服务端。
注意;授权服务端、资源服务端、客户端;我的理解是;
资源服务器是跟随授权服务端搭建的;可以和授权服务共属于同一个系统环境下;例如数据库可共用、公共包可共用。
而第三方客户端大多不是;第三方客户端大多和授权服务器无任何关系;只是通过授权联系起来;客户端应该有自己的一套认证与权限;例如我们开发一个系统;其中可以使用gitee认证登录时;我们的系统和gitee是没有任何关系的;只是能够通过gitee的用户授权拿到gitee的accesstoken然后并携带着访问gitee公开的接口而已。
按照pig项目框架搭建即可;当前需要的都有是;
“#”符号表示重点的包名
com.pig4cloud.pig
├── pig-common // 框架核心模块
│ └── pig-common-bom // 定义common全局jar版本模块
│ └── pig-common-common // 公共工具类核心模块
│ └── # constant // 公共常量包
│ └── # util // 公共工具包
│ └── pig-common-security // 安全工具模块
│ └── # annotation // 安全注解包
│ └── # component // 安全组件包;包括配置等
│ └── # util // 安全工具包
├── pig-upms // 通用用户权限管理聚合模块
│ └── pig-upms-api // 通用用户权限管理系统公共api模块
│ └── pig-upms-biz // 通用用户权限管理系统业务处理模块
│ └── # controller // 业务端点包
现在主要就是pig-auth包实现核心代码
最重要会涉及到一个过滤器;BearerTokenAuthenticationFilter;进行accesstoken认证;
整体流程是;拿到accesstoken;然后向授权服务器获取到授权信息;包括用户信息;;拿到后可以选择根据授权信息和用户信息确认UserDetails;这里的确认是从持久层中确认;;然后封装成BearerTokenAuthentication并存到SecurityContextHolder里面;然后执行后面filter。
注意;
授权服务端会提供一个默认的OAuth2TokenIntrospectionEndpointFilter过滤器来拦截“/oauth2/introspect”令牌自省端点;在这个过滤器中校验后并返回授权信息。
默认该端点是需要认证权限的;可以设置端点权限为permit。
如果是要认证那么需要资源服务端提供客户端信息;Basic/POST/其他方式;;然后会在授权服务端的OAuth2ClientAuthenticationFilter里面拿到并认证;之后才会顺利通过FilterSecurityInterceptor过滤器;进入OAuth2TokenIntrospectionEndpointFilter。
所以整体逻辑是;先写配置类;想好都需要哪些自定义类;先将配置文件补充完整;然后在去补充自定义代码逻辑。
1.配置类和自定义accesstoken认证类都可以写到统一的安全模块;
2.授权服务端需要提供通过accesstoken拿到授权信息接口;
3.资源服务端提供资源接口;
C1.PigResourceServerConfiguration
;Configuration
//;EnableWebSecurity
;RequiredArgsConstructor
public class PigResourceServerConfiguration {
private final PermitAllUrlProperties permitAllUrlProperties;
private final BearerTokenResolver pigBearerTokenExtractor;
;Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
//配置端点白名单方放行
//配置资源服务信息
//配置accesstoken提取器
//配置token自省器
//忽略掉相关端点的 csrf
return http.build();
}
}
C2.PigResourceServerAutoConfiguration
;RequiredArgsConstructor
;EnableConfigurationProperties(PermitAllUrlProperties.class)
public class PigResourceServerAutoConfiguration {
/**
* ;Description: 请求令牌的提取逻辑
* ;param urlProperties 对外暴露的接口列表
* ;Return: com.pig4cloud.pig.common.security.component.PigBearerTokenExtractor
*/
;Bean
public PigBearerTokenExtractor pigBearerTokenExtractor(PermitAllUrlProperties urlProperties) {
//new一个请求令牌的提取逻辑器
return new PigBearerTokenExtractor(urlProperties);
}
}
C3.;EnablePigResourceServer
这个是资源服务器注解;由于资源服务器可能会有多个;而且其中的安全配置有大多相同;所以可以在security公共安全包里编写一个配置类;然后通过注解添加到各个资源服务器中进行使用;这样更方便
;Documented
;Inherited //;Inherited修饰的注解的;Retention是RetentionPolicy.RUNTIME;则增强了继承性;在反射中可以获取得到
;Target({ElementType.TYPE})
;Retention(RetentionPolicy.RUNTIME)
;EnableGlobalMethodSecurity(prePostEnabled = true)
;Import({PigResourceServerConfiguration.class, PigResourceServerAutoConfiguration.class})
public ;interface EnablePigResourceServer {
}
C1.PigBearerTokenExtractor
BearerTokenResolver的功能主要是拿到请求里的accesstoken;为什么要自定义一个类实现BearerTokenResolver呢?默认提供的DefaultBearerTokenResolver;有正则匹配的类型;;^Bearer (?<token>[a-zA-Z0-9-._~;/];=*)$;;;而现在用的accesstoken的形式是Bearer clientId::username::UUID;不能匹配上;需要稍加改造;并且我们可以再添加多个类型的校验;防止伪造。
public class PigBearerTokenExtractor implements BearerTokenResolver {
;Override
public String resolve(HttpServletRequest request) {
//校验请求路径;是白名单直接返回null
//校验hearder里的accesstoken格式是否匹配;并返回token
//校验请求方式是否是GET/POST;是就从参数中获取accesstoken;并返回token
//判断如果headertoekn不是空
//如果parametertoekn不是空则抛出多个accesstoken异常
//如果parametertoekn是空则返回headertoekn
//如果parametertoekn不是空并且支持参数的token;则返回parameteken
//都是空则返回null
return null;
}
}
C2.OpaqueTokenIntrospector
携带token去授权服务端获取对应的有效用户信息;可以使用默认的实现类SpringOpaqueTokenIntrospector或者NimbusOpaqueTokenIntrospector;使用这个类需要引入<artifactId>oauth2-oidc-sdk</artifactId>;
这两个类;都会在携带token的基础上携带BasicAuthentication;去访问授权服务端的令牌自行端点。端点和客户端信息是在PigResourceServerConfiguration里面配置的哦。
如果想自定义该类并且不想携带客户端信息;可以去授权服务端;设置“/oauth2/introspect”端点权访问权限为permit。
C1.AuthenticatedController
访问权限是 authenticated 的权限;可以获取到SecurityContextHolder.getContext().getAuthentication()
C2.PermitController
访问权限是permit的权限