Springboot整合Spring Security Oauth2.0 + JWT (二)

上片文章已经整合Spring Security Springboot整合Spring Security Oauth2.0 + JWT (一),由于现在开发的项目基本上都是前后端分离,所以选择采用的Spring Security Oauth2.0。

整合Oauth2.0

在第一篇的基础之上实现
添加依赖

<dependency>
    <groupId>org.springframework.security.oauth.boot</groupId>
    <artifactId>spring-security-oauth2-autoconfigure</artifactId>
    <version>2.2.6.RELEASE</version>
</dependency>
编写认证服务器AuthorizationServerConfiguration继承AuthorizationServerConfigurerAdapter

(一)基于内存存储用户信息和令牌

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Bean
    public TokenStore tokenStore(){
        //基于内存存储令牌
        return new InMemoryTokenStore();
    }

    /**
     * 配置客户端信息
     * @param clients
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        //基于内存存储
        clients.inMemory()
                .withClient("clientId")//客户端标识
                .secret(passwordEncoder.encode("secret"))//客户端安全码
                .authorizedGrantTypes("authorization_code","password","refresh_token")//客户端授权类型
                .scopes("app")//客户端授权范围
                .redirectUris("http://www.baidu.com");//注册回调地址
    }
}

通过Get请求访问认证服务器获取授权码,这儿根据上面配置的客户端信息

http://localhost:8088/oauth/authorize?client_id=clientId&response_type=code

根据登录表单提交验证后
在这里插入图片描述

会跳转到之前配置的回调地址,并在后面返回一个授权码
在这里插入图片描述

拿到授权码后通过Post请求访问认证服务器获取令牌access_token
在这里插入图片描述
被拦截了-_-||,通过配置httpSecurity里面放行/oauth/**,不过没什么卵用,但是采用下面url请求就可以,原理还没搞清楚,需要研究下

http://clientId:secret@localhost:8088/oauth/token
携带参数 code:gvUye7 grant_type:authorization_code

在这里插入图片描述
看过其他博客,可以在认证服务器里面添加令牌端点约束解决这个问题的

/**
     * 配置令牌端点的安全约束
     * @param security
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security
                .tokenKeyAccess("permitAll()")//tokenKey这个endpoint完全公开
                .checkTokenAccess("permitAll()")//checkToken这个endpoint完全公开
                .allowFormAuthenticationForClients();//允许表单验证
    }

这样子过后可以添加参数拿到token了,并能使用check_token来查看token信息
在这里插入图片描述
在这里插入图片描述
上面的方式是采用授权码模式获取的token,采用密码模式测试一下
在这里插入图片描述
提示Unsupported grant type,字面意思是不支持的授权类型,原因是密码模式需要在认证服务器中配置AuthenticationManager,参考OAuth2密码模式提示Unsupported grant type: password
WebSecurityConfiguration类中添加

	@Bean
    @Override
    protected AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }

在认证管理器的令牌端点配置中添加

@Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(tokenStore())
                .authenticationManager(authenticationManager);
    }

运行发现正确拿到token
在这里插入图片描述

默认的端点URL

/oauth/authorize:授权端点
/oauth/token:令牌端点
/oauth/confirm_access:用户确认授权提交端点
/oauth/error:授权服务错误信息端点
/oauth/check_token:用于资源服务访问的令牌解析端点

(二)通过JDBC存储客户端信息和令牌
建立Oauth数据库表,直接用官方的SQL表结构 SQL表结构,这里面有sql语句,直接copy执行就好了。关于OAuth2相关数据表字段的详细说明可以参考OAuth2 数据库表说明文档
有张名为oauth_clients_details的表用于存储客户端信息的,在这里先配置它,跟上面代码内存配置的差不多
在这里插入图片描述
配置认证服务器

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

    @Resource
    private DataSource dataSource;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Bean
    public TokenStore tokenStore() {
        //基于jdbc存储token
        return new JdbcTokenStore(dataSource);
    }

    /**
     * 令牌端点,设置令牌
     *
     * @param endpoints
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(tokenStore())
                .authenticationManager(authenticationManager);
    }

    /**
     * 基于jdbc存储客户端信息,需要先进行配置
     *
     * @return
     */
    public ClientDetailsService clientDetailsService() {
        return new JdbcClientDetailsService(dataSource);
    }

    /**
     * 配置客户端信息
     *
     * @param clients
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.withClientDetails(clientDetailsService());
    }

    /**
     * 配置令牌端点的安全约束
     * @param security
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security
                .tokenKeyAccess("permitAll()")//tokenKey这个endpoint完全公开
                .checkTokenAccess("permitAll()")//checkToken这个endpoint完全公开
                .allowFormAuthenticationForClients();//允许表单验证
    }
}

根据数据库的配置,同样访问/oauth/authorize接口,得到下面的结果
在这里插入图片描述
拿到code后跟之前一样操作获取token,不过client_id和client_secret要和自己配置的一样

编写资源服务器ResourceServerConfiguration 继承ResourceServerConfigurerAdapter

这个案例为单体架构的项目,认证服务器和资源服务器放到一起的。做分布式架构的项目时候可以将它们独立分开来,做一个认证服务器,每个微服务都是一个资源服务器

@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

    //资源id,这个资源id,数据库客户端表配置的需要有这个
    public static final String RESOURCE_ID = "res";

    @Autowired
    private TokenStore tokenStore;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.tokenStore(tokenStore)
                .resourceId(RESOURCE_ID)
                .stateless(false);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .anyRequest().authenticated().and()
                .requestMatchers().antMatchers("/api/**");
    }
}

用前面的方式拿到token以后,每一次请求携带token
在这里插入图片描述
访问有权限的接口正常的
在这里插入图片描述
由于该接口资源上添加了某权限标识,当前登录用户没有该权限

此时的项目结构
在这里插入图片描述
整合的Jwt在下篇文章
Springboot整合Spring Security Oauth2.0 + JWT (三)

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值