sharp-admin
添加 SSOTokenAuthenticationFilter.java
public class SSOTokenAuthenticationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
String header = request.getHeader("Authorization");
String accessToken;
if (header == null || !header.startsWith("Bearer ")) {
accessToken = request.getParameter("access_token");
} else {
accessToken = header.substring(7);
}
if (StringUtils.isBlank(accessToken)) {
chain.doFilter(request, response);
return;
}
try {
SecurityContext securityContext = (SecurityContext) request.getSession().getAttribute("SPRING_SECURITY_CONTEXT");
if (Objects.isNull(securityContext)) {
// 根据 accessToken 解析用户信息和权限信息 构造 authentication
String code = "";
UserDAO userDAO = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext()).getBean(UserDAO.class);
User user = userDAO.selectByCode(code).get();
user.setPassword(accessToken);
AdminUserDetails userDetails = new AdminUserDetails(user, AuthorityUtils.createAuthorityList("ROLE_STUDENT"));
Authentication authentication = UsernamePasswordAuthenticationToken.authenticated(userDetails, userDetails.getPassword(), userDetails.getAuthorities());
request.getSession().setAttribute("SPRING_SECURITY_CONTEXT", authentication);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
chain.doFilter(request, response);
} catch (Exception e) {
response.setStatus(HttpStatus.FORBIDDEN.value());
HttpServletResponseUtils.write(response, "application/json;charset=UTF-8"
, JsonUtils.toJson(ResultUtils.fail(HttpStatus.FORBIDDEN.value(), e.getMessage())));
e.printStackTrace();
}
}
}
WebSecurityConfig.java
注册 SSOTokenAuthenticationFilter.java
http.addFilterBefore(new SSOTokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
sharp-admin 如何登录到其他 App
希望用户登录 sharp-admin 后,转发到 App 携带 jsessionid
,App 获取 jsessionid
, 获取用户的登录信息(类似 SSOTokenAuthenticationFilter.java 的处理流程)
比如登录 sharp-admin 后,获取jsessionid=abc,那么跳转到 App 需要把 jsessionid=abc 加入到 url 中,做地址重写。http://app.com;jsessionid=abc app获取请求中的 jsessionid
,通过接口 /api/user-info;jsessionid=abc获取用户信息,然后做后续的授权操作。
sharp-admin 获取当前用户的信息
/**
* 获取当前登录用户的信息
* @return
*/
@GetMapping("api/user-info")
@ResponseBody
public User userInfo() {
User user = UserContextHolder.get();
return user;
}
/api/user-info;jsessionid=abc
jsessionid 是通过路径参数传递的。
/api/user-info
不需要认证
.antMatchers("/api/user-info").permitAll()
MvcConfig.java
@Bean
public HttpFirewall getHttpFirewall() {
StrictHttpFirewall strictHttpFirewall = new StrictHttpFirewall();
strictHttpFirewall.setAllowSemicolon(true); // 允许;
return strictHttpFirewall;
}
注意:如果 cookies 和 地址栏 jsessionid 同时提交,那么 cookies 中的 JSESSIONID 会覆盖地址栏中的 jsessionid,测试的时候如果用浏览器测试地址栏就会被覆盖,postman 测试需要检查 cookies 是否携带了JSESSIONID。大多数情况下,地址栏 jsessionid 的使用,都是禁用 cookie 的情况下。jsessionid 也会有一些安全风险。