Session sharing based SpringBoot + Redis with single sign-on


title: Session-based sharing and single sign-on SpringBoot + Redis of
DATE: 2019-07-23 02:55:52
the Categories:

  • Architecture
    author: mrzhou
    Tags:
  • SpringBoot
  • repeat
  • session
  • sign in

Session sharing based SpringBoot + Redis with single sign-on

Foreword

Redis is implemented using Session sharing, in fact, the Internet has a lot of examples, and this is to ensure that the cluster deployment redis most typical usage scenarios. In SpringBoot project, in fact, you can run the code without writing a line, simply add a line to add annotations and dependence can be achieved (of course, the configuration information is still needed).
The project is then simply deployed to different tomcat, such as a different port (A, B), but the access path is the same project. A set method used at this time, and then use the get method in B, B can be found in A can acquire the content set.

But if put such a project deployed in multiple tomcat is said to achieve a single sign-on, it would be wrong.

The so-called single sign-on refers to a different project, you need only log on any project, and other projects required to log.

Likewise the above example, we have two methods set and get two items are placed (set, get), and the manner in two clusters are deployed to the server projects A and B, respectively, and then access the server A set and get B server, you will not find exactly the results you want.

The same project set / get

Add depend not say, direct the most simple way

@SpringBootApplication
@EnableRedisHttpSession
@RestController
public class SessionShareApplication {

    public static void main(String[] args) {
        SpringApplication.run(SessionShareApplication.class, args);
    }

    @Autowired
    HttpSession session;
    @Autowired
    HttpServletRequest req;
    
    @GetMapping("/set")
    public Object set() {
        session.setAttribute("state", "state was setted.");
        Map<String, Object> map = new TreeMap<>();
        map.put("msg", session.getAttribute("state"));
        map.put("serverPort", req.getLocalPort());
        return map;
    }
    @GetMapping("/get")
    public Object get() {
        Map<String, Object> map = new TreeMap<>();
        map.put("msg", session.getAttribute("state"));
        map.put("serverPort", req.getLocalPort());
        return map;
    }
}

The item playing war package, are deployed in tomcatA (port 8080), tomcatB (port 8081), and then set by tomcatA / set methods session, then use tomcatB / get the method to obtain the value of the session. But this is only achieved the same project sharing session. Not a single sign-on.

For verification, we will not imitate split set / get method for the two projects.

Split set / get two projects

  • get the project
@SpringBootApplication
@EnableRedisHttpSession
@RestController
public class SetApplication {

    public static void main(String[] args) {
        SpringApplication.run(SetApplication.class, args);
    }

    @Autowired
    HttpSession session;
    @Autowired
    HttpServletRequest req;
    
    @GetMapping("/")
    public Object set() {
        session.setAttribute("state", "state was setted.");
        Map<String, Object> map = new TreeMap<>();
        map.put("msg", session.getAttribute("state"));
        map.put("serverPort", req.getLocalPort());
        return map;
    }
}

The project is packaged as set.war

  • set project
@SpringBootApplication
@EnableRedisHttpSession
@RestController
public class GetApplication {

    public static void main(String[] args) {
        SpringApplication.run(GetApplication.class, args);
    }

    @Autowired
    HttpSession session;
    @Autowired
    HttpServletRequest req;
    
    @GetMapping("/")
    public Object get() {
        Map<String, Object> map = new TreeMap<>();
        map.put("msg", session.getAttribute("state"));
        map.put("serverPort", req.getLocalPort());
        return map;
    }
}

The project is packaged as get.war
then were the set.war, get.war deployed in tomcatA and tomcatB, then by tomcatA / set setting session, and then by tomcatB / get it found it impossible to obtain the value of the session.

problem analysis

Although the path we use are the same, but in fact the two projects, and in front of a project is completely different, the problem is that the session cookie and by default is associated with the path of the project, a project in the same situation cookie path-dependent program requires two methods are the same, obtaining the value of the session so there is no problem, but in the latter case, the cookie path belong to different items, the second item on the unable to obtain session content first project set up.

Solution

In fact, the solution is very simple in springboot project. Since the cookie path has changed, then we let it be configured to the same path will be solved.
Are added in each subproject in a configuration like or directly set a cookie path, if you have a domain name can also set a limit domain name, such as set.xxx.com and get.xxx.com this case and we need to set the cookie domain name as xxx.com, to ensure not able to get the cookie value xxx.com the domain name under which the item. This will ensure regular access to shared values of the session.

@Configuration
public class CookieConfig {

    @Bean
    public static DefaultCookieSerializer defaultCookieSerializer() {
        DefaultCookieSerializer serializer = new DefaultCookieSerializer();
        serializer.setCookiePath("/");
        //serializer.setDomainName("xxx.com"); //如果使用域名访问,建议对这一句进行设置    
        return serializer;
    }
}

Above is the correct way to open honest redis achieve single sign-on.

Guess you like

Origin www.cnblogs.com/askmiw/p/11229437.html
Recommended