oauth2 password 密码模式获取access_token流程

密码模式(Resource Owner Password Credentials Grant)中,用户向客户端提供自己的用户名和密码。客户端使用这些信息,向"服务商提供商"索要授权。
在这种模式中,用户必须把自己的密码给客户端,但是客户端不得储存密码。这通常用在用户对客户端高度信任的情况下,比如客户端是操作系统的一部分,或者由一个著名公司出品。而认证服务器只有在其他授权模式无法执行的情况下,才能考虑使用这种模式。

(A)用户向客户端提供用户名和密码。

(B)客户端将用户名和密码发给认证服务器,向后者请求令牌。 客户端发出的HTTP请求,包含以下参数:
grant_type:表示授权类型,此处的值固定为"password",必选项。
username:表示用户名,必选项。
password:表示用户的密码,必选项。
scope:表示权限范围,可选项。

(C)认证服务器确认无误后,向客户端提供访问令牌。

快速上手

redis 存储模式
pom

<dependencies><!-- SpringBoot整合Web组件 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!-- springboot整合freemarker --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency><!-->spring-boot 整合security --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId><exclusions><!--旧版本 redis操作有问题--><exclusion><artifactId>spring-security-oauth2</artifactId><groupId>org.springframework.security.oauth</groupId></exclusion></exclusions></dependency><!-- Spring Security OAuth2 --><dependency><groupId>org.springframework.security.oauth</groupId><artifactId>spring-security-oauth2</artifactId><version>2.3.3.RELEASE</version></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.6.0</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.62</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency><!-- redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency></dependencies>

security配置 配置登陆权限

@Component
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.formLogin().permitAll().and().authorizeRequests().antMatchers("/oauth/**").permitAll().anyRequest().authenticated().and().logout().permitAll().and().csrf().disable();}@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}}

service 配置用户名密码

@Service
public class UserService implements UserDetailsService {@Autowiredprivate PasswordEncoder passwordEncoder;public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {String password = passwordEncoder.encode("123456");return new User("admin", password, AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));}
}

redis配置中心

@Configuration
public class RedisConfig {@Autowiredprivate RedisConnectionFactory redisConnectionFactory;@Beanpublic TokenStore tokenStore() {return new RedisTokenStore(redisConnectionFactory);}
}

授权认证

/*** 认证授权Server端*/
@Component
@EnableAuthorizationServer
public class AuthorizationConfig extends AuthorizationServerConfigurerAdapter {@Autowiredprivate PasswordEncoder passwordEncoder;@Autowiredprivate AuthenticationManager authenticationManagerBean;@Autowiredprivate UserService userService;@Autowiredprivate TokenStore tokenStore;@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.authenticationManager(authenticationManagerBean) //使用密码模式需要配置.reuseRefreshTokens(false).tokenStore(tokenStore).userDetailsService(userService)  //refresh_token是否重复使用.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST); //支持GET,POST请求}@Overridepublic void configure(AuthorizationServerSecurityConfigurer security) throws Exception {//允许表单提交security.allowFormAuthenticationForClients().checkTokenAccess("permitAll()");}/*** appid mayikt secret= 123456** @param clients* @throws Exception*/@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {/*** 密码模式获取 token http://localhost:8080/oauth/token?username=admin&password=123456&grant_type=password&client_id=appId&client_secret=123456&scope=all** 刷新密码 http://localhost:8080/oauth/token?grant_type=refresh_token&client_id=appId&client_secret=123456&refresh_token=1b46f93f-af95-4ce6-afae-618eca676ebc*/clients.inMemory()// appid 表里取 这里写死.withClient("appId")// 密钥  表里取 这里写死.secret(passwordEncoder.encode("123456"))// 授权码.authorizedGrantTypes("authorization_code","password","client_credentials","refresh_token")// 作用域.scopes("all")// 资源的id  表里取 这里写死.resourceIds("mayikt_resource")// 回调地址  表里取 这里写死.redirectUris("http://www.mayikt.com/callback");}}

contoller 认证token

@RestController
@RequestMapping("/oauth")
public class AuthorizationContoller {@Autowiredprivate RestTemplate restTemplate;/*** 校验token** @param token* @return*/@GetMapping("/checkToken")public String getCheckToken(String token){String url = "http://localhost:8080/oauth/check_token?token="+token;String forObject = restTemplate.getForObject(url, String.class);return forObject;}
}

yml

spring:redis:database: 0host: 127.0.0.1server:port: 8080

密码模式获取token

密码模式获取 token http://localhost:8080/oauth/token?username=admin&password=123456&grant_type=password&client_id=appId&client_secret=123456&scope=all

refresh_token用来刷新token,刷新后原来的token立即失效

验证token
http://localhost:8080/oauth/checkToken?token=6dd755e7-ab40-4e77-a4ae-60ebba57aeaf

刷新token
刷新后原来的token就会失效
http://localhost:8080/oauth/token?grant_type=refresh_token&client_id=appId&client_secret=123456&refresh_token=1b46f93f-af95-4ce6-afae-618eca676ebc

jwt模式

<!‐‐JWT依赖‐‐><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>
<!‐‐JWT依赖‐‐><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>

Controller类,使用jjwt工具类来解析Authorization头中存储的JWT内容

    @GetMapping("/getCurrentUser")public Object getCurrentUser(Authentication authentication,HttpServletRequest request) {String header = request.getHeader("Authorization");String token = null;if (header != null) {token = header.substring(header.indexOf("bearer") + 7);} else {token = request.getParameter("access_token");}return Jwts.parser().setSigningKey("123123".getBytes(StandardCharsets.UTF_8)).parseClaimsJws(token).getBody();}

config

@Configuration
public class JwtTokenStoreConfig {@Beanpublic TokenStore jwtTokenStore() {return new JwtTokenStore(jwtAccessTokenConverter());}@Beanpublic JwtAccessTokenConverter jwtAccessTokenConverter() {JwtAccessTokenConverter accessTokenConverter = newJwtAccessTokenConverter();//配置JWT使用的秘钥accessTokenConverter.setSigningKey("123123");return accessTokenConverter;}
}

在授权服务器配置中指定令牌的存储策略为JWT

用密码模式测试

扩展JWT中的存储内容

有时候我们需要扩展JWT中存储的内容,这里我们在JWT中扩展一个 key为enhance,value为
enhance info 的数据。
继承TokenEnhancer实现一个JWT内容增强器

public class JwtTokenEnhancer implements TokenEnhancer {@Overridepublic OAuth2AccessToken enhance(OAuth2AccessToken accessToken,OAuth2Authentication authentication) {Map<String, Object> info = new HashMap<>();info.put("enhance", "enhance info");((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(info);return accessToken;}
}

创建一个JwtTokenEnhancer实例

@Beanpublic JwtTokenEnhancer jwtTokenEnhancer() {return new JwtTokenEnhancer();}

在授权服务器配置中配置JWT的内容增强器

@Autowired
private JwtTokenEnhancer jwtTokenEnhancer;@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)throws Exception{//配置JWT的内容增强器TokenEnhancerChain enhancerChain=new TokenEnhancerChain();List<TokenEnhancer> delegates=new ArrayList<>();delegates.add(jwtTokenEnhancer);delegates.add(jwtAccessTokenConverter);enhancerChain.setTokenEnhancers(delegates);endpoints.authenticationManager(authenticationManagerBean) //使用密码模式需要配置.tokenStore(tokenStore) //配置存储令牌策略.accessTokenConverter(jwtAccessTokenConverter).tokenEnhancer(enhancerChain) //配置tokenEnhancer.reuseRefreshTokens(false) //refresh_token是否重复使用.userDetailsService(userService) //刷新令牌授权包含对用户信息的检查.allowedTokenEndpointRequestMethods(HttpMethod.GET,HttpMethod.POST); //支持GET,POST请求}

oauth2整合security(密码模式)相关推荐

  1. oauth2整合security

    什么是oauth2 OAuth 2.0 是一个授权协议,它允许软件应用代表(而不是充当)资源拥有者去访问资源拥有者的资源.应用向资源拥有者请求授权,然后取得令牌(token),并用它来访问资源,并且资 ...

  2. Spring Security Oauth2 之密码模式

    点击关注公众号,实用技术文章及时了解   作者:歪桃   blog.csdn.net/m0_37892044/article/details/113058924 前言,因为最近的项目是用Spring ...

  3. Spring Security Oauth2:授权模式、简单模式 、密码模式 和 客户端模式

    Oauth2的授权模式流程 1.先得到用户的授权grant 2.利用grant得到令牌token 3.根据token获取用户的信息 步骤1:客户端(第三方应用)向用户请求授权. 步骤2:用户单击客户端 ...

  4. OAuth2.0_授权服务配置_密码模式及其他模式_Spring Security OAuth2.0认证授权---springcloud工作笔记145

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 然后我们再去看看密码模式和其他的模式来获取令牌. 我们要知道授权码模式是最安全的一种方式.对吧.验 ...

  5. oauth password模式_SpringBoot OAuth2.0 认证授权(密码模式)

    SpringBoot 整合 SpringSecurity,token 落地,前后端分离接口安全. SpringBoot 环境搭建和入门:Spring Boot 2.x 快速入门 导入 mysql 脚本 ...

  6. Spring Security OAuth2整合JWT

    文章目录 1. Spring Security 与 OAuth2 2. Spring Security OAuth2的配置和使用 ①:引入依赖 ②:配置 spring security ③:配置授权服 ...

  7. JWT实战 Spring Security Oauth2整合JWT 整合SSO单点登录

    文章目录 一.JWT 1.1 什么是JWT 1.2 JWT组成 头部(header) 载荷(payload) 签名(signature) 如何应用 1.3 JJWT 快速开始 创建token toke ...

  8. Spring Security+Oauth2四种授权模式

    上一篇文章:Spring Security + OAuth2.0项目搭建:https://blog.csdn.net/qq_42402854/article/details/123057625 接着认 ...

  9. (七)Spring Security (spring-cloud-starter-oauth2)应用详解------认证授权服务------授权码模式和密码模式

    OAuth2.0介绍 OAuth(开放授权)是一个开放标准,允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方应用或分享他们数据的所有内容.OAuth2. ...

最新文章

  1. 大数据时代的创新者们
  2. python的open方法_Python os.open() 方法
  3. (多线程)leetcode1195. 交替打印字符串 最简单解法一个变量搞定
  4. python提取pdf表格信息
  5. 笔记67 Spring Boot快速入门(七)
  6. 2数据库表空间容量查询_Zabbix监控达梦数据库表空间
  7. 4.6 Spark SQL 数据清洗
  8. 「leetcode」47.全排列 II【回溯算法】详细图解!
  9. (day 40 - 双指针+库函数) 剑指 Offer 58 - I. 翻转单词顺序
  10. [APUE]进程关系(上)
  11. java实现手机扫描二维码后网站跳转新页面
  12. 使用html查看dicom,LEADTOOLS构建HTML5 DICOM/PACS查看器(二)
  13. 用c语言判断一个数是否为素数
  14. ecshop二次开发之电子票
  15. C语言将数字转成大写中文数字
  16. Lipschitz函数相关
  17. 免费直播 | Three.js 实现粒子雷雨特效,走入前端 3D 世界!
  18. IDEA打包时clean报错
  19. redis哨兵模式搭建配置(一主三从三哨兵)
  20. websocket访问ServletAPI

热门文章

  1. xp升级win7_重装经典的Win7系统指南
  2. 【软构】黑盒测试与白盒测试
  3. 使用sed删除拼音的音调
  4. Web基础配置篇(一): Java环境配置
  5. 微信开发者工具开发小程序代码自动热加载/重载/部署
  6. javase-jdk下载、安装、配置
  7. Vue 3.0 + Element Plus 踩坑
  8. 【C语言爱心代码】不可思议!C语言仅仅用17行代码居然把爱心完美运行出来了
  9. python线程池抓取网页数据
  10. HEVC预测编码介绍