SSO Single Sign-on system implementation

Source: Internet
Author: User
Tags json redis uuid tomcat
First, preface

Small in the previous blog to introduce you to the use of single sign-on evolution process, the last step when the small series to show you the distributed architecture. The single sign-on system is used. This blog continues to follow a blog to achieve a single sign-on system. Second, the environment preparation

Eclipse

Redis Three, Single sign-on flowchart

This is a simple single sign-on flowchart, on that Taobao, when we improve the Taobao home page is not logged in, click on the login, will jump to the user login interface. At this point the user login interface is part of our SSO system, according to the requirements of the login, will receive the user name and password, and then according to the user name query password is correct.
If not correct, jump to the login page, the prompt is incorrect;
The following steps are necessary if correct:
1. Generate a UUID as token;
2. The user information is serialized to the Redis, the stored key is token, after the storage is successful, the token is returned;
3. Store tokens in cookies;
4. Determine if there is a callback URL, if any, jump to the specified URL, if not, jump to the system homepage;

Iv. process of realization 4.1 Use of the technology

Mybatis

Spring

Springmvc

Jedis 4.2 Creating a project

To create a MAVEN project:

4.3 dependent jar packages

Pom file:

<project xmlns= "http://maven.apache.org/POM/4.0.0" xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance" xsi: schemalocation= "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > < modelversion>4.0.0</modelversion> <parent> <groupId>com.dmsd</groupId> <artifactid >parent</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <groupid>com.dm Sd</groupid> <artifactId>sso</artifactId> <version>0.0.1-SNAPSHOT</version> < packaging>war</packaging> <dependencies> <dependency> <groupid>com.dmsd& Lt;/groupid> <artifactId>dao</artifactId> <version>0.0.1-snapshot</version > </dependency> <!--Spring-to <dependency> <groupid>org.springfra Mework</groupid> <artifactid>spring-context</artifactid> </dependency> <dependency> &LT;GROUPID&GT;ORG.SPRINGF
        Ramework</groupid> <artifactId>spring-beans</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactid>spring-we bmvc</artifactid> </dependency> <dependency> <groupid>org.springframew ork</groupid> <artifactId>spring-jdbc</artifactId> </dependency> <d Ependency> <groupId>org.springframework</groupId> <artifactid>spring-aspects& lt;/artifactid> </dependency> <dependency> &LT;GROUPID&GT;ORG.SPRINGFRAMEWORK&L
        T;/groupid> <artifactId>spring-context-support</artifactId> </dependency>
    <dependency>        <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId> Javax.servlet</groupid> <artifactId>jsp-api</artifactId> &LT;SCOPE&GT;PROVIDED&L T;/scope> </dependency> <!--redis clients--<dependency> <groupi


  D>redis.clients</groupid> <artifactId>jedis</artifactId> </dependency>
                </dependencies> <!--adding tomcat plugins--<build> <plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactid>tomcat7-maven-plug
                    In</artifactid> <configuration> <port>8084</port> <path>/</path> </configuration> </plugin> </plugins> </build> </project>
4.4 Integrating the SSM framework

The integration here can refer to the pre-written SSM integration blog.

4.5 Login Logic Implementation

DAO Layer:

Direct use of the code generated by MyBatis reverse engineering.

Service Layer:

Receive parameters: User name, password.

Verify that the password is correct, generate tokens, write user information to Redis, write tokens to a cookie, and return the Systemresult entity containing tokens.

Parameters: User name, password, httpservletresponse, httpservletrequest
return value: Taotaoresult

@Service public class Loginserviceimpl implements Loginservice {@Autowired private tbusermapper usermapper;

    @Autowired private jedisclient jedisclient;
    @Value ("${redis_session_key}") Private String Redis_session_key;

    @Value ("${session_expire}") Private Integer Session_expire; @Override Public systemresult Login (string username, string password, httpservletrequest request, Httpserv
        Letresponse response) {//Verify user name password is correct tbuserexample example = new Tbuserexample ();
        Criteria = Example.createcriteria ();
        Criteria.andusernameequalto (username);
        list<tbuser> list = Usermapper.selectbyexample (example);
        Fetch user Information if (list = = NULL | | list.isempty ()) {return Taotaoresult.build (400, "Username or password error");
        } tbuser user = List.get (0); Verify the password if (!user.getpassword (). Equals (Digestutils.md5digestashex (Password.getbytes ()))) {return SysTemresult.build (400, "User name or password error");
        }//Login succeeded//Generate token String token = Uuid.randomuuid (). toString ();
        Write user information to REDIS//key:redis_session:{token}//value:user to JSON user.setpassword (NULL);
        Jedisclient.set (Redis_session_key + ":" + token, Jsonutils.objecttojson (user));
        Set the SESSION Expiration Time Jedisclient.expire (Redis_session_key + ":" + token, session_expire);

        Write Cookie Cookieutils.setcookie (request, Response, "Tt_token", TOKEN);
    return Systemresult.ok (token);
 }

}

Controller layer:

Url:/user/login of the request
Receive parameters: Username, password
Call service to return the Taotaoresult object.
Respond to JSON data.

@Controller public
class Logincontroller {

    @Autowired
    private loginservice loginservice;

    @RequestMapping (value= "/user/login", Method=requestmethod.post)
    @ResponseBody public
    systemresult Login ( String Username, string password, 
            httpservletrequest request, httpservletresponse response) {
        try {
            Systemresult result = Loginservice.login (username, password, request, response);
            return result;

        } catch (Exception e) {
            e.printstacktrace ();
            Return Systemresult.build ($, exceptionutil.getstacktrace (e));}}}

4.6 Query user information via token

Note: According to the token to Redis query user information, if the user information does not exist stating that the session has expired, returned 400 and prompted the user session has expired. If the user is queried, the user information is returned, and the user's expiration time is updated.

Request Url:/user/token/{token}

Need to support JSONP

return: Systemresult

DAO Layer:

Access the Redis implementation using Jedis.

Service Layer:

Parameters: String Token
Query Redis based on token, query to result return user object, update expiration time. If the query does not reach the result, the return session has expired, status code 400.
return value: Systemresult

@Override public
    Systemresult Getuserbytoken (String token) {
        //based on token fetch user information
        String JSON = Jedisclient.get (Redis_session_key + ":" + token);
        Determine whether to query the result
        if (Stringutils.isblank (JSON)) {
            return Systemresult.build (400, "user session has expired");
        }
        Convert JSON to Java object
        tbuser user = Jsonutils.jsontopojo (JSON, tbuser.class);
        Update SESSION Expiration Time
        jedisclient.expire (Redis_session_key + ":" + token, session_expire);

        return Systemresult.ok (user);
    

Controller:

The requested Url:/user/token/{token}
The contents of the token are taken from the URL, the service is invoked to fetch the user information, and the Taotaoresult is returned. (JSON data)

@RequestMapping ("/user/token/{token}")
    @ResponseBody public
    Object Getuserbytoken (@PathVariable String Token, String callback) {
        try {
            Taotaoresult result = Loginservice.getuserbytoken (token);
            Support for Jsonp call
            if (Stringutils.isnotblank (callback)) {
                Mappingjacksonvalue mappingjacksonvalue = new Mappingjacksonvalue (result);
                Mappingjacksonvalue.setjsonpfunction (callback);
                return mappingjacksonvalue;
            }
            return result;

        } catch (Exception e) {
            e.printstacktrace ();
            Return Systemresult.build ($, exceptionutil.getstacktrace (e));
        }
    }

Home System login Jump code:

Using the Ajax cross-domain invocation, we first get the cookie stored in the browser, and then use the Ajax Jsonp to invoke the user information across the domain, because the return is Systemresult JSON form, he contains the Err, MSG, data three parts, So to get the user information is to be obtained through data.data.username.

var TT = Taotao = {
    checklogin:function () {
        var _ticket = $.cookie ("Tt_token");
        if (!_ticket) {
            return;
        }
        $.ajax ({
            URL: "http://localhost:8084/user/token/" + _ticket,
            dataType: "Jsonp",
            Type: "GET",
            Success:function (data) {
                if (data.status = =) {
                    var username = data.data.username;
                    var html = username + ", welcome to. <a href=\ "http://www.taotao.com/user/logout.html\" class=\ "link-logout\" >[exit]</a> ";
                    $ ("#loginbar"). HTML (HTML);}}
        );

}} $ (function () {
    ///See if the login is already logged in, if the login information
    tt.checklogin ();
});
v. Summary

This single sign-on is mostly done using Redis. Redis is really a great caching technology. Have done a good job in many ways. In addition, this is the generation of distributed, the login system separately extracted, this idea is very good. Come on.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.