oauth2 授权码模式 流程说明和接口整理

您所在的位置:网站首页 授权码模式不跳转登录页面怎么回事 oauth2 授权码模式 流程说明和接口整理

oauth2 授权码模式 流程说明和接口整理

2024-07-10 19:51| 来源: 网络整理| 查看: 265

一、说明

oauth2 授权模式一共有四种,即隐式授权模式、授权码授权模式、密码授权模式和客户端授权模式。 这里仅对授权码授权模式所包含的流程和接口做说明和整理。 具体的概念和源码解读,资料有很多,可以自行去搜索学习。

二、流程说明

假设有这样一个场景:现有A系统和B系统,A系统想要使用B系统的账号来做三方登录,那么A系统就必须要获取B系统的授权,以便拿到B系统的用户信息。(可以参考微信账号的三方登录场景) 想要实现以上场景就可以使用oauth2的授权码模式,具体流程参考下图:

oauth2-授权码授权模式

其中clientId、clientSecret、redirectUri等信息涉及到的表是:oauth_client_details

三、所涉及到的接口以及代码整理

以下会对接口做简要说明,最重要的是整理涉及到的自定义配置 想要了解具体代码逻辑实现,可以重点看一下 AuthorizationEndpoint 这个类的源码

① /oauth/authorize 接口 GET请求

该接口对应上图的第一步,即传递参数,获取B系统的登录界面。

authorize-get oauth2的登录界面很丑,很难满足实际使用场景,可以通过在认证服务器配置中使用自定义的登录页面替换。

@Override protected void configure(HttpSecurity http) throws Exception { http .csrf().disable() .requestMatchers().antMatchers("/login*","/oauth/authorize").and() .authorizeRequests() .anyRequest().permitAll() .and() .formLogin() //使用自定义的登录页面 .loginPage("/login.html") .loginProcessingUrl("/login"); }

注:如果同时存在认证服务器配置和资源服务牌配置的话,需要设置认证服务器配置的优先级高于资源服务器配置。

/** * 认证服务器配置 */ @Configuration @Order(1) //设置该配置的优先级 public class WebSecurityConfig extends WebSecurityConfigurerAdapter { ... ... } /** * 资源服务器配置 */ @Configuration @EnableResourceServer public class UnifiedResourceServerConfig extends ResourceServerConfigurerAdapter { ... ... } ② /oauth/confirm_access 接口

该接口会重定向到授权页面,同样,oauth2的授权界面很难满足实际使用场景,可以通过配置替换为自定义的授权页面。

//替换为自定义的授权页面 endpoints.pathMapping("/oauth/confirm_access", "/custom/confirm_access"); //自定义授权页面 @Controller @SessionAttributes("authorizationRequest") public class GrantController { @RequestMapping("/custom/confirm_access") public ModelAndView getAccessConfirmation(Map model, HttpServletRequest request) { AuthorizationRequest authorizationRequest = (AuthorizationRequest) model.get("authorizationRequest"); ModelAndView view = new ModelAndView(); view.setViewName("grant"); view.addObject("clientId", authorizationRequest.getClientId()); view.addObject("scopes",authorizationRequest.getScope()); return view; } } 同意/授权

授权后的信息存放在 oauth_approvals 表中。 具体源码可以查看 JdbcApprovalStore 类,该类中的sql默认是使用 Mysql 语法,同样可以通过自定义替换成别的数据库语法。

③ /oauth/authorize 接口 POST请求

该接口会生成code码,最终会重定向到A系统的redirectUrl地址,并将生成的code码以参数的形式传递到A系统。

生成的code码保存在 oauth_code 表中。 具体源码可以查看 JdbcAuthorizationCodeServices 类。

可以在代码中自定义code码生成规则

public class UnifiedAuthorizationCodeServices extends JdbcAuthorizationCodeServices { public UnifiedAuthorizationCodeServices(DataSource dataSource) { super(dataSource); } private RandomValueStringGenerator generator = new RandomValueStringGenerator(13); @Override public String createAuthorizationCode(OAuth2Authentication authentication) { String code = generator.generate(); store(code, authentication); return code; } }

配置代码

@Bean public AuthorizationCodeServices authorizationCodeServices() { return new UnifiedAuthorizationCodeServices(dataSource); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { // token 携带额外信息 TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain(); tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer())); endpoints .userDetailsService(userDetailsService) .tokenStore(tokenStore()) .tokenServices(defaultAuthorizationServerTokenServices()) .authenticationManager(authenticationManager) .accessTokenConverter(getAccessTokenConverter()) .exceptionTranslator(oauth2ResponseExceptionTranslator) //自定义sql查询语句 .approvalStore(jdbcApprovalStore()) //自定义授权码生成规则 .authorizationCodeServices(authorizationCodeServices()); //替换为自定义的授权页面 endpoints.pathMapping("/oauth/confirm_access", "/custom/confirm_access"); } ④ /oauth/token 接口 authorization_code模式

该接口对应图中,A系统访问B系统,传递clientId,clientSecret,code,redirectUri等参数换取B系统的accessToken和refreshToken。

使用code换取token 有了B系统token,就可以通过token调用B系统的接口获取B系统的用户信息了。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3