美文网首页Spring cloud
spring security oauth2 入门 密码模式

spring security oauth2 入门 密码模式

作者: 蔺荆门 | 来源:发表于2018-09-26 09:51 被阅读185次

    前言

    ​ 想了半天,其实没有什么前言,这篇文章就是讲基于oauth2的密码模式实现spring boot程序的基本授权和保护,带大家跑一下流程,帮助大家认识了解一下这个东西。

    准备

    ​ spring boot 的版本:

    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.15.RELEASE</version>
    <relativePath/> 
    </parent>
    

    开始

    1. 添加依赖

    ​ 主要就是添加spring security oauth2的依赖,其他的依赖就根据自己的业务,需要什么添加什么,爱咋咋地

    <dependency>
    <groupId>org.springframework.security.oauth</groupId>
    <artifactId>spring-security-oauth2</artifactId>
    </dependency>
    

    2. 编写配置

    ​ 在这块呢,需要对oauth 2标准有一定的了解。如果没有了解过的话去网上看看资料,很简单的。那我们需要配置的是授权服务器、资源服务器和客户端。虽然一般对于oauth的教程里面都会说,授权服务器和资源服务器只是概念上的区别,实际上可以放在同一台机器上,事实上确实是如此,但是我觉得大家初学oauth 2的话还是把它分开理解。
    我们来举个例子搭建一下概念。现在前后端分离很普遍,我们就以这个举例子。公司需要做一个项目,前端项目和后端项目分离,假定需要保护的资源就是api接口别无其他,那对应oauth 2里面的角色就是下面这种:
    资源服务器:提供api接口的服务器
    资源所有者:用户,资源是用户的但只是放在你的服务器上,不要会错意好吧,毕竟用户的账号密码只有他知道
    第三方客户端:前端项目,用户通过前端项目访问自己的资源(api接口)
    认证服务器:想象成一台单独的服务器,专门来认证,通过就发token,不通过就挡回去

    ​ 整个流程呢,大家看过oauth标准的一些资料以后也都心里有数了,我就只文字上的描述一下。资源所有者(用户)通过第三方客户端(前端界面)向认证服务器发认证请求,认证服务器验证通过后发一个token给第三方客户端,然后第三方客户端拿着token就去找资源服务器(后端项目)去换资源(调用api接口)。

    ​ 想要认证服务器给自己token的话,有四种方法大家也都了解了,这篇文章只讲密码模式,其他三种模式呢,后续再写。现在我们开始写配置了,大家可以在项目里面单独建立一个新包,专门用来配置oauth 2,也可以新建一个项目或模块再引入到业务项目中也可以,大家自己决定,爱咋咋地。

    • 认证服务器配置
      新建一个类
    @Configuration
    @EnableAuthorizationServer
    public class AuthorizationServerConfig {
    
    }
    

    EnableAuthorizationServer注解让这个项目成为了认证服务器,Configuration注解表明了这个类里面写的东西是一些配置,需要高冷的spring看一眼并照做。
    就这样,认证服务器就搭好了。

    • 资源服务器
      新建一个类
    @Configuration
    @EnableResourceServer
    public class ResourceServerConfig {
    
    }
    

    和认证服务器一毛一样,只是EnableResourceServer注解让这个项目成为了资源服务器。
    资源服务器搭好了。

    ​ 说了你可能不信,在正常情况下,现在你的项目已经被spring security oauth2掌管了,现在你去访问你的api会被oauth 2怼回来,如下显示

    <oauth>
    <error_description>
    Full authentication is required to access this resource
    </error_description>
    <error>unauthorized</error>
    </oauth>
    

    ​ 方才我说的是正常情况,如果你的IDE控制台打印了下面这三个配置信息就属于正常情况了,否则就不正常,自己重新看一下上面那两个类,总共六行代码,我写的比较漂亮算十行。这六行代码除了类名你爱咋咋地,其他的都和我的保持一致、spring boot版本再一致应该就没问题了,如果还有问题,留言给我。

    Using default security password: 433e73a0-c8c4-4733-a812-e4eb71103122
    ...
    security.oauth2.client.client-id = 6b620856-fc0e-4aca-b2a2-c2fce49fb954
    security.oauth2.client.client-secret = 7dc2044b-6872-40f6-b80e-78673444d158
    

    3. 获取token,访问资源

    ​ 我们使用一些工具来获取token,像postmanrestlet client插件等等。具体流程就是带上指定的参数,POST方式访问${项目根地址}/oauth/token就可以拿到token了。在获取token之前呢,很多教程直接扒拉一下参数,然后用curl或者其他工具咣当一下就搞定了,这里从我的当初学艺的经验来看,我觉得有个事儿需要掰扯一下,就是http basic认证。

    • http basic认证
      大家用Chrome打开刚才我说获取token那个连接,我的项目根路径就是http://localhost:8080,我就访问http://localhost:8080/oauth/token,会得到一个弹窗像这样 弹窗
      这个弹窗就是http basic认证。关于http basic的资料网上也有很多,我这里说一下待会我们会用到的知识,就是我们在刚才那个弹窗中输入用户名和密码点击登录后,浏览器会帮我们输入的用户名和密码做一个Base 64位编码,并将结果处理后添加到请求头中再发送出去。怎么编码的呢,就是把我们输入的用户名和密码按照username:password的格式组装成字符串,例如用户名为zhangsan密码为123456组装成zhangsan:123456,把这个字符串做Base 64位编码,得到一个字符串xxxxxx,之后在这个字符串前面添加一个前缀Basic得到Basic xxxxxx,最后把得到的字符串添加到请求头Authorization中。知道了浏览器会帮我们做什么之后,我们自己把用户名和密码组织好再编码并处理之后添加到请求头Authorization中,这样我们发送请求的时候就可以直接通过http basic验证,而不会看到弹窗要求我们输入信息从而使我们获取token变得一气呵成。

    讲清楚了如何通过http basic那我们获取token的过程应该不会有啥疑惑的了,让我们开始吧。我使用的是Chrome的插件restlet client,你们会用啥用啥,不要求。打开插件后注册登录就可以使用了,我这里不演示了。

    1. 新建一个POST请求


      post请求
    2. 输入网址和参数

      网址和参数
      关于参数我们看一下官网上的说明
      官网参数
      这四个参数中,grant_typeusername现在是固定的,grant_type写password是代表使用密码模式,username写user是spring security默认的,之后可以改。password在控制台上可以找到,Using default security password: 433e73a0-c8c4-4733-a812-e4eb71103122像这样的。scope现在可以任意填,这个参数是管第三方客户端的权限的,如果指定某些资源需要指定的scope才可以访问的话,不具有该scope第三方客户端就不能访问。
    3. http basic认证
      在这个环节,可以用工具提供的功能生成,也可以自己按照上面说的方法生成然后自行添加到header里面。

    • 使用工具提供的功能


      使用工具认证

      点击以后弹出



      输入用户名密码后点击set生成即可。和上面参数中的username和password有所区别就是,上面的username和password是我们数据库中的用户数据(当然现阶段由spring给我们默认生成),这里的username和password是控制台中打印的client-id和client-secret(我们后面也可以通过配置指定)。这里是表明哪个客户端在请求授权,上面参数中是表明哪个用户在请求授权。
      结果
    • 自己生成
      用js或者java都可以轻松的加密和解密Base64数据,把client-id和client-secret按照规则写成client-id:client-secret,Base64加密,然后加上前缀得到Basic xxxxxx,注意Basic和加密数据用一个空格隔开,最后放到header里面,key值为Authorization是固定不能变的。
    1. 发送请求


      发送请求

      这样就拿到access_token了

    2. 访问api接口
      拿到token之后呢,我们就可以访问接口了。访问的方式有两种,第一种就是参数中传入access_token,第二种就是在请求头Authorization中放入token的值,但是要注意格式。
      • 参数中传入
        参数里面放入access_token访问api接口即可
      • 请求头
        上面我们最终获取到token的时候,我们同时得到了一个token_typebearer是吧,那我们就像通过http basic认证一样,在请求头Authorization中放入token_type access_token格式的字符串,我这里就写bearer 07a06a24-d3c7-48bf-8a65-5dd315ab6eba,写好之后发送请求即可

    到此呢我们就完成了token的获取和资源的访问。

    4. 遗留的问题和后记

    ​ 文章中我遗留了一些问题,像如何不使用spring给我们默认的那个用户名和密码而使用我们数据库的用户、自己配置client-id和client-secret。这两个问题,你们可以自己去摸索一下,我下次讲,我想想怎么和你讲你们更好理解。

    ​ 回想我当初学这个的时候,在网上看了好多文章,很多入门级的教程一贴代码就把一些配置(很基础的配置)也带上了,虽然有些前辈也在代码里面写了一些注释,但是我总觉得我不清楚为什么这么写就照抄心里很是不踏实。我写这篇文章呢,讲的东西很简单,但是我想让对于spring security oauth2零基础的同学们学到一点就知道是怎么回事。不清楚的问题给我留言,我会完善。

    ​ 东西不多,但是我想讲清楚,就是这么回事。

    ​ 拜拜。。。

    相关文章

      网友评论

        本文标题:spring security oauth2 入门 密码模式

        本文链接:https://www.haomeiwen.com/subject/xonkoftx.html