1. Architecture
Hiro is a powerful, easy-to-use Java security framework that is used primarily for more convenient authentication, authorization, encryption, and session management. Shiro's primary and most important goals are easy to use and easy to understand.
Shiro is a comprehensive security framework with many features, and the following diagram can be used to understand the characteristics of Shiro:
It can be seen that Shiro has many additional features in addition to basic authentication, authorization, session management, and encryption.
From a large point of view, Shiro has three main concepts:,, the Subject
SecurityManager
Realms
following picture can see the interaction between these originals.
Subject : The subject, represents the current "user", the user is not necessarily a specific person, and the current application of any thing is subject, such as web crawler, robot, is an abstract concept; All subject are bound to SecurityManager, All interactions with subject will be delegated to SecurityManager; subject can be regarded as a façade; SecurityManager is the actual performer;
SecurityManager : security Manager, that is, all security-related operations interact with SecurityManager, and it manages all subject, and it is the core of Shiro, and it is responsible for interacting with the other components described behind, if you have learned SPRINGMVC , you can think of it as the Dispatcherservlet front controller;
Realm : domain, Shiro from the realm to obtain security data (such as users, roles, permissions), that is, SecurityManager to verify the user identity, then it needs to get the appropriate user from the realm to compare to determine whether the user identity is legitimate It also requires the user's corresponding roles/privileges from realm to verify that the user is able to operate, and that realm can be viewed as a DataSource, a secure data source.
2. Noun Explanation:
Authentication : identity Authentication/login, verify that the user has the corresponding identity;
Authorization : authorization, which is authentication of permissions, verifies that a authenticated user has a permission, that is, whether a user can do something, as usual: Verifying that a user has a role. or fine-grained verification that a user has a certain permission on a resource;
Session Manager : session management, that is, after the user logs on is a session, before exiting, all its information is in the session, the session can be normal javase environment, or it can be a web environment;
Cryptography : encryption, protection of data security, such as password encryption stored in the database, rather than plaintext storage;
Web Support : Web support, can be very easy to integrate into the web environment;
Caching: Cache, such as user login, its user information, the role/permissions do not need to check every time, this can improve efficiency;
Concurrency :Shiro supports concurrent authentication for multi-threaded applications, such as opening another thread in one thread to automatically propagate the past;
Testing : provide testing support;
Run as : allows one user to pretend to access the identity of another user (if they allow it);
Remember Me : Remember me, this is a very common feature, that is, once logged in, the next time you come back without logging in.
Remember one thing, Shiro. do not maintain the user, maintenance rights, these need we to design/ and then injected to the Shiro via the appropriate interface . can be.
3. Main code
public class Shirodbrealm extends Authorizingrealm {private static final Logger Logger = Logmanager.getlogger (SHIRODBR Ealm.class); @Autowired private UserService UserService; @Autowired private Iroleservice RoleService; Public Shirodbrealm (CacheManager CacheManager, Credentialsmatcher matcher) {super (CacheManager, Matcher); }/** * Shiro login Authentication * User Login * * * @Override protected AuthenticationInfo dogetauthenticationinfo (Aut Henticationtoken Authctoken) throws Authenticationexception {Logger.info ("Shiro Start login Authentication"); Usernamepasswordtoken token = (usernamepasswordtoken) Authctoken; Uservo user = Userservice.querybyloginname (token.getusername ()); The account does not exist if (user = = null) {return null; }//Account not enabled if (user.getstatus () = = 1) {return null; }//Read the user's URL and role map<string, set<string>> resourcemap = Roleservice.selectresourcemapbyuserId (User.getid ()); set<string> urls = resourcemap.get ("URLs"); set<string> roles = Resourcemap.get ("roles"); Shirouser shirouser = new Shirouser (User.getid (), User.getloginname (), User.getname (), URLs); Shirouser.setroles (roles); Authentication cache information return new Simpleauthenticationinfo (Shirouser, User.getpassword (). ToCharArray (), GetName ()); }/** * Shiro Authority Authentication */@Override protected authorizationinfo dogetauthorizationinfo (principalcollection pri ncipals) {Shirouser Shirouser = (shirouser) principals.getprimaryprincipal (); Simpleauthorizationinfo info = new Simpleauthorizationinfo (); Info.setroles (Shirouser.getroles ()); Info.addstringpermissions (Shirouser.geturlset ()); return info; } @Override public void Onlogout (PrincipalCollection principals) {super.clearcachedauthorizationinfo (pri Ncipals); Shirouser Shirouser = (shirouser) principals.getprimaryPrincipal (); Removeusercache (Shirouser); }/** * Clear user Cache * @param shirouser */public void Removeusercache (Shirouser shirouser) {Removeuser Cache (Shirouser.getloginname ()); }/** * Clear user Cache * @param loginName */public void Removeusercache (String loginName) {Simpleprincip alcollection principals = new Simpleprincipalcollection (); Principals.add (LoginName, Super.getname ()); Super.clearcachedauthenticationinfo (principals); }}
The
Login code is:
@PostMapping ("/login") @ResponseBody public Object loginpost (string loginName, String password) throws IOException { if (Stringutils.isblank (loginName)) {throw new RuntimeException ("User name cannot be null"); } if (Stringutils.isblank (password)) {throw new RuntimeException ("Password cannot be null"); } Subject user = Securityutils.getsubject (); Usernamepasswordtoken token = new Usernamepasswordtoken (loginName, password); try {logger.info ("Start login"); User.login (token); Return Rendersuccess ("landing success"); } catch (Unknownaccountexception e) {throw new RuntimeException ("account does not exist!) ", e); } catch (Disabledaccountexception e) {throw new RuntimeException ("Account not enabled! ", e); } catch (Incorrectcredentialsexception e) {throw new runtimeexception ("Bad password! ", e); } catch (Throwable e) {throw new RuntimeException (E.getmessage (), E); } }
4. Execution process
The user submits the user name and password----Shiro the token--and the realm passes the username password query back--Shiro automatically compares the query out password and user input password consistency--and login control.
Calling User.login (token) in the login method triggers protected AuthenticationInfo dogetauthenticationinfo (Authenticationtoken Authctoken) method execution.
When you use Securityutils.getsubject (). ispermitted ("/public/getdatalist") in your code, protected Authorizationinfo is triggered Dogetauthorizationinfo (PrincipalCollection principals)
Method for authentication of permissions.
Java uses Shiro small note