一 微服务用户鉴权拦截
1.1 实现方法
当微服务收到明文token时,应该怎么鉴权拦截呢?自己实现一个filter?自己解析明文token,自己定义一套资源访问策略?
能不能适配Spring Security呢,是不是突然想起了前面我们实现的Spring Security基于token认证例子。咱们还拿 统一用户服务作为网关下游微服务,对它进行改造,增加微服务用户鉴权拦截功能。
二 实例操作案例
2.1 定义filter对用户权限进行拦截
2.1.1 filter作用
解析token,将信息进行存储到Spring Security的Authentication中,封装成Authentication对象。
2.1.2 逻辑实现
1.解析token
2.新建并填充authentication
3.将authentication保存进安全上下文
剩下的事儿就交给Spring Security好了。

经过上边的过虑 器,资源 服务中就可以方便到的获取用户的身份信息:
UserDTO user = (UserDTO) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
2.1.3 完整代码
package com.ljf.springsecurity.oauth.filter;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ljf.springsecurity.oauth.common.EncryptUtil;
import com.ljf.springsecurity.oauth.model.UserDTO;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author Administrator
* @version 1.0
**/
@Component
public class TokenAuthenticationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
//解析出头中的token
String token = httpServletRequest.getHeader("json-token");
if(token!=null){
String json = EncryptUtil.decodeUTF8StringBase64(token);
//将token转成json对象
JSONObject jsonObject = JSON.parseObject(json);
//用户身份信息
// UserDTO userDTO = new UserDTO();
// String principal = jsonObject.getString("principal");
// userDTO.setUsername(principal);
System.out.println("json:"+jsonObject.getString("principal"));
UserDTO userDTO = JSON.parseObject(jsonObject.getString("principal"), UserDTO.class);
//用户权限
JSONArray authoritiesArray = jsonObject.getJSONArray("authorities");
String[] authorities = authoritiesArray.toArray(new String[authoritiesArray.size()]);
//将用户信息和权限填充 到用户身份token对象中
UsernamePasswordAuthenticationToken authenticationToken
= new UsernamePasswordAuthenticationToken(userDTO,null, AuthorityUtils.createAuthorityList(authorities));
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
//将authenticationToken填充到安全上下文
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
filterChain.doFilter(httpServletRequest,httpServletResponse);
}
}
2.2 Spring Security配置
开启方法保护,并增加Spring配置策略,除了/login方法不受保护(统一认证要调用),其他资源全部需要认证才能访 问。

2.3 controller使用用户信息
1.说明:
在controller中方法前的 @PreAuthorize("hasAuthority('p3')"),会使用2.1.3章节 中介绍的filter,filter封装的UsernamePasswordAuthenticationToken 中封装的信息和这里的@PreAuthorize的内容进行比对验证。
2.代码截图如下,从Authentication获取用户信息。

本文介绍了如何在微服务环境中实现用户鉴权拦截,通过解析token并利用SpringSecurity进行权限管理。具体步骤包括自定义filter解析token,创建Authentication对象并保存到安全上下文,以及配置SpringSecurity保护资源。示例代码展示了如何在controller中使用用户信息进行权限校验。
1267

被折叠的 条评论
为什么被折叠?



