1. 引入依赖
1 | <dependency> |
2. 实体类
用户实体类
1 | public class User { |
角色实体类
1 | public class Role { |
用户详细信息实体类(继承了User
,实现了org.springframework.security.core.userdetails.UserDetails
)
1 | public class SecurityUserDetails extends User implements UserDetails { |
3. 自定义用户信息服务类
1 | import org.springframework.security.core.userdetails.UserDetailsService; |
4. Java Web Token工具类
1 |
|
5. 处理类
- 在访问一个受保护的资源,用户没有通过登录认证,则抛出登录认证异常。
1 | /** |
- 在访问一个受保护的资源,用户通过了登录认证,但是权限不够,抛出授权异常
1 | /** |
登录成功后MyAuthenticationSuccessHandler类中onAuthenticationSuccess()被调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33/**
* @Description: 登录成功处理类
* 用户登录系统成功后,需要做的业务操作
*/
public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
private final static Logger LOGGER = LoggerFactory.getLogger(MyAuthenticationSuccessHandler.class);
private String tokenHead;
JwtUtils jwtUtil;
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
LOGGER.debug("认证通过,开始获取token");
SecurityUserDetails securityUserDetails = (SecurityUserDetails)authentication.getPrincipal();
String token = jwtUtil.generateAccessToken(securityUserDetails);
token = tokenHead + token;
LOGGER.debug("获取token:"+token);
User user = new User();
user.setUserId(securityUserDetails.getUserId());
user.setUsername(securityUserDetails.getUsername());
user.setRoles(securityUserDetails.getRoles());
response.setStatus(200);
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter printWriter = response.getWriter();
String body = JSON.toJSONString(ResponseGenerator.genSuccessResult(new ResponseUserToken(token,user)));
printWriter.write(body);
printWriter.flush();
}
}登录失败后MyAuthenticationFailureHandler 类中onAuthenticationFailure()被调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24/**
* @Description: 登录失败处理类
* 用户登录系统失败后需要做的业务操作
*/
public class MyAuthenticationFailHandler extends SimpleUrlAuthenticationFailureHandler {
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,AuthenticationException e) throws IOException, ServletException {
String body = "";
if (e instanceof UsernameNotFoundException || e instanceof BadCredentialsException) {
body = JSON.toJSONString(ResponseGenerator.genFailResult(ResponseCode.UNAUTHORIZED.code(),"用户名或密码错误"));
} else if (e instanceof DisabledException) {
body = JSON.toJSONString(ResponseGenerator.genFailResult(ResponseCode.UNAUTHORIZED.code(),"账户被禁用,请联系管理员"));
} else {
body = JSON.toJSONString(ResponseGenerator.genFailResult(ResponseCode.UNAUTHORIZED.code(),"登录失败"));
}
response.setStatus(200);
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter printWriter = response.getWriter();
printWriter.write(body);
printWriter.flush();
}
}
6. token过滤器
1 | /** |
7. 自定义资源权限认证器和加载资源与权限的对应关系
- 资源权限认证器
1 | /** |
- 加载资源与权限的对应关系,
1 | /** |
8. 配置文件
1 | 8089 = |
9. Web配置
1 | /** |
10. 测试
/findUserById
需要ROLE_USER
角色/all
需要ROLE_ADMIN
角色- test用户有
ROLE_ADMIN
角色,无ROLE_USER
角色
无token访问
登录获取token
带token访问,有权限
带token访问,无权限