【转载】Spring Security Oauth2 自定义 OAuth2 Exception
https://www.cnblogs.com/merryyou/p/9100260.html
前言
在使用Spring Security Oauth2登录和鉴权失败时,默认返回的异常信息如下
{
"error": "unauthorized",
"error_description": "Full authentication is required to access this resource"
}
。它与我们自定义返回信息不一致,并且描述信息较少。那么如何自定义Spring Security Oauth2异常信息呢,下面我们简单实现以下。格式如下:
{
"error": "400",
"message": "坏的凭证",
"path": "/oauth/token",
"timestamp": "1527432468717"
}
自定义登录失败异常信息
新增CustomOauthException
- 添加自定义异常类,指定
json序列化方式
@JsonSerialize(using = CustomOauthExceptionSerializer.class)
public class CustomOauthException extends OAuth2Exception {
public CustomOauthException(String msg) {
super(msg);
}
}
新增CustomOauthExceptionSerializer
- 添加
CustomOauthException的序列化实现
public class CustomOauthExceptionSerializer extends StdSerializer<CustomOauthException> {
public CustomOauthExceptionSerializer() {
super(CustomOauthException.class);
}
@Override
public void serialize(CustomOauthException value, JsonGenerator gen, SerializerProvider provider) throws IOException {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
gen.writeStartObject();
gen.writeStringField("error", String.valueOf(value.getHttpErrorCode()));
gen.writeStringField("message", value.getMessage());
// gen.writeStringField("message", "用户名或密码错误");
gen.writeStringField("path", request.getServletPath());
gen.writeStringField("timestamp", String.valueOf(new Date().getTime()));
if (value.getAdditionalInformation()!=null) {
for (Map.Entry<String, String> entry : value.getAdditionalInformation().entrySet()) {
String key = entry.getKey();
String add = entry.getValue();
gen.writeStringField(key, add);
}
}
gen.writeEndObject();
}
}
添加CustomWebResponseExceptionTranslator
- 添加
CustomWebResponseExceptionTranslator,登录发生异常时指定exceptionTranslator
public class CustomOauthExceptionSerializer extends StdSerializer<CustomOauthException> {
public CustomOauthExceptionSerializer() {
super(CustomOauthException.class);
}
@Override
public void serialize(CustomOauthException value, JsonGenerator gen, SerializerProvider provider) throws IOException {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
gen.writeStartObject();
gen.writeStringField("error", String.valueOf(value.getHttpErrorCode()));
gen.writeStringField("message", value.getMessage());
// gen.writeStringField("message", "用户名或密码错误");
gen.writeStringField("path", request.getServletPath());
gen.writeStringField("timestamp", String.valueOf(new Date().getTime()));
if (value.getAdditionalInformation()!=null) {
for (Map.Entry<String, String> entry : value.getAdditionalInformation().entrySet()) {
String key = entry.getKey();
String add = entry.getValue();
gen.writeStringField(key, add);
}
}
gen.writeEndObject();
}
}
修改MerryyouAuthorizationServerConfig
- 指定自定义
customWebResponseExceptionTranslator
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore)
.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService);
//扩展token返回结果
if (jwtAccessTokenConverter != null && jwtTokenEnhancer != null) {
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
List<TokenEnhancer> enhancerList = new ArrayList();
enhancerList.add(jwtTokenEnhancer);
enhancerList.add(jwtAccessTokenConverter);
tokenEnhancerChain.setTokenEnhancers(enhancerList);
//jwt
endpoints.tokenEnhancer(tokenEnhancerChain)
.accessTokenConverter(jwtAccessTokenConverter);
}
endpoints.exceptionTranslator(customWebResponseExceptionTranslator);
}
自定义Token异常信息
添加AuthExceptionEntryPoint
- 自定义
AuthExceptionEntryPoint用于tokan校验失败返回信息
public class AuthExceptionEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException)
throws ServletException {
Map map = new HashMap();
map.put("error", "401");
map.put("message", authException.getMessage());
map.put("path", request.getServletPath());
map.put("timestamp", String.valueOf(new Date().getTime()));
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
try {
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(response.getOutputStream(), map);
} catch (Exception e) {
throw new ServletException();
}
}
}
添加CustomAccessDeniedHandler
- 授权失败(forbidden)时返回信息
@Slf4j
@Component("customAccessDeniedHandler")
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
@Autowired
private ObjectMapper objectMapper;
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
response.setContentType("application/json;charset=UTF-8");
Map map = new HashMap();
map.put("error", "400");
map.put("message", accessDeniedException.getMessage());
map.put("path", request.getServletPath());
map.put("timestamp", String.valueOf(new Date().getTime()));
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write(objectMapper.writeValueAsString(map));
}
}
修改MerryyouResourceServerConfig
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.authenticationEntryPoint(new AuthExceptionEntryPoint())
.accessDeniedHandler(CustomAccessDeniedHandler);
}
效果如下
登录异常

token异常

禁止访问

token失效

代码下载
- github:https://github.com/longfeizheng/security-oauth2
- gitee:https://gitee.com/merryyou/security-oauth2
【转载】Spring Security Oauth2 自定义 OAuth2 Exception的更多相关文章
- Spring Security Oauth2 自定义 OAuth2 Exception
付出就要得到回报,这种想法是错的. 前言 在使用Spring Security Oauth2登录和鉴权失败时,默认返回的异常信息如下 { "error": "unauth ...
- 朱晔和你聊Spring系列S1E10:强大且复杂的Spring Security(含OAuth2三角色+三模式完整例子)
Spring Security功能多,组件抽象程度高,配置方式多样,导致了Spring Security强大且复杂的特性.Spring Security的学习成本几乎是Spring家族中最高的,Spr ...
- spring security使用自定义登录界面后,不能返回到之前的请求界面的问题
昨天因为集成spring security oauth2,所以对之前spring security的配置进行了一些修改,然后就导致登录后不能正确跳转回被拦截的页面,而是返回到localhost根目录. ...
- spring security采用自定义登录页和退出功能
更新... 首先采用的是XML配置方式,请先查看 初识Spring security-添加security 在之前的示例中进行代码修改 项目结构如下: 一.修改spring-security.xml ...
- [转载]spring security 的 logout 功能
原文地址:security 的 logout 功能">spring security 的 logout 功能作者:sumnny 转载自:http://lengyun3566.iteye ...
- spring security 3 自定义认证,授权示例
1,建一个web project,并导入所有需要的lib. 2,配置web.xml,使用Spring的机制装载: <?xml version="1.0" encoding=& ...
- 阶段5 3.微服务项目【学成在线】_day16 Spring Security Oauth2_06-SpringSecurityOauth2研究-Oauth2授权码模式-申请令牌
3.3 Oauth2授权码模式 3.3.1 Oauth2授权模式 Oauth2有以下授权模式: 授权码模式(Authorization Code) 隐式授权模式(Implicit) 密码模式(Reso ...
- 阶段5 3.微服务项目【学成在线】_day16 Spring Security Oauth2_07-SpringSecurityOauth2研究-Oauth2授权码模式-资源服务授权测试
下面要完成 5.6两个步骤 3.3.4 资源服务授权 3.3.4.1 资源服务授权流程 资源服务拥有要访问的受保护资源,客户端携带令牌访问资源服务,如果令牌合法则可成功访问资源服务中的资 源,如下图 ...
- 阶段5 3.微服务项目【学成在线】_day16 Spring Security Oauth2_09-SpringSecurityOauth2研究-Oauth2密码模式授权
密码模式(Resource Owner Password Credentials)与授权码模式的区别是申请令牌不再使用授权码,而是直接 通过用户名和密码即可申请令牌. 测试如下: Post请求:htt ...
- spring security 之自定义表单登录源码跟踪
上一节我们跟踪了security的默认登录页的源码,可以参考这里:https://www.cnblogs.com/process-h/p/15522267.html 这节我们来看看如何自定义单表认 ...
随机推荐
- 激活windows教程
新建bat文件 [批处理文件:后缀是 bat ] 输入代码: slmgr/skms kms.03k.org slmgr/ato 然后以管理员运行 :
- 解决数据库表的字段id中间自增断层问题(删除自增主键其中的任意一条数据后,再次插入数据发现id排序出现问题)
万能解决办法: 先将该表的id字段删除,然后再重新按照见表需求创建该字段 注意!!!!!!!!!!!!! 注意!!!!!!!!!!!!! 注意!!!!!!!!!!!!! 删除之前一定要复制建表时候的S ...
- 放大招!青云企业级容器平台 QKCP 迎来重磅升级
青云企业级容器平台 QKCP 3.2 重磅发布.QKCP(QingCloud KubeSphere Container Platform)是青云科技基于 KubeSphere 开源容器平台打造的企业级 ...
- 容器虚拟化平台 KSV 1.5 发布:部署更便捷,适配更多信创需求!
报告!我们又迎来了一次重磅更新: 近日,由青云科技打造的轻量化虚拟机管理平台--KSV 容器虚拟化 1.5 版本正式发布! KSV 1.5 好在什么地方?逐个来解释 新增基于模板创建虚拟机.克隆虚拟机 ...
- git安装使用及连接gitlab集成idea
一.简介 Git是一个开源的分布式版本控制系统,通过git可以对项目进行代码托管,通常配合GitLub.Github使用: 想了解更多请进官网(官网下载较慢):https://www.git-scm. ...
- direasch目录扫描
direasch目录扫描工具 安装: 1.github源码下载解压 使用 git 安装:(推荐git clone https://github.com/maurosoria/dirsearch.git ...
- SQL 清除数据库中所有表的数据
进行数据库的操作,有时候我们需要清除数据库中所有的数据,如果你不嫌麻烦,可以一次一次的执行truncate操作,但是如果遇到有无数个表的情况,这种操作无疑是很耗时的 我曾经百度别人的代码,看都没看就直 ...
- 不敢相信,Nginx 还能这么玩?
大家好,我是程序员鱼皮.今天来聊聊 Nginx 技术,这是一个企业项目必用,但是却经常被程序员忽略的技术.学好 Nginx,可以助你在求职中脱颖而出. 或许你会想:"Nginx 不就是用来部 ...
- 国内985大学计算机方向硕博高性价比灌水的SCI期刊pr、kbs、eswa、ieee tii、ieee tiv具体都是啥?
国内985大学计算机方向硕博高性价比灌水的SCI期刊pr.kbs.eswa.ieee tii.ieee tiv,下面给出具体名称: Pattern Recognition(PR) Knowledge- ...
- 研发LLM模型,如何用数值表示人类自然语言?
上一篇:<人工智能--自然语言处理简介> 序言:人工智能大语言模型(LLM)如何理解人类的自然语言?这个过程的核心在于将文本转化为计算机能处理的数值形式,经过计算,最终达到对语言的理解.起 ...