39

SpringBoot实现单点登录SOS

 3 years ago
source link: http://asche.top/archives/springbootshi-xian-dan-dian-deng-lu-so
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

单点登录(Single Sign On),简称为SSO,是比较流行的企业业务整合的解决方案之一。 SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

SOSExample 是使用SpringBoot框架实现的一个单点登录简单demo,主要为功能即在某个子系统登录或者退出登录后,在其余的子系统中也表现出相同的状态。

项目思路

本项目包含两个模块,一个是负责统一登录认证的模块,另一个即正常业务模块。业务模块使用多个不同端口启动来模仿多个子系统。某个子系统登录时,将相应的登录信息发送给业务服务器,业务服务器再将信息传给统一认证服务器,成功之后,返回浏览器,同时浏览器也会使用Ajax发送异步请求,向其余的子系统发送相应信息(可以不包括密码),然后其余子系统返回结果中包含Set-Cookie(这里可以只返回个用户名),浏览器收到后会在其余子系统中添加相应的Cookie。有了Cookie,事情就应该好办了。后面详细的可以参考代码。

关键源码

业务服务器中的登录接口,主要负责接收浏览器登录信息,然后交给认证服务器去认证,登录成功则在当前Session中标记一下

@PostMapping("/login")
    public String login(String username, String password,
                        HttpServletRequest request, Model model) throws IOException {
        String url = String.format("http://localhost:9090/login?username=%s&password=%s", username, password);
        String responseContent = HttpUtils.getResponseContent(url);
        System.out.println("login:" + responseContent);
        if("1".equals(responseContent)){
            request.getSession().setAttribute("user", username);
            return "redirect:home";
        }
        model.addAttribute("msg", "login failed!");
        return "login";
    }

这里只是主要用于浏览器异步请求的时候为子系统添加Cookie,作为demo,没有考虑太多安全因素。

@RequestMapping("/addCookie")
    @ResponseBody
    public String addCookie(String cookie, HttpServletResponse response){
        response.addCookie(new Cookie("user", cookie));
        return "1";
    }

这里是注销登录,主要包含清除当前Session中的标记,以及认证服务端也清除登录标记。

@GetMapping("/logout")
    public String logout(HttpServletRequest request, HttpServletResponse response) throws IOException {
        HttpSession session = request.getSession();
        Object user = session.getAttribute("user");
        System.out.println(user);
        if (user != null){
            String url = String.format("http://localhost:9090/logout?username=%s", user.toString());
            HttpUtils.getResponseContent(url);
            session.setAttribute("user", null);
        }
        return "redirect:home";
    }

然后就是统一认证服务端代码了,代码很少,就不讲了。

@Controller
public class LoginController {

    private static Set<String> userSet = new HashSet<>();

    @Autowired
    LoginMapper loginMapper;

    @GetMapping("/login")
    @ResponseBody
    public String login(String username, String password){
        Login login = loginMapper.selectByPrimaryKey(username);
        userSet.add(username);
        return login != null && login.getPassword().equals(password) ? "1" : "0";
    }

    @GetMapping("/loginCheck")
    @ResponseBody
    public String checkLogin(String username){
        return userSet.contains(username) ? "1" : "0";
    }

    @GetMapping("/logout")
    @ResponseBody
    public String logout(String username){
        return userSet.remove(username) ? "1" : "0";
    }
}

前端登录js部分代码

<script th:inline="javascript">
    /*<![CDATA[*/

    var url1 = "http://localhost:8080/addCookie?cookie=";
    var url2 = "http://localhost:8081/addCookie?cookie=";

    function login(){
        var user = $("#username").val()

        $("form#login-form").submit();

        $.ajax({
            url: url1 + user,
            type: "get",
            dataType: "jsonp"
        })
        $.ajax({
            url: url2 + user,
            type: "get",
            dataType: "jsonp"
        })
        // alert(form)
    }
</script>

然后数据库的话,这里附上SQL语句,主要是user和password

create table login
(
    user     varchar(12)             not null,
    password varchar(16) default '0' null,
    name     varchar(20)             null,
    constraint login_user_uindex
        unique (user)
)
    charset = utf8;

alter table login
    add primary key (user);

最后完整源码上传到了Github: SOSExample


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK