Shiro implement app, Web unified login authentication and Rights Management

Source: Internet
Author: User
Tags setcookie server memory

In the background, the project consists of a management system (web) and a portal (web), a mobile app (including Android and iOS), three systems sharing a backend, and the backend using Shiro for login authentication and permission control. Okay, so the question is. Can the web and app be Shiro certified? What is the difference between the two? If yes, what is the solution? Looking at everyone's anxious little eyes, the next one to solve the above problems.

Can the Web and app be certified with Shiro Unified login?

OK. If both the Web and the app are logged in with a password, that's not necessarily the case, because for Shiro (this will not introduce Shiro details, only the necessary for this article), no matter who is logged in, with what login (user name password, verification code), as long as through Subject.login Tokens in tokens tell Shiro and then give their own authentication fields within their defined realm, okay, foggy, look at the code.

// write in the rest of your login, such as the login method inside the userrest, the user is the parameter passed over Subject currentUser =new//  start to enter Shiro certification process Currentuser.login (token);

The above code is to start using Shiro authentication, call Subject.login (token) to Shiro certification, and then we are related to the custom authentication realm, such as custom Userrealm

protectedAuthenticationInfo dogetauthenticationinfo (Authenticationtoken authctoken)throwsauthenticationexception {//to obtain a token based on a user name and password//In fact, this token was sent from Userresource face Currentuser.login (token).//all two tokens are quoted in the same way.Usernamepasswordtoken token =(Usernamepasswordtoken) Authctoken; System.out.println ("Validate current subject when getting token to" +reflectiontostringbuilder.tostring (token, tostringstyle.multi_line_style)); //gets the user name corresponding to the username from the database.User User =Userservice.getbyphonenum (Token.getusername ()); if(NULL!=user) {AuthenticationInfo Authcinfo=NewSimpleauthenticationinfo (User.getphonenum (), User.getpassword (), GetName ()); returnAuthcinfo; }Else{              return NULL; }    }  

and a picture.

The diagram depicts a complete login process using Shiro

So the above code shows that currently we have not found the app and Web login D difference, then what is the difference?

The difference between Web and app login certifications

Well, the title is not very accurate, should be logged in and after the login session to keep the difference between the web and the app, first say login:

Login

The app and PC Web require different devices to a large extent determine the difference between the two, the web is generally viewed on the PC, login with the user name and password, if the use of remember password is a cookie authentication, Web login has the following conditions

    • Login for the first time, login with username and password
    • Close the browser, the session expires, re-login with the password (if you have the Remember password function, you can use a cookie login)
    • User Delete cookie or cookie expires, login with username and password

App on mobile device view, the first time you log in with the user name and password, but later if not the user actively quit, should remain logged in, so that there will be a better user experience, but it is not possible to keep the app's session, it is not possible to save the password locally, so the app should be the following process

    • Login for the first time, use user name password
    • After the user opens the application, the user does not need to enter the password system to automatically log in
    • Login with user name and password after user active exit (reload, etc. as active exit)

Seemingly did not see what difference, the only difference is the 2nd: How to log in without a password, the Web is using cookies (automatically maintained by the browser), how to log the app? Because the app does not save the password locally, then also refer to the web, using something like cookies, we call him token bar, the problem solved, the app to save tokens, for security, regular update token, then to see the session to maintain.

Session (hold State)

If the user logged in, how to stay logged on, the web has a cookie and session to solve the problem, the following is a brief look at my understanding of these two things, because the app session is reference to this principle design.

Cookie: is maintained by the browser, each request browser will put the cookie in the header (if any), it can also be seen as JS can access the local storage data location One (the other is storage)

Session: Because HTTP is stateless, but sometimes the server needs to save the requested data for the next request to use, that is, the need to maintain the status of continuous requests, this time the server with the help of cookies, when the browser sends a request to the server, the server generates a unique value , write to the cookie to return to the browser, and generate a Session object, so that the session and cookie value has a one by one correspondence, browsing the next visit will take this cookie value, this time the server will get the value of the cookie, Then find out if there is a session associated with the cookie in your own cache.

Because of the combination of cookies and sessions, Shiro can natively support Web login and session retention, and for the app it can also learn about cookies and session implementations, the only problem being that Web cookies are maintained by the browser, Automatically put the cookie in the header, that our app as long as the server returned by the cookie in the header, every time you visit the server with it.

Password-Free Login

Resolves a login and session retention issue, with a password-free login:

Web: Because the general web page owners need to remember the 7-day password (or a little longer) function, can be implemented using cookies, and Shiro also provides the ability to remember the password, the server-side session does not need to save too long

App: Because the app password login time needs to be longer (when the user does not actively quit, should remain logged in the state), so that the server side to the session to save a long time, to the server memory and performance of a large challenge, the contradiction is: The app takes a long time password-free login , and the server can not save the session for a long time, the workaround:

    • The first time the app logs in, uses the username and password, if the login is successful, the cookie is stored locally (such as sharepreference), and the cookie value is saved to the user table in the background.
    • The app accesses the server, the app adds the cookie inside the Heade, the server session still exists, can be accessed normally
    • The app accesses the server, the app adds the cookie inside the Heade, the server session expires, the access fails, the app automatically takes the cookie stored locally to the server to log in, and the server can log in based on the cookie and user name, The server then has a session, which will generate a new cookie to return to the App,app to update the local cookie, and can be accessed normally
    • Users manually quit the app, delete the app stored in the cookie, the next login with a user name and password login

There are problems with this approach:

    1. Cookies are stored locally in the app, are less secure, and can increase security by encrypting cookies
    2. Each time the server session expires, the app will have to re-initiate the login request (although the user is not aware of it), but this in itself increases the number of visits, but the request is not very large, but this way makes the cookie frequently updated, but increased security

Here's another way to achieve this:

To achieve their own Sessiondao, the session is saved in the database, so the advantage is that the session will not be piled up in memory, there is no need to consider the session expiration time, for the application of this need long-term preservation session situation, You can save the session indefinitely, without having to resend the login request after each session expires. Here's how it's implemented:

To save the session to the database using Hibernate, create a new simplesessionentity

 Packageorg.lack.entity;Importjava.io.Serializable;Importorg.apache.shiro.session.mgt.SimpleSession;ImportCom.phy.em.user.entity.User; Public classsimplesessionentity {PrivateLong ID; PrivateA String cookie; PrivateSerializable session;  PublicLong getId () {returnID; }     Public voidsetId (Long id) { This. ID =ID; }     PublicSerializable Entity () {returnsession; }     Public voidSetsession (Serializable session) { This. session =session; }     PublicString GetCookie () {returncookies; }     Public voidSetcookie (String cookie) { This. cookie =cookies; }     PublicSerializable getsession () {returnsession; }}
 <?xml version= "1.0" encoding= "Utf-8"? ><! DOCTYPE hibernate-mapping Public "-//hibernate/hibernate mapping DTD 3.0//en" "http://hibernate.sourceforge.net/ Hibernate-mapping-3.0.dtd ">package  =" Org.lack.entity "> <class  name=" simplesessionentity "table=" Session " > <!--identification--<id name= "id" > <column name= "id" ></column> &L                T;generator class  = "Increment" ></generator> </id>                <property name= "Session" > <column name= "session" ></column> </property> <property name= "Cookies" > <column name= "cookies" ></column> </property> & Lt;/class  >

The above is affixed to the simplesessionentity mapping file, especially to note that Hibernate is also supported to save the object in the database, but the entity to implement serializable, when taken out of the strong to the corresponding object can be, So the type of session here is serializable

Create a new session cache class, here inherit from Enterprisecachesessiondao, you can use Ehcache as a level two cache, you must remember to implement save, update, Readsession, delete method, In particular, the Save method simply saves a basic session, and the important attribute are update, which is read from the database in the readsession.

 PackageOrg.lack.daoImportjava.io.Serializable;Importjava.util.Date;ImportOrg.apache.log4j.Logger;Importorg.apache.shiro.session.Session;Importorg.apache.shiro.session.UnknownSessionException;Importorg.apache.shiro.session.mgt.SimpleSession;ImportOrg.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;Importorg.springframework.transaction.annotation.Transactional;ImportCom.phy.em.common.dao.IBaseDao;Importcom.phy.em.common.shiro.entity.SimpleSessionEntity;ImportCom.phy.em.user.entity.User; Public classSessionentitydaoextendsEnterprisecachesessiondao {PrivateIbasedao<user>Basedao; PrivateIbasedao<simplesessionentity>Sessiondao; PrivateLogger log = Logger.getlogger (Sessionentitydao.class); @Override PublicSerializable Create (Session session) {//save to cache firstSerializable cookie =Super. Create (session); //Create a new simplesessionentity, and then save to the databasesimplesessionentity entity =Newsimplesessionentity ();        Entity.setsession ((simplesession) session);        Entity.setcookie (Cookie.tostring ());                Sessiondao.save (entity); returncookies; } @Override Public voidUpdate (Session session)throwsunknownsessionexception {Super. Update (session); Simplesessionentity Entity=getentity (Session.getid ()); if(Entity! =NULL) {entity.setsession ((simplesession) session);        Sessiondao.update (entity); }} @Override PublicSession readsession (Serializable sessionId)throwsUnknownsessionexception {Session session=NULL; Try{Session=Super. Readsession (SESSIONID); } Catch(Exception e) {}//if the session has been deleted, query the session from the database        if(Session = =NULL) {simplesessionentity entity=getentity (Session.getid ()); if(Entity! =NULL) {Session=(Session) entity.getsession (); }                    } Else{            //if the session is not deleted, determine if the session expires            if(Isexpire (session)) {//Session ExpiresUser User =GetUser (sessionId); if(User! =NULL){                    //If the user is an app user (a user is not an empty description), determine if the session expires, and if it expires, modify the last access time((simplesession) session). Setlastaccesstime (NewDate ()); }            }        }        returnsession; } @Override Public voidDelete (Session session) {Super. Delete (session); }        PrivateUser GetUser (Serializable sessionId) {String hql= "From user user where User.cookie = '" + sessionId + "'"; returnbasedao.finduniquebyhql (HQL); }        Privatesimplesessionentity getentity (Serializable sessionId) {String hql= "from simplesessionentity entity where Entity.cookie = '" + sessionId + "'"; returnsessiondao.finduniquebyhql (HQL); }        Private BooleanIsexpire (Session session) {LongTimeout =session.gettimeout (); LongLasttime =session.getlastaccesstime (). GetTime (); LongCurrent =NewDate (). GetTime (); if((Lasttime + timeout) >Current ) {            return false; }        return true; }     Public voidSetbasedao (ibasedao<user>Basedao) {         This. Basedao =Basedao; }     Public voidSetsessiondao (ibasedao<simplesessionentity>Sessiondao) {         This. Sessiondao =Sessiondao; }    }

My card UI was stupid cry, in succession Enterprisecachesessiondao only realized readsession, delusional oneself new simplesession to return to Shiro use, tried many times after not, After debugging a lot of Shiro far, found in simplesession Shiro not only set the basic properties, more importantly, set up the attribute, but my own new simplesession No, so certification is a failure, So please be sure to remember to implement the Save and update methods.

Although took a lot of detours, but with the Shiro source debugging learning, to Shiro understand deeper, no longer just stay in the point that will only use, there is depth.

OK, so far, the text is finished, we begin to solve the problem is finished, write down to break the app login process encountered problems and some of their own experience.

About system security

Consider a number of security considerations when considering app logins

    • Encrypt the password when the user logs in with a user name and password
    • Session Hold if cookies are used, they can be authenticated after they have been intercepted by others.
    • It is certainly inappropriate to save the password locally, if you save the cookie (token), the phone is rooted, it is easy to see, such as Android is just an XML file, so the cookie is saved to encrypt, after encryption improves the crack threshold, Encryption involves the secret key problem, if the secret key is written in the code, Java is anti-compiled after the secret key can be found, of course, Google has already started to support the NDK (ie, Android native development, this native refers to the use of C + + development, compiled into so file, Call in Java), so that the more difficult to crack, using hybrid, not to mention, directly unzip the installation package can be seen.
    • If the cookie is stored locally, what is the time (frequency) of the update, so that the cookie is compromised and is only useful for a certain period of time (of course, "This time" is enough for a "conscientious" person to do something)

In considering these issues, I realized:

    • Security is only relative (attack and defense is a strong I am stronger, there is attack, the defense will be enhanced, the defense is enhanced, the attack to be more successful to be stronger)
    • Security is not technically safer the better, to consider the actual application, the cost of input (often not the technology can not be achieved, but to consider the actual situation, including the cost, the importance of information, etc., this is a kind of engineering thinking)

Shiro implement app, Web unified login authentication and Rights Management

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.