登录实现
拿浏览器网页登录举例:

基于 OAuth2.0-密码模式 实现网页登录的本质就是浏览器通过 /oauth/token 接口将 用户名 和 密码 等信息传给后台, 然后后台验证通过后返回一个有效的 token 给浏览器.

通过 curl 命令发送请求

请求头 Authorization 存放的是 clientId 和 secret 经过 Base64 编码后的结果

请求参数包括用户名(username)、密码(password)、授权模式(grant_type).

curl --location --request
POST 'http://localhost:8101/oauth/token?username=zhangsan&password=123456&grant_type=password \
--header 'Authorization: Basic bmltbzE6MTIzNDU2'

响应内容

{
"scope": "[all, read, write]",
"code": 0,
"access_token": "7e1d19dd-5cef-4993-a1c3-c35aa53d9b29",
"token_type": "bearer",
"refresh_token": "992518eb-4357-4283-8673-a9ca96ad2a9e",
"expires_in": 7199
}
问题
如果我们想把登录接口命名为 /login, 该怎么办?

方法一
在 AuthorizationServerConfigurerAdapter 配置一个 pathMapping, 把原有的路径给 覆盖 掉.

@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
.pathMapping("/oauth/token","/login"); }
}

方法二
根据上文 源码分析 - Spring Security OAuth2 生成 token 的执行流程 讲的 API , 实现 TokenEndpoint#postAccessToken()方法 的核心逻辑, 重新定义一个 /login 接口.

回顾上文中的一张图:

核心代码如下:

@PostMapping(value = "/login")
@ResponseBody
public String doLogin(
HttpServletRequest request,
String username,
String password) {

// 自定义响应对象
LoginRes res = new LoginRes();

try {
// 对请求头进行 base64 解码, 获取 client id 和 client secret
String[] tokens = CryptUtils.decodeBasicHeader(request.getHeader("Authorization"));
String clientId = tokens[0];
String clientSecret = tokens[1];

// 通过 clientId 获取客户端详情
ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);

// 校验 ClientDetails
if (clientDetails == null) {
throw new UnapprovedClientAuthenticationException("Unknown client id : " + clientId);
}

if (!passwordEncoder.matches(clientSecret, clientDetails.getClientSecret())) {
throw new UnapprovedClientAuthenticationException("Invalid client secret for client id : " + clientId);
}

// 通过 username 和 password 构建一个 Authentication 对象
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(req.getUsername(),
req.getPassword());

// 验证用户信息
Authentication auth = authenticationManager.authenticate(authRequest);
// 放入 Secirty 的上下文
SecurityContextHolder.getContext().setAuthentication(auth);

// 通过 Client 信息和 请求参数, 获取一个 TokenRequest 对象
TokenRequest tokenRequest = new TokenRequest(new HashMap<String, String>(), clientId,
clientDetails.getScope(), "password");

// 通过 TokenRequest 和 ClientDetails 构建 OAuthRequest
OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);

// 通过 OAuth2Request 和 Authentication 构建OAuth2Authentication
OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, auth);

// 通过 OAuth2Authentication 构建 OAuth2AccessToken
OAuth2AccessToken token = authorizationServerTokenServices.createAccessToken(oAuth2Authentication);

// 把 token 信息封装到 自定义的响应对象中
res.setAccessToken(token.getValue());
res.setTokenType(token.getTokenType());
res.setRefreshToken(token.getRefreshToken().getValue());
res.setExpiresIn(token.getExpiresIn());
res.setScope(token.getScope().toString());

} catch (Exception e) {
log.warn("Fail to login of user {} for {}", req.getUsername(), e.getMessage());
}
return JsonUtil.toJsonString(res);
}

Spring Security OAuth2 - 自定义 OAuth2.0 令牌发放接口地址的更多相关文章

  1. IdentityServer4源码解析_4_令牌发放接口

    目录 identityserver4源码解析_1_项目结构 identityserver4源码解析_2_元数据接口 identityserver4源码解析_3_认证接口 identityserver4 ...

  2. Spring Security Oauth2 自定义 OAuth2 Exception

    付出就要得到回报,这种想法是错的. 前言 在使用Spring Security Oauth2登录和鉴权失败时,默认返回的异常信息如下 { "error": "unauth ...

  3. 朱晔和你聊Spring系列S1E10:强大且复杂的Spring Security(含OAuth2三角色+三模式完整例子)

    Spring Security功能多,组件抽象程度高,配置方式多样,导致了Spring Security强大且复杂的特性.Spring Security的学习成本几乎是Spring家族中最高的,Spr ...

  4. spring security使用自定义登录界面后,不能返回到之前的请求界面的问题

    昨天因为集成spring security oauth2,所以对之前spring security的配置进行了一些修改,然后就导致登录后不能正确跳转回被拦截的页面,而是返回到localhost根目录. ...

  5. spring security 3 自定义认证,授权示例

    1,建一个web project,并导入所有需要的lib. 2,配置web.xml,使用Spring的机制装载: <?xml version="1.0" encoding=& ...

  6. spring security采用自定义登录页和退出功能

    更新... 首先采用的是XML配置方式,请先查看  初识Spring security-添加security 在之前的示例中进行代码修改 项目结构如下: 一.修改spring-security.xml ...

  7. 阶段5 3.微服务项目【学成在线】_day16 Spring Security Oauth2_06-SpringSecurityOauth2研究-Oauth2授权码模式-申请令牌

    3.3 Oauth2授权码模式 3.3.1 Oauth2授权模式 Oauth2有以下授权模式: 授权码模式(Authorization Code) 隐式授权模式(Implicit) 密码模式(Reso ...

  8. 阶段5 3.微服务项目【学成在线】_day16 Spring Security Oauth2_07-SpringSecurityOauth2研究-Oauth2授权码模式-资源服务授权测试

    下面要完成  5.6两个步骤 3.3.4 资源服务授权 3.3.4.1 资源服务授权流程 资源服务拥有要访问的受保护资源,客户端携带令牌访问资源服务,如果令牌合法则可成功访问资源服务中的资 源,如下图 ...

  9. 阶段5 3.微服务项目【学成在线】_day16 Spring Security Oauth2_09-SpringSecurityOauth2研究-Oauth2密码模式授权

    密码模式(Resource Owner Password Credentials)与授权码模式的区别是申请令牌不再使用授权码,而是直接 通过用户名和密码即可申请令牌. 测试如下: Post请求:htt ...

  10. spring security 之自定义表单登录源码跟踪

    ​ 上一节我们跟踪了security的默认登录页的源码,可以参考这里:https://www.cnblogs.com/process-h/p/15522267.html 这节我们来看看如何自定义单表认 ...

随机推荐

  1. 安装并运行tomcat8

    ps:tomcat7对应 jdk 1.7 tomcat8对应 jdk 1.8 注意要对应自己的项目选择下载tomcat版本 1. 软件商城搜索安装 tokcat 找到自己的tomcat的端口 8023 ...

  2. CSP-J2/S2 2023 游记

    可能早就应该发出来的游记. 2023-10-07 16:32. 前一天睡得比较晚,所以迟到了一点点. 上来先敲了个对拍,拍了一个 if a % 1000 = 0 then a++ 的 A + B,拍出 ...

  3. 洛谷P1596水坑计数

    [USACO10OCT] Lake Counting S 题目链接 题面翻译 由于近期的降雨,雨水汇集在农民约翰的田地不同的地方.我们用一个 \(N\times M(1\leq N\leq 100, ...

  4. 一文了解 Conda(包教包会,不会留言)

    Conda 使用指南 Conda 是一个开源包管理和环境管理系统,能够以跨平台的方式进行软件包的安装.管理和依赖管理,特别适用于 Python 和 R 语言的环境管理.本文整理了常见 Conda 命令 ...

  5. Linux系统管理-yum源配置

    一.本地光盘yum源配置 1.创建挂载点 [root@localhost ~]# mkdir /mnt/cdrom 2.配置自动挂载本地光盘 [root@localhost ~]# vim /etc/ ...

  6. css常用布局之flex布局

    Flexbox 是一个一维的布局模式,它可以轻松地在不同的方向上排列子元素(称为 flex 项),即使它们的大小是未知或者是动态变化的.以下是 Flexbox 的一些关键概念: 容器和项: 启用 Fl ...

  7. 学习JavaScript第二天

    文章目录 1.运算符(操作符) 1.1运算符的分类 1.2算数运算符 1.3递增和递减运算符 1.4比较运算符 1.5逻辑运算符 2.选择结构 2.1if语句 2.1.1语法 2.1.2案例1:判断闰 ...

  8. Nuxt.js 应用中的 imports:extend 事件钩子详解

    title: Nuxt.js 应用中的 imports:extend 事件钩子详解 date: 2024/10/28 updated: 2024/10/28 author: cmdragon exce ...

  9. 『玩转Streamlit』--文本与标题组件

    本篇准备开始介绍Streamlit的组件. Streamlit的组件非常多,后续几篇打算按照用途的分类,介绍每个分类中最常用的组件. 本次从最简单的组件开始,介绍文本和标题相关的组件,也就是以下4个组 ...

  10. C++学习——访问修饰符

    一.类是什么 类是C++当中的一个集合,定义了"属性",通过类可以实例化对象,此时对象的属性就囊括在这个类当中.比如: class student { public: string ...