网站源码分享授权程序,收录网站源码授权

大家好,感谢邀请,今天来为大家分享一下网站源码分享授权程序的问题,以及和收录网站源码授权的一些困惑,大家要是还不太明白的话,也没有关系,因为接下来将为大家分享,希望可以帮助到大家,解决大家的问题,下面就开始吧!

理论

OAuth是一个关于授权(authorization)的开放网络标准,用来授权第三方应用获取用户数据,是目前最流行的授权机制,它当前的版本是2.0。

应用场景

假如你正在“网站A”上冲浪,看到一篇帖子表示非常喜欢,当你情不自禁的想要点赞时,它会提示你进行登录操作。

打开登录页面你会发现,除了最简单的账户密码登录外,还为我们提供了微博、微信、QQ等快捷登录方式。假设选择了快捷登录,它会提示我们扫码或者输入账号密码进行登录。

登录成功之后便会将QQ/微信的昵称和头像等信息回填到“网站A”中,此时你就可以进行点赞操作了。

名词定义

在详细讲解oauth2之前,我们先来了解一下它里边用到的名词定义吧:

Client:客户端,它本身不会存储用户快捷登录的账号和密码,只是通过资源拥有者的授权去请求资源服务器的资源,即例子中的网站A;ResourceOwner:资源拥有者,通常是用户,即例子中拥有QQ/微信账号的用户;AuthorizationServer:认证服务器,可以提供身份认证和用户授权的服务器,即给客户端颁发token和校验token;ResourceServer:资源服务器,存储用户资源的服务器,即例子中的QQ/微信存储的用户信息;

认证流程

如图是oauth2官网的认证流程图,我们来分析一下:

A客户端向资源拥有者发送授权申请;B资源拥有者同意客户端的授权,返回授权码;C客户端使用授权码向认证服务器申请令牌token;D认证服务器对客户端进行身份校验,认证通过后发放令牌;E客户端拿着认证服务器颁发的令牌去资源服务器请求资源;F资源服务器校验令牌的有效性,返回给客户端资源信息;

为了大家更好的理解,阿Q特地画了一张图:

到这儿,相信大家对理论知识已经掌握得差不多了,接下来我们就进入实战训练吧。

实战

在正式开始搭建项目之前我们先来做一些准备工作:要想使用oauth2的服务,我们得先创建几张表。

数据库

oauth2相关的建表语句可以参考官方初始化sql,也可以查看阿Q项目中的init.sql文件,私信回复“oauth2”获取源码。

至于表结构,大家可以先大体了解下,其中字段的含义,在init.sql文件中阿Q已经做了说明。

oauth_client_details:存储客户端的配置信息,操作该表的类主要是JdbcClientDetailsService.java;oauth_access_token:存储生成的令牌信息,操作该表的类主要是JdbcTokenStore.java;oauth_client_token:在客户端系统中存储从服务端获取的令牌数据,操作该表的类主要是JdbcClientDetailsService.java;oauth_code:存储授权码信息与认证信息,即只有grant_type为authorization_code时,该表才会有数据,操作该表的类主要是JdbcAuthorizationCodeServices.java;oauth_approvals:存储用户的授权信息;oauth_refresh_token:存储刷新令牌的refresh_token,如果客户端的grant_type不支持refresh_token,那么不会用到这张表,操作该表的类主要是JdbcTokenStore;

在oauth_client_details表中添加一条数据

client_id:cheetah_one//客户端名称,必须唯一\nresource_ids:product_api//客户端所能访问的资源id集合,多个资源时用逗号(,)分隔\nclient_secret:$2a$10$h/TmLPvXozJJHXDyJEN22ensJgaciomfpOc9js9OonwWIdAnRQeoi//客户端的访问密码\nscope:read,write//客户端申请的权限范围,可选值包括read,write,trust。若有多个权限范围用逗号(,)分隔\nauthorized_grant_types:client_credentials,implicit,authorization_code,refresh_token,password//指定客户端支持的grant_type,可选值包括authorization_code,password,refresh_token,implicit,client_credentials,若支持多个grant_type用逗号(,)分隔\nweb_server_redirect_uri:http://www.baidu.com//客户端的重定向URI,可为空,当grant_type为authorization_code或implicit时,在Oauth的流程中会使用并检查与注册时填写的redirect_uri是否一致\naccess_token_validity:43200//设定客户端的access_token的有效时间值(单位:秒),可选,若不设定值则使用默认的有效时间值(60*60*12,12小时)\nautoapprove:false//设置用户是否自动Approval操作,默认值为&39;,可选值包括&39;,&39;,&39;,&39;\n

数据库中对密码进行了加密处理,大家可以在此路径下自行生成

用户角色相关的表也在init.sql文件中,表结构非常简单,大家自行查阅。我的初始化数据为

依赖引入

<dependency>\n<groupId>org.springframework.boot</groupId>\n<artifactId>spring-boot-starter-web</artifactId>\n</dependency>\n<dependency>\n<groupId>org.springframework.cloud</groupId>\n<artifactId>spring-cloud-starter-security</artifactId>\n</dependency>\n<dependency>\n<groupId>org.springframework.cloud</groupId>\n<artifactId>spring-cloud-starter-oauth2</artifactId>\n</dependency>\n<dependency>\n<groupId>org.springframework.security</groupId>\n<artifactId>spring-security-jwt</artifactId>\n</dependency>\n

至于其它依赖,大家可以根据需要自行引入,不再赘述,回复“oauth2”获取源码。

资源服务

配置文件对服务端口、应用名称、数据库、mybatis和日志进行了配置。

写了一个简单的控制层代码,用来模拟资源访问

@RestController\n@RequestMapping(&34;)\npublicclassProductController{\n\n@GetMapping(&34;)\npublicStringfindAll(){\nreturn&34;;\n}\n}\n

接着创建配置类继承ResourceServerConfigurerAdapter并增加@EnableResourceServer注解开启资源服务,重写两个configure方法

/**\n*指定token的持久化策略\n*InMemoryTokenStore表示将token存储在内存中\n*RedisTokenStore表示将token存储在redis中\n*JdbcTokenStore表示将token存储在数据库中\n*@return\n*/\n@Bean\npublicTokenStorejdbcTokenStore(){\nreturnnewJdbcTokenStore(dataSource);\n}\n\n/**\n*指定当前资源的id和token的存储策略\n*@paramresources\n*@throwsException\n*/\n@Override\npublicvoidconfigure(ResourceServerSecurityConfigurerresources)throwsException{\n//此处的id可以写在配置文件中,这里我们先写死\nresources.resourceId(&34;).tokenStore(jdbcTokenStore());\n}\n\n\n/**\n*设置请求权限和header处理\n*@paramhttp\n*@throwsException\n*/\n@Override\npublicvoidconfigure(HttpSecurityhttp)throwsException{\n//固定写法\nhttp.authorizeRequests()\n//指定不同请求方式访问资源所需的权限,一般查询是read,其余都是write\n.antMatchers(HttpMethod.GET,&34;).access(&oauth2.hasScope(&39;)&34;/**&34;39;write&34;)\n.antMatchers(HttpMethod.PATCH,&34;).access(&oauth2.hasScope(&39;)&34;/**&34;39;write&34;)\n.antMatchers(HttpMethod.DELETE,&34;).access(&oauth2.hasScope(&39;)&34;Access-Control-Allow-Origin&34;*&34;OPTIONS&34;Access-Control-Allow-Methods&34;Access-Control-Allow-Methods&34;Access-Control-Allow-Headers&34;Access-Control-Allow-Headers&34;/login*&34;/css/*&34;/login.html&34;/login&34;isAuthenticated()&34;error&34;unauthorized&34;error_description&34;Fullauthenticationisrequiredtoaccessthisresource&34;/findAll&34;ROLE_PRODUCT&34;产品列表查询成功&34;ROLE_PRODUCT”));\nreturnsysUser;\n}\n\n

然后测试会发现可以正常访问。

采坑

包名问题

当我在创建项目的时候,给product和server两个模块设置了不同的包名,导致发送请求获取资源时报错。

经过分析得知,在登录账号时会将用户的信息存储到oauth_access_token表的authentication中,在进行token校验时会根据token_id取出该字段进行反序列化,如果此时发现包名不一致便会导致解析token失败,因此请求资源失败。

解决思路

两个项目的包名改为一致;可以将用户和权限的实体抽成单独的模块,供其它模块引用;loadUserByUsername方法中使用的用户实体类不需要继承UserDetailsService类,每次返回时用user类包装一下即可;

数据库问题

当我在进行权限校验测试时,在设置权限时发现少打了一个单词,导致请求一直出错。修改完成之后继续请求,仍提示权限不足。

于是我将数据库中oauth_refresh_token和oauth_access_token的数据清除,重新开始测试就可以了。

个人认为是生成token时发现数据库中token存在,故不刷新token,但进行校验时却用带有权限标识的token前去校验导致失败。

至于其它的小坑在这不再赘述,如果遇到问题,建议按照流程对比我的源码仔细检查,回复“oauth2”获取源码。

小结

本文从原理、应用场景、认证流程出发,对oauth2进行了基本的讲解,并且手把手带大家完成了项目的搭建。大家在对授权码模式、简化模式、密码模式、客户端模式进行测试的同时要将重点放到授权码模式上。

原文:https://mp.weixin.qq.com/s/BNA42Agb_RFFiXJ8mlfhqw

作者:阿Q说代码

如果感觉本文对你有帮助,点赞关注支持一下

OK,本文到此结束,希望对大家有所帮助。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平