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

How to integrate Shiro into SpringBoot to realize privilege Control

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)05/31 Report--

This article mainly introduces "how SpringBoot integrates Shiro to achieve access control". In daily operation, I believe many people have doubts about how to integrate SpringBoot with Shiro to achieve access control. Xiaobian consulted all kinds of materials and sorted out simple and easy-to-use methods of operation. I hope it will be helpful to answer the doubts of "how to integrate Shiro to achieve access control". Next, please follow the editor to study!

1. SpringBoot integrates Shiro

Apache Shiro is a powerful and easy-to-use Java security framework that performs authentication, authorization, password, and session management.

1.1introduction to shiro

Shiro has a core component, which is Subject, SecurityManager and Realms

Subject: equivalent to the "user" of the current operation, this user is not necessarily a concrete person, but an abstract concept that indicates anything that interacts with the current program, such as crawlers, scripts, and so on. All Subject is bound to SecurityManager, and all interactions with Subject are delegated to SecurityManager; to think of Subject as a facade; SecurityManager is the actual executor.

SecurityManager: this is the core of the shiro framework, with which all security-related operations interact, and it manages all Subject.

Realms: acts as a "bridge" between Shiro and application security data. When performing authentication (login) and authorization (access control) verification for users, SecurityManager needs to compare the corresponding users from Realm to determine whether the user's identity is legitimate; it also needs to get the corresponding roles / permissions from Realm to verify whether the user can operate.

1.2, the specific implementation of the code

1.2.1. Configuration of Maven

Org.apache.shiro shiro-spring-boot-starter 1.7.1 com.github.theborakompanioni thymeleaf-extras-shiro 2.0.0 org.apache.shiro shiro-ehcache 1.7.1

Shiro is used with jsp by default, and here is shiro Integration thymeleaf all the jar packages to be imported into shiro Integration thymeleaf

1.2.2. Integrate classes that need to be implemented

Generally speaking, integration only needs to complete the implementation of two classes.

One is ShiroConfig and the other is CustomerRealm.

If you need to add the shiro cache and not the native cache but the redis cache, you need to write two other classes

One is RedisCache and the other is RedisCacheManager.

1.2.3, project structure

1.2.4. Implementation of ShiroConfig

Cache without shiro

Package com.yuwen.config;import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;import com.yuwen.shiro.cache.RedisCacheManager;import com.yuwen.shiro.realm.CustomerRealm;import org.apache.shiro.authc.credential.HashedCredentialsMatcher;import org.apache.shiro.realm.Realm;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;import org.apache.shiro.web.mgt.DefaultWebSecurityManager;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration Import java.util.HashMap;import java.util.Map;@Configurationpublic class ShiroConfig {/ / make the page shiro tag effective @ Bean public ShiroDialect shiroDialect () {return new ShiroDialect ();} / 1. Create shiroFilter to intercept all requests @ Bean public ShiroFilterFactoryBean shiroFilterFactoryBean (DefaultWebSecurityManager defaultWebSecurityManager) {ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean (); / / set security management factoryBean.setSecurityManager (defaultWebSecurityManager) to filter / / configure restricted resources of the system / / configure settings anon Map map = new HashMap (); map.put ("/ main", "authc"); / / request this resource requires authentication and authorization authc indicates that authentication is required before you can access map.put ("/ admin", "roles [admin]") / indicates that the admin role can access roles [] indicates which role is required to access map.put ("/ manage", "perms [user:*:*]"); / / indicates that user:*:* permission is required to access perms [] indicates what permission is required to access / / access the page that requires authentication. If you are not logged in, you will jump to / login route to log in to factoryBean.setLoginUrl ("/ login"). / / access the unauthorized page will automatically jump to / unAuth routing factoryBean.setUnauthorizedUrl ("/ unAuth"); factoryBean.setFilterChainDefinitionMap (map); return factoryBean;} / / 2, create the security manager @ Bean public DefaultWebSecurityManager defaultWebSecurityManager (@ Qualifier ("getRealm") Realm realm) {DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager (); / / set securityManager.setRealm (realm) to the security manager Return securityManager;} / / 3. Create a custom realm @ Bean public Realm getRealm () {CustomerRealm customerRealm = new CustomerRealm (); / modify the credential verification matcher HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher (); / / set the encryption algorithm to md5 credentialsMatcher.setHashAlgorithmName ("MD5"); / / set the number of hashes credentialsMatcher.setHashIterations (1024) CustomerRealm.setCredentialsMatcher (credentialsMatcher); return customerRealm;}}

Because it is not safe to set a plaintext password in the database, so I encrypt the password here with md5. My encryption method is: password = password + salt + hash times and then MD5 encryption, so you need to set the match when you create a custom realm so that the password can match when you log in.

1.2.5. Implementation of CustomerRealm

Package com.yuwen.shiro.realm;import com.yuwen.pojo.User;import com.yuwen.pojo.vo.ViewPerms;import com.yuwen.pojo.vo.ViewRole;import com.yuwen.service.UserService;import com.yuwen.shiro.salt.MyByteSource;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo Import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import org.apache.shiro.util.CollectionUtils;import org.springframework.util.ObjectUtils;import javax.annotation.Resource;import java.util.List;// Custom realmpublic class CustomerRealm extends AuthorizingRealm {@ Resource private UserService userService; / / Authorization @ Override protected AuthorizationInfo doGetAuthorizationInfo (PrincipalCollection principalCollection) {/ / get identity Information String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal () / / get role and permission information based on primary identity information List roles = userService.findRolesByUsername (primaryPrincipal); if (! CollectionUtils.isEmpty (roles)) {SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo (); roles.forEach (viewRole-> {simpleAuthorizationInfo.addRole (viewRole.getName () / / permission information List perms = userService.findPermsByRoleId (viewRole.getName ()); if (! CollectionUtils.isEmpty (perms)) {perms.forEach (viewPerms-> {simpleAuthorizationInfo.addStringPermission (viewPerms.getPName ());});}}) Return simpleAuthorizationInfo;} return null;} / / Authentication @ Override protected AuthenticationInfo doGetAuthenticationInfo (AuthenticationToken authenticationToken) throws AuthenticationException {/ / get login identity information String principal = (String) authenticationToken.getPrincipal (); User user = userService.findByUsername (principal) If (! ObjectUtils.isEmpty (user)) {/ / ByteSource.Util.bytes (user.getSalt ()) passes salt through this tool / / if authentication is successful, an AuthenticationInfo implementation is returned Return new SimpleAuthenticationInfo (user.getUsername (), user.getPassword (), new MyByteSource (user.getSalt ()), this.getName ());} return null;}}

This authentication is automatically invoked when logging in. If there is an error during authentication, an exception will be reported. I received the exception in the controller layer and handled it.

Exception handling during login in controller layer

@ PostMapping ("/ login") public String login (String username,String password) {/ / get the principal object Subject subject = SecurityUtils.getSubject (); try {/ / automatically calls the authentication method subject.login (new UsernamePasswordToken (username,password)) in the CustomerRealm class; return "index" } catch (UnknownAccountException e) {/ / receives exceptions and handles e.printStackTrace (); model.addAttribute ("msg", "user name error, please log in again");} catch (IncorrectCredentialsException e) {/ / receives exceptions and handles e.printStackTrace (); model.addAttribute ("msg", "password error, please log in again") } return "login";}

1.2.6, shiro cache configuration

The shiro cache is defined. After a user logs in, his or her user information and roles / permissions do not have to be checked every time, which can improve efficiency.

Configuration of the default cache

Turn on cache management in the getRealm () method in ShiroConfig

@ Bean public Realm getRealm () {CustomerRealm customerRealm = new CustomerRealm (); / / enable cache management customerRealm.setCacheManager (new EhCacheManager ()); / / enable global cache customerRealm.setCachingEnabled (true); / / enable authentication cache customerRealm.setAuthenticationCachingEnabled (true); customerRealm.setAuthenticationCacheName ("authenticationCache"); / / enable permission cache customerRealm.setAuthorizationCachingEnabled (true) CustomerRealm.setAuthorizationCacheName ("authorizationCache"); return customerRealm;}

The cache integrated with reids is not explained here. Put it in the source code and check it for yourself. The source code is below.

1.2.7, the setting of the home page index.html

Tags are used here to determine what authentication or roles or permissions are required for certain areas to access.

Home page index exits main | manage | admin user: display authentication passed content display admin role display with user module "user:*:*" permission display 1.3, simple test

1.3.1, admin role all permissions test

1.3.2. Test with permissions without roles

1.3.3. No role and no permission test

At this point, the study on "how SpringBoot integrates Shiro to achieve access control" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

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

Internet Technology

Wechat

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

12
Report