SpringBoot+Vue整合CAS

  • Post author:
  • Post category:vue




依赖

       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.11</version>
        </dependency>
        <dependency>
            <groupId>net.unicon.cas</groupId>
            <artifactId>cas-client-autoconfig-support</artifactId>
            <version>2.3.0-GA</version>
        </dependency>



配置

server:
  port: 8088

#cas服务端的地址
cas:
  server-url-prefix: http://test.sso.shanhaiyh.com
  #cas服务端的登录地址
  server-login-url: http://test.sso.shanhaiyh.com/login
  #客户端访问地址
  client-host-url: http://192.168.1.216:8088
  #验证的协议
  validation-type: cas



配置类 CasAutoConfig

package com.example.cas.config;

import net.unicon.cas.client.configuration.CasClientConfigurerAdapter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;

@Configuration
public class CasAutoConfig extends CasClientConfigurerAdapter {
    @Value("${cas.server-login-url}")
    private String serverLoginUrl;

    @Value("${cas.client-host-url}")
    private String serverLocalUrl;


    @Value("${cas.server-url-prefix}")
    private String serverUrlPrefix;

    @Override
    public void configureAuthenticationFilter(FilterRegistrationBean authenticationFilter) {
        Map<String, String> initParameters = authenticationFilter.getInitParameters();
        initParameters.put("authenticationRedirectStrategyClass", "com.example.cas.config.CustomAuthRedirectStrategy");
    }


    @Override
    public void configureValidationFilter(FilterRegistrationBean validationFilter) {

        Map<String, String> initParameters = validationFilter.getInitParameters();
        initParameters.put("encodeServiceUrl", "false");
        // 配置地址,这里还可以配置很多,例如cas重定向策略等。
        initParameters.put("ignorePattern", "/casLogin/*");
        validationFilter.setInitParameters(initParameters);
        super.configureAuthenticationFilter(validationFilter);

    }


    @Bean
    public FilterRegistrationBean corsFilter() {

        // 1.创建 CORS 配置对象
        CorsConfiguration config = new CorsConfiguration();
        // 支持域
        ArrayList<String> strings = new ArrayList<>();
        strings.add("http://192.168.1.216:8088");
        config.setAllowedOriginPatterns(Collections.singletonList("*"));
        // 是否发送 Cookie
        config.setAllowCredentials(true);
        // 支持请求方式
        config.addAllowedMethod("*");
        // 允许的原始请求头部信息
        config.addAllowedHeader("*");
        // 暴露的头部信息
        config.addExposedHeader("*");

        // 2.添加地址映射
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean<CorsFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new CorsFilter(source));
        registrationBean.setOrder(-2147483648);
        return registrationBean;

    }

}



解决前后端分离时跨越问题

package com.example.cas.config;

import com.example.cas.common.ResData;
import org.jasig.cas.client.authentication.AuthenticationRedirectStrategy;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@Component
public class CustomAuthRedirectStrategy implements AuthenticationRedirectStrategy {

    @Override
    public void redirect(HttpServletRequest request, HttpServletResponse response, String s) throws IOException {
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/json; charset=utf-8");
        String url = request.getParameter("url");
        if (!StringUtils.isEmpty(url)) {
            url = "http://192.168.1.216:9528/";
        }
        PrintWriter out = response.getWriter();
        String data = ResData.error(401, "登录认证失败,请重新登录", "http://test.sso.shanhaiyh.com/login?service=http://192.168.1.216:8088/casLogin?url=" + url).toString();
        out.write(data);
        out.flush();
        out.close();
    }

}



测试控制器

package com.example.cas.controller;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.example.cas.common.ResData;
import com.example.cas.vo.PowerRmiVo;
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.validation.AssertionImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

@Controller
public class CASController {

    @Value("${cas.server-login-url}")
    private String serverLoginUrl;


    @Value("${cas.client-host-url}")
    private String serverLocalUrl;

    @GetMapping("/casLogin")
    public String casLogin(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String url = request.getParameter("url");
        if (!StringUtils.isEmpty(url)) {
            url = "http://192.168.1.216:9528/";
        }
        //由于用户信息存储在session中,因此可以从session中获取到存储用户信息的AssertionImpl对象从而获取用户信息
        HttpSession session = request.getSession();
        AssertionImpl assertion = (AssertionImpl) session.getAttribute("_const_cas_assertion_");
        String username = null;
        String ssoUrl = "";
        if (assertion != null) {
            AttributePrincipal principal = assertion.getPrincipal();
            username = principal.getName();
            if (StringUtils.isEmpty(username)) {
                ssoUrl = serverLoginUrl + "?service=" + URLEncoder.encode(serverLocalUrl + "/casLogin?url=" + url, StandardCharsets.UTF_8);
                return "redirect:" + ssoUrl;
            }
        }
        return "redirect:" + url;
    }


    @RequestMapping("/order")
    @ResponseBody
    public Object order(HttpServletRequest request) throws IOException {
        return ResData.success(HttpServletResponse.SC_OK, "操作成功", request.getParameter("id"));
    }


    @RequestMapping("/casLogout")
    @ResponseBody
    public ResData casLogout(HttpSession session) throws IOException {
        session.invalidate();
        String ssoUrl = serverLoginUrl + "?service=" + URLEncoder.encode(serverLocalUrl + "/cas/casLogin", StandardCharsets.UTF_8);
        return ResData.success(HttpServletResponse.SC_OK, "退出成功", ssoUrl);
    }

    @GetMapping("/getUserInfo")
    @ResponseBody
    public Object getUserInfo(HttpServletRequest request) throws IOException {
        //由于用户信息存储在session中,因此可以从session中获取到存储用户信息的AssertionImpl对象从而获取用户信息
        HttpSession session = request.getSession();
        AssertionImpl assertion = (AssertionImpl) session.getAttribute("_const_cas_assertion_");
        if (assertion != null) {
            AttributePrincipal principal = assertion.getPrincipal();
            String username = principal.getName();
            return ResData.success(1, "操作成功", username);
        }
        return ResData.error(0, "操作失败", "");
    }


    @GetMapping("/getMenuList")
    @ResponseBody
    public Object getMenus(HttpServletRequest request) throws IOException {
        //由于用户信息存储在session中,因此可以从session中获取到存储用户信息的AssertionImpl对象从而获取用户信息
        HttpSession session = request.getSession();
        AssertionImpl assertion = (AssertionImpl) session.getAttribute("_const_cas_assertion_");
        if (assertion != null) {
            AttributePrincipal principal = assertion.getPrincipal();
            String username = principal.getName();
            String url = "https://api.shanhaiyh.com/shiant-api-c/service";
            List<PowerRmiVo> lists = null;
            for (int i = 0; i < 3; i++) {
                HttpResponse response = HttpRequest.get(url + "/shop/getMenuByUserName?userName=" + username).execute();
                if (response != null) {
                    String body = response.body();
                    JSONObject jsonObject = JSON.parseObject(body);
                    Object code = jsonObject.get("code").toString();
                    if ("0".equals(code)) {
                        Object data1 = jsonObject.get("data");
                        lists = JSON.parseArray(data1.toString(), PowerRmiVo.class);
                        break;
                    }
                }
            }
            return ResData.success(1, "操作成功", lists);
        }
        return ResData.error(0, "操作失败", "");
    }
}



测试效果:


单点登录成功后通过用户查询到的菜单信息

在这里插入图片描述



版权声明:本文为qq_45834006原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。