主页 > 人工智能  > 

微服务OAuth2.1扩展额外信息到JWT并解析(SpringSecurity6)


文章目录 一、简介二、重写UserDetailsService三、Controller解析JWT获取用户信息四、后记

一、简介 VersionJava17SpringCloud2023.0.0SpringBoot3.2.1Spring Authorization Server1.2.1Spring Security6.2.1mysql8.2.0

Spring Authorization Server 使用JWT时,前两部分默认格式如下

{ "kid": "33bd1cad-62a6-4415-89a6-c2c816f3d3b1", "alg": "RS256" } { "sub": "XcWebApp", "aud": "XcWebApp", "nbf": 1707373072, "iss": "http://localhost:63070/auth", "exp": 1707380272, "iat": 1707373072, "jti": "62e885c5-6b3f-49a2-aa10-b2e872a52b33" }

现在我们要把用户信息也扩展到JWT,最简便的方法就是将用户信息写成JSON字符串替换sub字段。其中用户信息由xc_user数据库表存储。

二、重写UserDetailsService

注释掉原来的UserDetailsService实例。新建一个实现类,如下

@Component @Slf4j public class UserServiceImpl implements UserDetailsService { @Autowired XcUserMapper xcUserMapper; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { //根据username查询数据库 XcUser xcUser = xcUserMapper.selectOne(new LambdaQueryWrapper<XcUser>() .eq(XcUser::getUsername, username)); //用户不存在,返回null if (xcUser == null){ return null; } //用户存在,拿到密码,封装成UserDetails,密码对比由框架进行 String password = xcUser.getPassword(); //扩展用户信息 xcUser.setPassword(null); String userInfo = JSON.toJSONString(xcUser); UserDetails userDetails = User.withUsername(userInfo).password(password).authorities("read").build(); return userDetails; } } 如果XcUser为null,返回null,这里处理了用户不存在的情况。如果用户存在,则获取密码,放到UserDetails 中,密码比对过程我们不关心,由框架完成。如果使用了加密算法,这里的password应该是密文。我们可以把用户信息转成JSON字符串放入withUsername。这样框架生成JWT时就会把用户信息也放进去。

是的,你没有猜错,UserDetails 只要返回密码框架就能比对成功,不需要再返回username。

三、Controller解析JWT获取用户信息

写一个工具类,通过Security ContextHolder.getContext()上下文获取Authentication然后解析JWT。

@Slf4j public class SecurityUtil { public static XcUser getUser(){ Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication instanceof JwtAuthenticationToken) { JwtAuthenticationToken jwtAuth = (JwtAuthenticationToken) authentication; Map<String, Object> tokenAttributes = jwtAuth.getTokenAttributes(); Object sub = tokenAttributes.get("sub"); return JSON.parseObject(sub.toString(), XcUser.class); } return null; } @Data public static class XcUser implements Serializable { //... } }

JwtAuthenticationToken是Spring Authorization Server的一个类,可以帮助我们解析JWT。

四、后记

从SecurityContextHolder.getContext().getAuthentication()解析我们放进去的XcUser的方法不止一种,将其打印出来就可以看出,有多个地方包含了XcUser,例如。

{ "authenticated": true, "authorities": [{ "authority": "SCOPE_all" }], "credentials": { "audience": ["XcWebApp"], "claims": { "sub": "{\"createTime\":\"2022-09-28 08:32:03\",\"id\":\"48\",\"name\":\"系统管理员\",\"sex\":\"1\",\"status\":\"1\",\"username\":\"admin\",\"utype\":\"101003\"}", "aud": ["XcWebApp"], "nbf": "2024-02-08T14:01:16Z", "scope": ["all"], "iss": "http://localhost:63070/auth", "exp": "2024-02-08T16:01:16Z", "iat": "2024-02-08T14:01:16Z", "jti": "91df8f15-2096-4e03-a927-877b51bf5997" }, "expiresAt": "2024-02-08T16:01:16Z", "headers": { "kid": "e14df18d-1c95-441d-80d6-8457f3ceba9e", "alg": "RS256" }, "id": "91df8f15-2096-4e03-a927-877b51bf5997", "issuedAt": "2024-02-08T14:01:16Z", "issuer": "http://localhost:63070/auth", "notBefore": "2024-02-08T14:01:16Z", "subject": "{\"createTime\":\"2022-09-28 08:32:03\",\"id\":\"48\",\"name\":\"系统管理员\",\"sex\":\"1\",\"status\":\"1\",\"username\":\"admin\",\"utype\":\"101003\"}", "tokenValue": "eyJraWQiOiJlMTRkZjE4ZC0xYzk1LTQ0MWQtODBkNi04NDU3ZjNjZWJhOWUiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ7XCJjcmVhdGVUaW1lXCI6XCIyMDIyLTA5LTI4IDA4OjMyOjAzXCIsXCJpZFwiOlwiNDhcIixcIm5hbWVcIjpcIuezu-e7n-euoeeQhuWRmFwiLFwic2V4XCI6XCIxXCIsXCJzdGF0dXNcIjpcIjFcIixcInVzZXJuYW1lXCI6XCJhZG1pblwiLFwidXR5cGVcIjpcIjEwMTAwM1wifSIsImF1ZCI6IlhjV2ViQXBwIiwibmJmIjoxNzA3NDAwODc2LCJzY29wZSI6WyJhbGwiXSwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo2MzA3MC9hdXRoIiwiZXhwIjoxNzA3NDA4MDc2LCJpYXQiOjE3MDc0MDA4NzYsImp0aSI6IjkxZGY4ZjE1LTIwOTYtNGUwMy1hOTI3LTg3N2I1MWJmNTk5NyJ9.NZ3f_Pkh871L1c8XkV2PxHfn17pWjaRvBd9HQQTRJhfFvNBN7zoh2riumpfVUj_xVmnCadVX3YE4ARxc0CuiV1QyVDpFnmKiuvWdsRVV9NF5Kkb67CGtF2zw1l2gFdSDFWAwOq1SemtogHX5a4XFF2kG6kx9ZOSL4EoiQMMhUOwfY6mL9Zdcgq_E28kfnrAk__q84rgo9JPvj3jH6cm_oS63-tNXZYdClDG61DHS4Bw7cswUfVf_bcI_a8kXfiM8SzCnROvxe1hU2dM88qxUgkI1GPlrtZhe9z7113XP7ilaPo2UknCFh_OSbfUeUDmP1GpTaspfGmnHhBXLQyG06Q" }, "details": { "remoteAddress": "192.168.222.1" }, "name": "{\"createTime\":\"2022-09-28 08:32:03\",\"id\":\"48\",\"name\":\"系统管理员\",\"sex\":\"1\",\"status\":\"1\",\"username\":\"admin\",\"utype\":\"101003\"}", "principal": { "audience": ["XcWebApp"], "claims": { "sub": "{\"createTime\":\"2022-09-28 08:32:03\",\"id\":\"48\",\"name\":\"系统管理员\",\"sex\":\"1\",\"status\":\"1\",\"username\":\"admin\",\"utype\":\"101003\"}", "aud": ["XcWebApp"], "nbf": "2024-02-08T14:01:16Z", "scope": ["all"], "iss": "http://localhost:63070/auth", "exp": "2024-02-08T16:01:16Z", "iat": "2024-02-08T14:01:16Z", "jti": "91df8f15-2096-4e03-a927-877b51bf5997" }, "expiresAt": "2024-02-08T16:01:16Z", "headers": { "kid": "e14df18d-1c95-441d-80d6-8457f3ceba9e", "alg": "RS256" }, "id": "91df8f15-2096-4e03-a927-877b51bf5997", "issuedAt": "2024-02-08T14:01:16Z", "issuer": "http://localhost:63070/auth", "notBefore": "2024-02-08T14:01:16Z", "subject": "{\"createTime\":\"2022-09-28 08:32:03\",\"id\":\"48\",\"name\":\"系统管理员\",\"sex\":\"1\",\"status\":\"1\",\"username\":\"admin\",\"utype\":\"101003\"}", "tokenValue": "eyJraWQiOiJlMTRkZjE4ZC0xYzk1LTQ0MWQtODBkNi04NDU3ZjNjZWJhOWUiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ7XCJjcmVhdGVUaW1lXCI6XCIyMDIyLTA5LTI4IDA4OjMyOjAzXCIsXCJpZFwiOlwiNDhcIixcIm5hbWVcIjpcIuezu-e7n-euoeeQhuWRmFwiLFwic2V4XCI6XCIxXCIsXCJzdGF0dXNcIjpcIjFcIixcInVzZXJuYW1lXCI6XCJhZG1pblwiLFwidXR5cGVcIjpcIjEwMTAwM1wifSIsImF1ZCI6IlhjV2ViQXBwIiwibmJmIjoxNzA3NDAwODc2LCJzY29wZSI6WyJhbGwiXSwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo2MzA3MC9hdXRoIiwiZXhwIjoxNzA3NDA4MDc2LCJpYXQiOjE3MDc0MDA4NzYsImp0aSI6IjkxZGY4ZjE1LTIwOTYtNGUwMy1hOTI3LTg3N2I1MWJmNTk5NyJ9.NZ3f_Pkh871L1c8XkV2PxHfn17pWjaRvBd9HQQTRJhfFvNBN7zoh2riumpfVUj_xVmnCadVX3YE4ARxc0CuiV1QyVDpFnmKiuvWdsRVV9NF5Kkb67CGtF2zw1l2gFdSDFWAwOq1SemtogHX5a4XFF2kG6kx9ZOSL4EoiQMMhUOwfY6mL9Zdcgq_E28kfnrAk__q84rgo9JPvj3jH6cm_oS63-tNXZYdClDG61DHS4Bw7cswUfVf_bcI_a8kXfiM8SzCnROvxe1hU2dM88qxUgkI1GPlrtZhe9z7113XP7ilaPo2UknCFh_OSbfUeUDmP1GpTaspfGmnHhBXLQyG06Q" }, "token": { "audience": ["XcWebApp"], "claims": { "sub": "{\"createTime\":\"2022-09-28 08:32:03\",\"id\":\"48\",\"name\":\"系统管理员\",\"sex\":\"1\",\"status\":\"1\",\"username\":\"admin\",\"utype\":\"101003\"}", "aud": ["XcWebApp"], "nbf": "2024-02-08T14:01:16Z", "scope": ["all"], "iss": "http://localhost:63070/auth", "exp": "2024-02-08T16:01:16Z", "iat": "2024-02-08T14:01:16Z", "jti": "91df8f15-2096-4e03-a927-877b51bf5997" }, "expiresAt": "2024-02-08T16:01:16Z", "headers": { "kid": "e14df18d-1c95-441d-80d6-8457f3ceba9e", "alg": "RS256" }, "id": "91df8f15-2096-4e03-a927-877b51bf5997", "issuedAt": "2024-02-08T14:01:16Z", "issuer": "http://localhost:63070/auth", "notBefore": "2024-02-08T14:01:16Z", "subject": "{\"createTime\":\"2022-09-28 08:32:03\",\"id\":\"48\",\"name\":\"系统管理员\",\"sex\":\"1\",\"status\":\"1\",\"username\":\"admin\",\"utype\":\"101003\"}", "tokenValue": "eyJraWQiOiJlMTRkZjE4ZC0xYzk1LTQ0MWQtODBkNi04NDU3ZjNjZWJhOWUiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ7XCJjcmVhdGVUaW1lXCI6XCIyMDIyLTA5LTI4IDA4OjMyOjAzXCIsXCJpZFwiOlwiNDhcIixcIm5hbWVcIjpcIuezu-e7n-euoeeQhuWRmFwiLFwic2V4XCI6XCIxXCIsXCJzdGF0dXNcIjpcIjFcIixcInVzZXJuYW1lXCI6XCJhZG1pblwiLFwidXR5cGVcIjpcIjEwMTAwM1wifSIsImF1ZCI6IlhjV2ViQXBwIiwibmJmIjoxNzA3NDAwODc2LCJzY29wZSI6WyJhbGwiXSwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo2MzA3MC9hdXRoIiwiZXhwIjoxNzA3NDA4MDc2LCJpYXQiOjE3MDc0MDA4NzYsImp0aSI6IjkxZGY4ZjE1LTIwOTYtNGUwMy1hOTI3LTg3N2I1MWJmNTk5NyJ9.NZ3f_Pkh871L1c8XkV2PxHfn17pWjaRvBd9HQQTRJhfFvNBN7zoh2riumpfVUj_xVmnCadVX3YE4ARxc0CuiV1QyVDpFnmKiuvWdsRVV9NF5Kkb67CGtF2zw1l2gFdSDFWAwOq1SemtogHX5a4XFF2kG6kx9ZOSL4EoiQMMhUOwfY6mL9Zdcgq_E28kfnrAk__q84rgo9JPvj3jH6cm_oS63-tNXZYdClDG61DHS4Bw7cswUfVf_bcI_a8kXfiM8SzCnROvxe1hU2dM88qxUgkI1GPlrtZhe9z7113XP7ilaPo2UknCFh_OSbfUeUDmP1GpTaspfGmnHhBXLQyG06Q" }, "tokenAttributes": { "sub": "{\"createTime\":\"2022-09-28 08:32:03\",\"id\":\"48\",\"name\":\"系统管理员\",\"sex\":\"1\",\"status\":\"1\",\"username\":\"admin\",\"utype\":\"101003\"}", "aud": ["XcWebApp"], "nbf": "2024-02-08T14:01:16Z", "scope": ["all"], "iss": "http://localhost:63070/auth", "exp": "2024-02-08T16:01:16Z", "iat": "2024-02-08T14:01:16Z", "jti": "91df8f15-2096-4e03-a927-877b51bf5997" } }

标签:

微服务OAuth2.1扩展额外信息到JWT并解析(SpringSecurity6)由讯客互联人工智能栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“微服务OAuth2.1扩展额外信息到JWT并解析(SpringSecurity6)