文章目录
- 一、简介
- 二、重写UserDetailsService
- 三、Controller解析JWT获取用户信息
- 四、后记
一、简介
Version | |
---|---|
Java | 17 |
SpringCloud | 2023.0.0 |
SpringBoot | 3.2.1 |
Spring Authorization Server | 1.2.1 |
Spring Security | 6.2.1 |
mysql | 8.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 {@AutowiredXcUserMapper xcUserMapper;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {//根据username查询数据库XcUser xcUser = xcUserMapper.selectOne(new LambdaQueryWrapper<XcUser>().eq(XcUser::getUsername, username));//用户不存在,返回nullif (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;}@Datapublic 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"}
}