SpringBoot前后端分离整合cas(客户端)

SpringBoot前后端分离整合cas(客户端)

cas认证详细流程:
SpringBoot前后端分离整合cas(客户端)_第1张图片
前后端分离:项目前端使用nginx启动,后端是springBoot服务;
nginx可以统一管理Cookie,避免出现跨域问题。

添加依赖

  <dependency>
            <groupId>org.jasig.cas.client</groupId>
            <artifactId>cas-client-support-springboot</artifactId>
            <version>3.6.2</version>
  </dependency>

配置文件添加

cas:
  # cas服务端地址,nginx代理
  server-url-prefix: http://127.0.0.1:9010/cas
  # cas服务端登录地址,nginx代理
  server-login-url: http://127.0.0.1:9010/cas/login
  # 当前服务程序地址,nginx代理
  client-host-url: http://127.0.0.1:9010
  validation-type: cas3
  
# 不校验权限路径(正则表达式)
ignorePattern: ".*\\/api\\/rest\\/test\\/.*|.*\\/test\\/hello"

启动类添加注解@EnableCasClient

@EnableCasClient
@SpringBootApplication
public class TestApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(TobApplication.class, args);
    }
    
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(TobApplication.class);
    }
}

重写cas客户端配置

@Configuration
public class SmsCasClientConfigurer implements CasClientConfigurer {
    @Value("${host-url}")
    private String serverName;
    @Value("${ignorePattern}")
    private String ignorePattern;
    @Value("${cas.server-login-url}")
    private String serverLoginUrl;
    @Value("${casLogin-url}")
    private String casLoginUrl;

    @Override
    public void configureAuthenticationFilter(FilterRegistrationBean authenticationFilter) {
        Map initParameters = authenticationFilter.getInitParameters();
        // 设置不校验权限路径  
        initParameters.put("ignorePattern", ignorePattern);  
    } 
}

默认Get接口

@RestController
@RequestMapping("/api/common")
public class CommonController {
    @GetMapping("/getUserName")
    public String getUserName(HttpServletRequest request) {
        if(request.getUserPrincipal()!=null){
        	return request.getUserPrincipal().getName();
        }else{
			return "";
		}
    }

前端添加拦截

我的前端使用的vue,若不是可以参考文章底部博客。

前端登陆之后cas服务端会默认添加"TGC"的cookie到浏览器,然后会跳转到前端页面,前端首次去访问后端程序时需要验证票据,所以默认第一个请求接口尽量是get请求,若是post可能会被cas重定向成get。下面的2,3步你也可以不做,直接在路由守卫permission.js中直接调用接口,根据自己的实际情况使用此博客即可。

1,get请求接口src\api\commonAPI.js

import { httpServer } from 'axios'

export function getUserNameAPI (data) {
  return httpServer.get(`api/common/getUserName`);
}

2,设置缓存src\store\modules\user.js

import { getUserNameAPI } from "@/api/commonAPI.js";

const state = {
  username: ""
}

/*从session获取username,vue页面中可调用:如下示例
...
{{getUserName}}
...
computed: {
    ...mapGetters(["getUserName"]),
}
...
*/
const getters = {
  getUserName: state => {
    var name;
    if (sessionStorage.getItem('username')) {
      name= sessionStorage.getItem('username');
    } else {
      name= state.username;
    }
    return name;
  }
}

const mutations = {
  ["SET_USER_NAME"](state, data) {
    state.username = data === null ? "" : data;
    sessionStorage.setItem('username',data)
  }
}

//调用接口并添加username到session中
const actions = {
  getUserName({commit}) {
    return new Promise(resolve => {
      getUserNameAPI().then(res => {
        commit("SET_USER_NAME", res);
        resolve()
      });
    })
  }
}

export default {
  state,
  getters,
  mutations,
  actions
};

3,添加user.js到src\store\index.js

import Vue from "vue";
import Vuex from "vuex";
import createPersistedState from "vuex-persistedstate";
import user from "./modules/user";

Vue.use(Vuex);

export default new Vuex.Store({
  modules: {
    user
  },
  plugins: [createPersistedState({ storage: window.sessionStorage })]
});

4,修改路由守卫src\permission.js

//路由拦截
import  {Spin} from "view-design";
import "view-design/dist/styles/iview.css";
import router from "./router";
import store from "./store";
import Cookies from "js-cookie";

Spin.show({
  render: (h) => {
    return h('div', [
      h('div', '登录中...')
    ])
  }
})

router.beforeEach((to, from, next) => {
  //走cas校验
  if(true){
    let CUR_URL = window.location.href;
    //判断是否存在TGC的Cookies,不存在则跳转到cas登录页面登录,登陆成功之后cas服务端会添加TGC的Cookies到浏览器中
    let CASTGC_COOKIE = Cookies.get("TGC")?true:false;
    if (CASTGC_COOKIE) {
      // 登录
      if (CUR_URL.indexOf("?ticket") > -1) {
        window.location.href = CUR_URL.split("?ticket")[0];
      }
      Promise.all([store.dispatch('getUserName')]).then(opts => {
        Spin.hide();
        next();
      })
    } else {
      window.location.href = `http://127.0.0.1:9010/cas/login?service=${window.location}`;
    }
  } else {
    //不走cas校验
    Promise.all([store.dispatch('getUserName')]).then(opts => {
      Spin.hide();
      next();
    })
  }
});

nginx代理

worker_processes  1;
events {
    worker_connections  1024;
}
http {
	include /etc/nginx/mime.types;
    default_type application/octet-stream;
    		
    sendfile on;
    keepalive_timeout 65;
    
	server {
        	listen       9010;
        	server_name  127.0.0.1;
        	
        	#nginx代理前端
			location / {
            	autoindex on;
            	add_header Access-Control-Allow-Origin *;
            	add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
            	# 静态资源位置
            	alias /usr/share/nginx/html;
            	index  index.html;
            	try_files $uri $uri/ /index.html last;
        	}
			
			#我的后端服务,my_server为我的服务前缀
			location ^~  /my_server/ {
            	proxy_pass http://127.0.0.1:8091/my_server/;
            	add_header Access-Control-Allow-Origin *;
            	proxy_cookie_path /my_server/ /;  #解决nginx转发丢失cookie的问题

            	# 支持 OPTIONS 请求,并设置预检请求结果的缓存时间
            	if ($request_method = 'OPTIONS') {
                	add_header 'Access-Control-Max-Age' 1728000;
                	add_header 'Content-Type' 'text/plain charset=UTF-8';
                	add_header 'Content-Length' 0;
                	return 204;
            	}
         	}

			#cas服务端
			location ^~  /cas/ {
            	proxy_pass http://127.0.0.1:8092/cas/;
            	add_header Access-Control-Allow-Origin *;
            	proxy_cookie_path /cas/ /;  #解决nginx转发丢失cookie的问题

            	# 支持 OPTIONS 请求,并设置预检请求结果的缓存时间
            	if ($request_method = 'OPTIONS') {
                	add_header 'Access-Control-Max-Age' 1728000;
                	add_header 'Content-Type' 'text/plain charset=UTF-8';
                	add_header 'Content-Length' 0;
                	return 204;
            	}
         	}
     }
}

参考博客:
https://blog.csdn.net/weixin_41358538/article/details/130880319

你可能感兴趣的:(spring,boot,后端,java)