Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

30 minutes to learn how to use Shiro

2025-04-11 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Database >

Share

Shulou(Shulou.com)06/01 Report--

Abstract: the core part of Shiro is SecurityManager, which is responsible for security authentication and authorization. Shiro itself has implemented all the details, and users can use it as a black box. The SecurityUtils object is essentially a factory similar to ApplicationContext in Spring. Subject is a difficult object for beginners to understand. Many people think that it can be equated with User, but it is not. Subject Chinese translation: project, and the correct understanding is just like this. It is an abstract concept of the projects you are currently designing that need to be protected by Shiro. Through the login relationship between token and subject, Shiro ensures the security of the project as a whole.

I. structure

To learn how to use Shiro, you have to start with its architecture, and Shiro is delicately designed as a security framework. The application of Shiro does not rely on any container, it can also be used under JavaSE. But the most commonly used environment is JavaEE. Take user login as an example:

(1) create a token using the user's login information

UsernamePasswordToken token = new UsernamePasswordToken (username, password)

Token can be understood as a user token, and the login process is abstracted as Shiro to verify whether the token has a legitimate identity and related permissions.

(2) perform the landing operation

SecurityUtils.setSecurityManager (securityManager); / / inject SecurityManager

Subject subject = SecurityUtils.getSubject (); / / get Subject singleton object

Subject.login (token); / / log in

The core part of Shiro is SecurityManager, which is responsible for security authentication and authorization. Shiro itself has implemented all the details, and users can use it as a black box. The SecurityUtils object is essentially a factory similar to ApplicationContext in Spring. Subject is a difficult object for beginners to understand. Many people think that it can be equated with User, but it is not. Subject Chinese translation: project, and the correct understanding is just like this. It is an abstract concept of the projects you are currently designing that need to be protected by Shiro. Through the login relationship between token and subject, Shiro ensures the security of the project as a whole.

(3) judge the user

Shiro itself cannot know whether the user holding the token is legal, because no one but the designer of the project will know. Therefore, Realm is one of the few modules in the whole framework that must be implemented by the designer. Of course, Shiro provides a variety of ways to implement. This paper only introduces the most common and most important way of implementation-database query.

(4) two important articles in English

The first obstacle I encountered in the process of learning Shiro is the English name of these two objects: AuthorizationInfo,AuthenticationInfo. There is no doubt about their own eyes, they do look alike, not only look alike, but also have a very similar meaning.

Before explaining them, you must first describe Shiro's definition of secure users: like most operating systems. Users have the two most basic attributes of roles and permissions. For example, my Windows login name is learnhow, its role is administrator, and administrator has all system permissions. In this way, learnhow naturally has all system permissions. So what if other people need to log on to my computer? I can open a guest role. Any unknown user who can't provide the correct user name and password can log in through guest, and the system has very limited access to the guest role.

In the same way, Shiro constrains users in this way. AuthenticationInfo represents the collection of role information of users, and AuthorizationInfo represents the set of permission information of roles. In this way, when the designer sets a control constraint on a certain url path in the project that can only be accessed by a certain role or permission, the Shiro can judge by the above two objects. At this point, people may still be confused. Don't worry, you'll understand if you keep looking back.

Second, realize Realm

How to implement Realm is not only the highlight of this article, but also the painstaking part. Here you will come into contact with several new concepts: caching mechanism, hashing algorithm, encryption algorithm. Since this article will not specifically introduce these concepts, so here just throw a brick to attract jade to talk about a few points, can help you better understand Shiro.

(1) caching mechanism

Ehcache is the caching framework used in many Java projects, and Hibernate is one of them. Its essence is to save the data that can only be stored in memory to the hard disk through the algorithm, and then take it out in turn according to the demand. You can think of Ehcache as a Map object, save the object through put, and retrieve the object through get.

The above is the basic configuration of the ehcache.xml file. TimeToLiveSeconds is the maximum survival time of the cache, and timeToIdleSeconds is the maximum idle time of the cache. Ttl and tti can only take effect when eternal is false. You can inquire more about the meaning of configuration on the Internet.

(2) Hash algorithm and encryption algorithm

Md5 is the hash algorithm that will be used in this article, and the encryption algorithm will not be covered in this article. Hashing and encryption are essentially turning an Object into a meaningless string. The difference is that the hashed object cannot be recovered, which is an one-way process. For example, the encryption of a password usually uses a hashing algorithm, so if a user forgets the password, he can only change it and cannot get the original password. However, the encryption of information is a regular encryption algorithm, and the encrypted information can be decrypted and restored through the secret key.

(3) user registration

Please note that although we have been talking about the security of user login, when it comes to user login, user registration is the first thing. How to ensure that the user registration information is not lost, not to disclose the secret is also the focus of the project design.

Public class PasswordHelper {private RandomNumberGenerator randomNumberGenerator = new SecureRandomNumberGenerator (); private String algorithmName = "md5"; private final int hashIterations = 2; public void encryptPassword (User user) {/ / User object contains the most basic fields Username and Password

User.setSalt (randomNumberGenerator.nextBytes (). ToHex ()); / / replace the user's registered password with an irreversible new password to save the data through the hashing algorithm, using salt in the hashing process

String newPassword = new SimpleHash (algorithmName, user.getPassword ()

ByteSource.Util.bytes (user.getCredentialsSalt ()), hashIterations) .toHex ()

User.setPassword (newPassword)

}

}

If you don't know what salting means to ignore the hashing process, just understand that the password stored in the database is a new string based on the password you filled in at the time of registration. The hashed password replaces the user's registered password, and then saves the User to the database. Leave the rest of the work to UserService.

So this brings a new problem, since the hash algorithm can not be recovered, when the user logs in with the original password, how should we judge? The answer is to hash the user's password with the same algorithm again and compare it with the string stored in the database.

(4) match

CredentialsMatcher is an interface that matches whether the token used by the user to log in matches the user information stored in the database. Of course, it does more than that. This article will introduce an implementation class of this interface: HashedCredentialsMatcher

Public class RetryLimitHashedCredentialsMatcher extends HashedCredentialsMatcher {/ / declares a cache interface, which is part of Shiro cache management, and its implementation can be injected into private Cache passwordRetryCache through an external container

Public RetryLimitHashedCredentialsMatcher (CacheManager cacheManager) {

PasswordRetryCache = cacheManager.getCache ("passwordRetryCache")

} @ Override

Public boolean doCredentialsMatch (AuthenticationToken token, AuthenticationInfo info) {String username = (String) token.getPrincipal (); AtomicInteger retryCount = passwordRetryCache.get (username); if (retryCount = = null) {

RetryCount = new AtomicInteger (0)

PasswordRetryCache.put (username, retryCount)

} / / customize an authentication process: when a user enters a password incorrectly for more than 5 times, the user is prohibited from logging in for a period of time if (retryCount.incrementAndGet () > 5) {throw new ExcessiveAttemptsException ()

}

Boolean match = super.doCredentialsMatch (token, info); if (match) {

PasswordRetryCache.remove (username)

} return match

}

}

As you can see, in this implementation, the designer simply added a judgment that does not allow continuous wrong login. The real matching process is left to its direct parent class to complete. The judgment of continuous login error depends on Ehcache cache. Obviously, match returns true as a match.

(5) obtain the role and permission information of the user

Having said so much before we focus on Realm, if you have understood the whole process of Shiro for user matching and registration encryption, it is easier to really understand the implementation of Realm. We also have to go back to the two very similar objects mentioned above, AuthorizationInfo and AuthenticationInfo. Because Realm is where these two objects are provided.

Public class UserRealm extends AuthorizingRealm {/ / the role information and permission information of the user are saved in the database, and the data private UserService userService = new UserServiceImpl () is obtained through UserService; / * *

* provide user information and return permission information

* / @ Override protected AuthorizationInfo doGetAuthorizationInfo (PrincipalCollection principals) {String username = (String) principals.getPrimaryPrincipal (); SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo (); / / query the current user's roles Set roles = userService.findRoles (username); Set roleNames = new HashSet (); for (Role role: roles) {

RoleNames.add (role.getRole ())

} / / provide the role name to info

AuthorizationInfo.setRoles (roleNames); / / query the current user rights by user name Set permissions = userService.findPermissions (username); Set permissionNames = new HashSet (); for (Permission permission: permissions) {

PermissionNames.add (permission.getPermission ())

} / / provide the permission name to info

AuthorizationInfo.setStringPermissions (permissionNames); return authorizationInfo

} / * *

* provide account information and return authentication information

* / @ Override protected AuthenticationInfo doGetAuthenticationInfo (AuthenticationToken token) throws AuthenticationException {String username = (String) token.getPrincipal (); User user = userService.findByUsername (username); if (user = = null) {/ / the user name does not throw an exception throw new UnknownAccountException ()

} if (user.getLocked () = = 0) {/ / the user is locked by the administrator and throws an exception throw new LockedAccountException ()

} SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo (user.getUsername ()

User.getPassword (), ByteSource.Util.bytes (user.getCredentialsSalt ()), getName (); return authenticationInfo

}

}

According to the design idea of Shiro, the previous relationship between users and roles is many-to-many, and the relationship between roles and permissions is also many-to-many. Therefore, it is necessary to set up five tables in the database, namely, user table (storing user name, password, salt, etc.), role table (role name, related description, etc.), permission table (permission name, related description, etc.), user-role corresponding intermediate table (using user ID and role ID as joint primary key), role-permission corresponding intermediate table (role ID and permission ID as joint primary key). The specific implementation of dao and service is not provided in this article. In short, the conclusion is that Shiro needs to determine whether the logged-in user is legitimate or not based on the user name and password, and then authorize the legitimate user. And this process is the implementation process of Realm.

(6) conversation

Each login of a user is a session, and Shiro can also manage the session instead of containers such as Tomcat. The goal is that when the user stays on a page without action for a long time, access to any link will be redirected to the login page to re-enter the user name and password without requiring the programmer to constantly determine whether the Session contains User objects in Servlet. Another use of enabling Shiro session management is that you can take different session handling for different modules. Take Taobao as an example, users can choose to remember their username and password after registering on Taobao. After a second visit, there is no need to log in. But if you want to visit links such as Alipay or shopping cart, you still need to confirm the identity of the user. Of course, Shiro can also create the most implementation using the Session provided by the container.

Third, integrate with SpringMVC

With the support of the registration module and the Realm module, here is how to integrate development with SpringMVC. Students who have experience in framework integration must know that the so-called integration is basically the configuration of a bunch of xml files, and Shiro is no exception.

(1) configure the front-end filter

Let's start with a digression. Filter is the filter and interceptor is the interceptor. The former is based on callback function and must be supported by container. Because the container is required to assemble the entire FilterChain and call it one by one. The latter is based on proxy implementation and belongs to the category of AOP.

If you want to use Shiro in a WEB environment, you must first configure it in the web.xml file.

Shiro_Project index.jsp SpringMVC org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:springmvc.xml 1 true SpringMVC / org.springframework.web.context.ContextLoaderListener org.springframework.web.util.Log4jConfigListener contextConfigLocation classpath:spring.xml Classpath:spring-shiro-web.xml log4jConfigLoaction classpath:log4j.properties shiroFilter org.springframework.web.filter.DelegatingFilterProxy true targetFilterLifecycle true shiroFilter / *

Students who are familiar with Spring configuration can focus on the section with green words, which is the key to making Shiro effective. Since the project is managed by Spring, all configuration is left to Spring in principle. The function of DelegatingFilterProxy is to notify Spring to hand over all Filter to ShiroFilter management.

Then configure the spring-shiro-web.xml file under the classpath path

/ authc/admin = roles [admin]

/ authc/** = authc

/ * * = anon

It is important to note that the configuration of paths in the filterChainDefinitions filter is ordered, and the container will not continue to look for it when a matching entry is found. Therefore, the path with wildcards should be placed at the back. The meaning of the three configurations is: / authc/admin requires user useful admin permissions, / authc/** user must log in to access, and / * all other paths can be accessed by anyone.

Having said that, you must be concerned about how to write the login code after introducing Shiro into Spring.

@ Controller

Public class LoginController {@ Autowired

Private UserService userService; @ RequestMapping ("login")

Public ModelAndView login (@ RequestParam ("username") String username, @ RequestParam ("password") String password) {

UsernamePasswordToken token = new UsernamePasswordToken (username, password)

Subject subject = SecurityUtils.getSubject (); try {

Subject.login (token)

} catch (IncorrectCredentialsException ice) {/ / capture password error exception

ModelAndView mv = new ModelAndView ("error")

Mv.addObject ("message", "password error!")

Return mv

} catch (UnknownAccountException uae) {/ / catch unknown username exception

ModelAndView mv = new ModelAndView ("error")

Mv.addObject ("message", "username error!")

Return mv

} catch (ExcessiveAttemptsException eae) {/ / catch too many exceptions with incorrect login

ModelAndView mv = new ModelAndView ("error")

Mv.addObject ("message", "times error")

Return mv

}

User user = userService.findByUsername (username)

Subject.getSession () .setAttribute (user, user)

Return new ModelAndView ("success")

}

}

After the login is complete, the current user information is saved in Session. This Session is a session object managed by Shiro, and it must still be obtained through Shiro. There is no User object in traditional Session.

@ Controller@RequestMapping ("authc")

Public class AuthcController {/ authc/** = authc any user who logs in through the form can access @ RequestMapping ("anyuser")

Public ModelAndView anyuser () {

Subject subject = SecurityUtils.getSubject ()

User user = (User) subject.getSession () .getAttribute ("user")

System.out.println (user)

Return new ModelAndView ("inner")

} / authc/admin = user [admin] only users with the admin role can access it, otherwise the request will be redirected to the login interface @ RequestMapping ("admin")

Public ModelAndView admin () {

Subject subject = SecurityUtils.getSubject ()

User user = (User) subject.getSession () .getAttribute ("user")

System.out.println (user)

Return new ModelAndView ("inner")

}

}

Friends who are willing to understand the framework technology or source code directly ask (Penguin): 2042849237 you are welcome to learn and study related technologies.

For more details, source code reference: http:// × × / technology

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Database

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report