从零开始SpringCloud Alibaba实战(33)——客户端安全验证

在文章article服务下添加一下依赖

	<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.security.oauth.boot</groupId>
                    <artifactId>spring-security-oauth2-autoconfigure</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--springboot 2.1.3 版本 可能不兼容 spring-security-oauth2-autoconfigure:2.1.0.M4 低版本吧
        所以我在上边排除spring-security-oauth2-autoconfigure 依赖-->
        <dependency>
            <groupId>org.springframework.security.oauth.boot</groupId>
            <artifactId>spring-security-oauth2-autoconfigure</artifactId>
            
        </dependency>

添加**WebSecurityConfig **



@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 安全拦截机制(最重要)
     *
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                //所有/r/**的请求必须认证通过
                .antMatchers("/r/**").authenticated()
                //除了/r/**,其它的请求可以访问
                .anyRequest().permitAll();
    }
}

====================================================================

资源服务器配置
@EnableResourceServer 注解到一个 @Configuration 配置类上,并且必须使用 ResourceServerConfigurer 这个配置对象来进行配置(可以选择继承自 ResourceServerConfigurerAdapter 然后覆写其中的方法,参数就是这个对象的实例),下面是一些可以配置的属性:

ResourceServerSecurityConfigurer中主要包括:

tokenServices:ResourceServerTokenServices 类的实例,用来实现令牌服务。
tokenStore:TokenStore类的实例,指定令牌如何访问,与tokenServices配置可选
resourceId:这个资源服务的ID,这个属性是可选的,但是推荐设置并在授权服务中进行验证。
其他的拓展属性例如 tokenExtractor 令牌提取器用来提取请求中的令牌。



@Configuration
@EnableResourceServer //自动增加了一个类型为 OAuth2AuthenticationProcessingFilter 的过滤器链
public class ResouceServerConfig extends ResourceServerConfigurerAdapter {

    /**
     * 客户端访问的资源列表
     */
    public static final String RESOURCE_ID = "res1";

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources
                //客户端访问的资源列表
                .resourceId(RESOURCE_ID)
                //验证令牌的服务
                .tokenServices(tokenService())
                .stateless(true);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/**").access("#oauth2.hasScope('all')");
        http
                // 关闭 csrf
                .csrf().disable()
                //不创建session不使用session
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

}

验证token
ResourceServerTokenServices 是组成授权服务的另一半,如果你的认证授权服务和资源服务在同一个应用程序上的话,你可以使用 DefaultTokenServices ,这样的话,你就不用考虑关于实现所有必要的接口的一致性问题。如果你的资源服务器是分离开的,那么你就必须要确保能够有匹配认证授权服务提供的 ResourceServerTokenServices,它知道如何对令牌进行解码。

令牌解析方法: 使用 DefaultTokenServices 在资源服务器本地配置令牌存储、解码、解析方式 使用
RemoteTokenServices 资源服务器通过 HTTP 请求来解码令牌,每次都请求认证授权服务器端点 /oauth/check_token

使用认证授权服务的 /oauth/check_token 端点,你需要在认证授权服务将这个端点暴露出去,以便资源服务可以进行访问,这里在上一篇文章中已经提到了。
服务 ResouceServerConfig 中添加代码

  /**
     * 资源服务令牌解析服务
     *
     * @return
     */
    @Bean
    public ResourceServerTokenServices tokenService() {
        //使用远程服务请求授权服务器校验token,必须指定校验token 的url、client_id,client_secret
        RemoteTokenServices service = new RemoteTokenServices();
        service.setCheckTokenEndpointUrl("http://localhost:8080/auth/oauth/check_token");
        //客户端id
        service.setClientId("c1");
        //客户端密钥
        service.setClientSecret("secret");
        return service;
    }

注意 service.setCheckTokenEndpointUrl(“http://localhost:8080/auth/oauth/check_token”);
要根据自己项目url来。

测试
启动 auth 服务 , 启动 文章服务

首先我们先来访问 文章服务中的 controller接口 localhost:8081/article/r/r1

直接报401的错误,并且提醒我们:Full authentication is required to access this resourceFull authentication is required to access this resource(访问此资源需要完全身份验证)

因为我们刚才访问的时候没有携带token,所以平台A就不能拿到张三的个人信息,平台A只能去申请令牌,才能继续访问。

上一篇文章中 auth 认证授权服务 已经写完认证授权功能,这里为了演示方便,我就不采取客户端模式,直接用密码模式来演示。

申请令牌
在这里插入图片描述
响应结果

{
“access_token”: “148ec1b5-26ce-4b0a-89d0-45fd6155a7a5”,
“token_type”: “bearer”,
“refresh_token”: “a5c199ca-3caf-45a0-85f1-9e43040a8f10”,
“expires_in”: 39859,
“scope”: “all”
}

请求资源
按照oauth2.0协议要求,请求资源需要携带token,如下:
token的参数名称为:Authorization,值为:Bearer access_token值。

注意:在写,Bearer access_token 的时候中间是有一个空格的,
并且请求的参数是放在 headers 里面。
在这里插入图片描述
如果token错误(少写一个5),则授权失败

接着测试
修改centroller中的方法,添加一个权限 @PreAuthorize(“hasAnyAuthority(‘p2’)”)


    @GetMapping(value = "/r1")
    @PreAuthorize("hasAnyAuthority('p2')")
    public String r1() {
        return "张三的个人信息";
    }

先校验一下token,


响应的数据

{
“aud”: [
“res1”
],
“exp”: 1612116736,
“user_name”: “zhangsan”,
“authorities”: [
“admin”,
“p1”
],
“client_id”: “c1”,
“scope”: [
“all”
]
}
在这里插入图片描述
我们发现 token:148ec1b5-26ce-4b0a-89d0-45fd6155a7a5 的权限是admin 和p1
但是controller中的方法是: @PreAuthorize(“hasAnyAuthority(‘p2’)”)

重启article 服务

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值