springboot 前后端分离 cas配置

  1. 项目介绍
    前端react, 后台springboot,接入公司CAS。

  2. 首次登录逻辑
    2.a 前端访问后台,后台返回{login:“false”}
    2.b 前端收到{login:“false”}后,去请求后台/client1/login (springboot cas 放行该URL 不做认证)
    2.c /client1/login 处理逻辑如下:

if(request.getParameter("ticket") 不为 true){
	// 重定向去cas认证获取ticket
} else {
	// 带ticket 用HTTP请求的方式访问cas 获取用户信息(用户名), 并自己生成ssessionid;
	// 重定向前端首页(用户访问的地址)
}
  1. 实现逻辑(方法)
    3.a 自定义MyAuthenticationEntryPoint 继承AuthenticationEntryPoint 的,并重写 commence() 方法
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSONObject;
import ×××.preprocessclient.myutils.CommUtil;
import ×××.preprocessclient.myutils.HttpUtil;
import ×××.preprocessclient.myutils.MyConstants;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.savedrequest.DefaultSavedRequest;
import org.springframework.util.concurrent.SuccessCallback;

public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint {
    String logTag = "MyAuthenticationEntryPoint ";
    CommUtil cutil = new CommUtil();
    HttpUtil hutil = new HttpUtil();
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response,
            AuthenticationException authException) throws IOException, ServletException {
        // redirect to login page. Use https if forceHttps true      
        String requestURL =  request.getRequestURI();     
        Map<String, String> cookie = formatCookie(request);
        
        if (cookie.containsKey("sessionid") & cookie.get("sessionid") != null){
            String sessionid = cookie.get("sessionid");
            cutil.mlog(logTag + "has sessionid " + sessionid);

            Cookie thisCookie = new Cookie("sessionid", sessionid);
            thisCookie.setDomain("10.×××.×××.×××");  // 前端IP
            thisCookie.setPath("/");
            thisCookie.setSecure(false);            
            response.addCookie(thisCookie);
            response.setContentType("application/json;charset=utf-8");

            String postback = successfulLogin(request, sessionid);
            JSONObject pb = cutil.stringToJSONObject(postback);
            PrintWriter out = response.getWriter();
            out.write(pb.toJSONString());
            out.flush();
            out.close();

        } else {
            cutil.mlog(logTag + "no ssesionid !!!");
            response.setContentType("application/json;charset=utf-8");
            PrintWriter out = response.getWriter();
            StringBuffer sb = new StringBuffer();
            JSONObject notLogin = new JSONObject();
            notLogin.put("login", "false");  // 本文步骤 2.a 返回的内容
            notLogin.put("err_msg", "not login");
            out.write(notLogin.toJSONString());
            out.flush();
            out.close();
        }
    }

    private Map<String, String> formatCookie(HttpServletRequest request){
        Map<String, String> cookie = new HashMap<>();

        Cookie[] requestCookies = request.getCookies();
        if(requestCookies != null){
            for(int i=0; i<requestCookies.length; i++){
                cutil.mlog(logTag + "format cookie name: " + requestCookies[i].getName() + " value: " + requestCookies[i].getValue());
                cookie.put(requestCookies[i].getName(), requestCookies[i].getValue());
            }
        }
        return cookie;
    }

    private String successfulLogin(HttpServletRequest request, String sessionid) {
        String requestURL = request.getRequestURI();
        String method = request.getMethod();
        cutil.mlog(logTag + "successfulLogin " + requestURL + " " + method);

        Map<String, String> para = new HashMap<>();
        para.put("sessionid", sessionid);
        String url = MyConstants.localhostIP + "/preprocess/ticket/username";

        String userName = hutil.httpPostString(url, para, sessionid, "UTF-8", "UTF-8");
        checkUser(userName);

        Map<String, String> requestMap = new HashMap<>();
        requestMap.put("userName", userName);

        Enumeration<String> requestParas = request.getParameterNames();
        while(requestParas.hasMoreElements()){
            String requestPara = requestParas.nextElement();
            requestMap.put(requestPara, request.getParameter(requestPara));
        }

        String result = "";
        if (method.equals("POST")){
            result = hutil.httpPostString(MyConstants.zuulUrlIP + requestURL, requestMap, userName, "UTF-8", "UTF-8");
        }else{
            result = hutil.httpclientGetString(MyConstants.zuulUrlIP + requestURL, userName);
        }
        return result;
    }


    public void checkUser(String username){
        String url = MyConstants.localhostIP + "/checkuser";
        Map<String,String> map = new HashMap<>();
        map.put("username", username);
        cutil.mlog(logTag + "check user " + hutil.httpPostString(url, map, null, "UTF-8", "UTF-8"));

    }
}

3.b 新建一个类WebSecurityConfig 继承 WebSecurityConfigurerAdapter,并使用自定义的MyAuthenticationEntryPoint

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(jsr250Enabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    CommUtil cutil = new CommUtil();
    
    @Override
    public void init(WebSecurity web) throws Exception {
        // TODO Auto-generated method stub
        super.init(web);
    }
    @Override
    protected void configure(final HttpSecurity httpSecurity) throws Exception {
        httpSecurity.exceptionHandling()
            .accessDeniedPage("/error/403")
            .authenticationEntryPoint(new MyAuthenticationEntryPoint())
            .authorizeRequests()
                .antMatchers( "/client1/login").permitAll()
                .anyRequest().authenticated()
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值