当前位置:实例文章 » 其他实例» [文章]No2.搭建基本的资源端解析token(资源服务端);

No2.搭建基本的资源端解析token(资源服务端);

发布人:清晨敲代码 发布时间:2022-12-09 10:07 阅读次数:6

代码地址与接口看总目录:【学习笔记】记录冷冷-pig项目的学习过程,大概包括Authorization Server、springcloud、Mybatis Plus~~~_清晨敲代码的博客-CSDN博客

目录

A1.框架搭建

A2.代码实现

B1.配置类

C1.PigResourceServerConfiguration

C2.PigResourceServerAutoConfiguration

C3.@EnablePigResourceServer

B2.accesstoken认证核心类

C1.PigBearerTokenExtractor

C2.OpaqueTokenIntrospector

B3.端点类

C1.AuthenticatedController

C2.PermitController


首先,请求接口时只携带并解析accesstoken,使用授权服务端默认的OAuth2TokenIntrospectionEndpointFilter过滤器,无用户持久化操作,仅认证无鉴权;

仅作为最基本的资源服务端。

注意:授权服务端、资源服务端、客户端:我的理解是,

资源服务器是跟随授权服务端搭建的,可以和授权服务共属于同一个系统环境下,例如数据库可共用、公共包可共用。

而第三方客户端大多不是,第三方客户端大多和授权服务器无任何关系,只是通过授权联系起来,客户端应该有自己的一套认证与权限,例如我们开发一个系统,其中可以使用gitee认证登录时,我们的系统和gitee是没有任何关系的,只是能够通过gitee的用户授权拿到gitee的accesstoken然后并携带着访问gitee公开的接口而已。

A1.框架搭建

按照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包实现核心代码

A2.代码实现

最重要会涉及到一个过滤器:BearerTokenAuthenticationFilter(进行accesstoken认证)

整体流程是,拿到accesstoken,然后向授权服务器获取到授权信息(包括用户信息),拿到后可以选择根据授权信息和用户信息确认UserDetails(这里的确认是从持久层中确认),然后封装成BearerTokenAuthentication并存到SecurityContextHolder里面,然后执行后面filter。

注意:

授权服务端会提供一个默认的OAuth2TokenIntrospectionEndpointFilter过滤器来拦截“/oauth2/introspect”令牌自省端点,在这个过滤器中校验后并返回授权信息。

默认该端点是需要认证权限的,可以设置端点权限为permit。

如果是要认证那么需要资源服务端提供客户端信息(Basic/POST/其他方式),然后会在授权服务端的OAuth2ClientAuthenticationFilter里面拿到并认证,之后才会顺利通过FilterSecurityInterceptor过滤器,进入OAuth2TokenIntrospectionEndpointFilter。

所以整体逻辑是,先写配置类,想好都需要哪些自定义类,先将配置文件补充完整,然后在去补充自定义代码逻辑。

1.配置类和自定义accesstoken认证类都可以写到统一的安全模块;

2.授权服务端需要提供通过accesstoken拿到授权信息接口;

3.资源服务端提供资源接口;

B1.配置类

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 {
 
}

B2.accesstoken认证核心类

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。

B3.端点类

C1.AuthenticatedController

访问权限是 authenticated 的权限,可以获取到SecurityContextHolder.getContext().getAuthentication()

C2.PermitController

访问权限是permit的权限

相关标签:

免责声明

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱290110527@qq.com删除。

Top