SpringSecurity5-教程4-Cookie单点登录

该代码段展示了一个基于Cookie的单点登录(SSO)过滤器,用于从cookie中获取token,解析并设置用户的登录状态。如果cookie存在有效token,它会避免重定向到登录页面。过滤器检查token是否改变,更新用户信息,并使用SpringSecurity进行认证和授权。
/**
 * 从cookie获取 token,解析并设置登录态
 * 当cookie有token时,处理/oauth/authorize将不会再跳入登录页
 */
@Slf4j
@Getter
@Setter
@WebFilter("/*")
public class CookieSsoFilter extends OncePerRequestFilter {
    @Autowired
    private UserService userService;

    @Autowired
    private HttpSession session;

    private SecurityContextRepository securityContextRepository = new HttpSessionSecurityContextRepository();

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        if (request.getCookies() == null) {
            filterChain.doFilter(request, response);
            return;
        }
        String userToken = getUserToken(request);
        if (Strings.isBlank(userToken)) {
            filterChain.doFilter(request, response);
            return;
        }
        boolean tokenNotChanged = userToken.equals(session.getAttribute("usertoken"));
        if (tokenNotChanged) {
            filterChain.doFilter(request, response);
            return;
        }

        // 更新用户
        User user = userService.find(userToken);
        if (user == null) {
            filterChain.doFilter(request, response);
            return;
        }
        session.setAttribute("usertoken", usertoken);
        // 保存认证结果
        saveAuthentication(request, response, user);
        filterChain.doFilter(request, response);
    }

    private void saveAuthentication(HttpServletRequest request, HttpServletResponse response, user user) {
        List<SimpleGrantedAuthority> authorities = Lists.newArrayList();
        authorities.add(new SimpleGrantedAuthority("ROLE_USER")); // /oauth/authorize等接口需要这个权限
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(user, user.getPassword(), authorities);
        authentication.setDetails(new WebAuthenticationDetails(request));
        HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response);
        SecurityContext securityContext = securityContextRepository.loadContext(holder);
        securityContext.setAuthentication(authentication);
        SecurityContextHolder.setContext(securityContext);
        securityContextRepository.saveContext(securityContext, holder.getRequest(), holder.getResponse());
    }
}

public String getUserToken(HttpServletRequest request) {
        return  Arrays.stream(request.getCookies())
                .filter(c -> c.getName().equals("userToken"))
                .findAny().map(Cookie::getValue).orElse(null);
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值