手撸SSO单点登录(三):统一跳转至SSO登录页

一、目标

这一章节的目标主要是讲解第一次打开系统,无论OA系统,还是认证系统等,在未登录的情况下怎么统一跳转至SSO登录页面。client 用OA系统代替更直观
视频讲解地址https://www.bilibili.com/video/BV1qB4y117Lj/

二 、系统UML工程类图

在这里插入图片描述
SmartSsoConfig、LoginFilter、LoginController这三个类是主要的实现类

三、代码实现

1.com.yuantai.config.SmartSsoConfig

@Configuration
public class SmartSsoConfig {

    @Value("${sso.server.url}")
    private String serverUrl;
    @Value("${sso.app.id}")
    private String appId;
    @Value("${sso.app.secret}")
    private String appSecret;
    /**
     * 单点登录Filter容器
     * @return
     */
    @Bean
    public FilterRegistrationBean<SmartContainer> smartContainer() {
        SmartContainer smartContainer = new SmartContainer();
        smartContainer.setServerUrl(serverUrl);
        smartContainer.setAppId(appId);
        smartContainer.setAppSecret(appSecret);

        // 忽略拦截URL,多个逗号分隔
        smartContainer.setExcludeUrls("/login,/logout,/oauth2/*,/custom/*,/assets/*");

        smartContainer.setFilters(new LogoutFilter(), new LoginFilter());

        FilterRegistrationBean<SmartContainer> registration = new FilterRegistrationBean<>();
        registration.setFilter(smartContainer);
        registration.addUrlPatterns("/*");
        registration.setOrder(1);
        registration.setName("smartContainer");
        return registration;
    }
}
  • smartContainer() 初始化了参数、注册SmartContainer过滤器
  • SmartContainer过滤器存储了基础参数、doFilter对登录进行验证处理

2.com.yuantai.filter.LoginFilter

  • isAccessAllowed()方法判断登录三种情况(已登录、第一次登录成功、未登录)
  • redirectLogin(request, response); 属于第三种情况未登录、重定向到SSO统一登录页面(http://authentication.sso.com:8080/login?appId=xxx&redirectUri=http://xxx.sso.com:8080/)

3.com.yuantai.controller.LoginController

 /**
     * 登录页
     * @param redirectUri
     * @param appId
     * @param request
     * @return
     */
    @RequestMapping(method = RequestMethod.GET)
    public String login(
            @RequestParam(value = SsoConstant.REDIRECT_URI, required = true) String redirectUri,
            @RequestParam(value = Oauth2Constant.APP_ID, required = true) String appId,
            HttpServletRequest request) throws UnsupportedEncodingException {
        String tgt = sessionManager.getTgt(request);
        if (StringUtils.isEmpty(tgt)) {
            return goLoginPath(redirectUri, appId, request);
        }
        return generateCodeAndRedirect(redirectUri, tgt);
    }

当2步发起重定向后会跳转到login的方法(GET请求)跳转到统一的SSO登录页面

总结

  • 客户端发起请求,这3步完成了统一跳转至SSO登录页面。
  • 动手是学习起来最快的方式,不要让眼睛是感觉看会了,但上手操作就废了。也希望有需要的读者可以亲手操作一下,把你的想法也融入到可落地实现的代码里,看看想的和做的是否一致。

代码下载方式

搜索微信公众号:攻城狮小章鱼 ,关注后 ,发SSO源码获取源代码
在这里插入图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
以下是一个简单的 Java 实现 SSO 单点登录的代码: 1. 创建一个 SSOServer 类,用于处理用户登录和注销: ``` public class SSOServer { private static SSOServer instance = null; private Set<String> tokens = new HashSet<String>(); private SSOServer() {} public static SSOServer getInstance() { if (instance == null) { instance = new SSOServer(); } return instance; } public boolean login(String token) { if (tokens.contains(token)) { return false; } tokens.add(token); return true; } public void logout(String token) { tokens.remove(token); } public boolean isValid(String token) { return tokens.contains(token); } } ``` 2. 创建一个 LoginServlet 类,用于处理用户登录请求: ``` public class LoginServlet extends HttpServlet { private static final String LOGIN_PAGE = "/login.jsp"; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); // 验证用户名和密码 if (username.equals("admin") && password.equals("admin")) { // 生成随机的 token String token = UUID.randomUUID().toString(); // 将 token 存储到 session 中 request.getSession().setAttribute("token", token); // 将 token 存储到 SSO 服务器中 SSOServer.getInstance().login(token); // 跳转成功面 response.sendRedirect(request.getContextPath() + "/success.jsp"); } else { // 登录失败,跳转登录面 request.setAttribute("error", "用户名或密码错误"); request.getRequestDispatcher(LOGIN_PAGE).forward(request, response); } } } ``` 3. 创建一个 LogoutServlet 类,用于处理用户注销请求: ``` public class LogoutServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 从 session 中获取 token String token = (String) request.getSession().getAttribute("token"); // 将 token 从 SSO 服务器中删除 SSOServer.getInstance().logout(token); // 销毁 session request.getSession().invalidate(); // 跳转登录面 response.sendRedirect(request.getContextPath() + "/login.jsp"); } } ``` 4. 在需要进行单点登录的应用程序中,创建一个 Filter 类,用于验证用户是否已登录: ``` public class SSOFilter implements Filter { private static final String LOGIN_PAGE = "/login.jsp"; public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; // 从 session 中获取 token String token = (String) httpRequest.getSession().getAttribute("token"); if (token == null || !SSOServer.getInstance().isValid(token)) { // 用户未登录或已过期,跳转登录面 httpResponse.sendRedirect(httpRequest.getContextPath() + LOGIN_PAGE); } else { // 用户已登录,继续执行请求 chain.doFilter(request, response); } } } ``` 5. 在 web.xml 中配置 Filter: ``` <filter> <filter-name>SSOFilter</filter-name> <filter-class>com.example.sso.SSOFilter</filter-class> </filter> <filter-mapping> <filter-name>SSOFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ``` 通过以上步骤,就可以实现 JavaSSO 单点登录功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值