Hello, in this chapter we add Shiro permission protection interface function. If you have any questions, please contact me at [email protected]. Ask for directions of various gods, thank you

One: What is Shiro

Shiro is an open source authorization framework for the Java platform for authentication and access authorization. Specifically, the following elements are supported:

  • Users, roles, permissions (only operational permissions, data permissions must be closely aligned with business requirements), resources (urls).
  • Users assign roles and define permissions for roles.
  • Roles or permissions are supported during access authorization, and multi-level permission definitions are supported.

Simply put, Shiro uses its own configuration to ensure that the interface can only be accessed by specified roles or permissions, ensuring the security of the interface.

Two: Add Shiro dependencies

<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-web-starter</artifactId> < version > 1.4.0 - RC2 < / version > < / dependency >Copy the code

Create database tables such as permission, role, and user role permission relation table

1: Modify the original userInfo table

Add password (encrypted user password),salt (encrypted salt value)

After modification, the structure is shown in the following figure



The password data is generated after 123456 is encrypted

2: Add the role table

CREATE TABLE `sys_role` (
  `id` varchar(36) NOT NULL COMMENT 'Role Name',
  `role_name` varchar(255) DEFAULT NULL COMMENT 'Role name for display',
  `role_desc` varchar(255) DEFAULT NULL COMMENT 'Character Description',
  `role_value` varchar(255) DEFAULT NULL COMMENT 'Role value for permission determination',
  `create_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  `is_disable` int(1) DEFAULT NULL COMMENT 'Disabled or not',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Role table';Copy the code

3: Add the user role relationship table

CREATE TABLE `user_role` (
  `id` varchar(36) NOT NULL,
  `user_id` varchar(36) DEFAULT NULL COMMENT 'user ID',
  `role_id` varchar(36) DEFAULT NULL COMMENT 'character id',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='User Role Relationship Table';
Copy the code

4: Add a permission table

CREATE TABLE `sys_perm` (
  `id` varchar(36) NOT NULL,
  `perm_name` varchar(255) DEFAULT NULL COMMENT 'Permission Name',
  `perm_desc` varchar(255) DEFAULT NULL COMMENT 'Permission Description',
  `perm_value` varchar(255) DEFAULT NULL COMMENT 'Permission value',
  `create_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  `is_disable` int(1) DEFAULT NULL COMMENT 'Disabled or not',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;Copy the code

5: Add the role permission table

CREATE TABLE `role_perm` (
  `id` varchar(36) NOT NULL,
  `perm_id` varchar(32) DEFAULT NULL COMMENT 'authorization id',
  `role_id` varchar(32) DEFAULT NULL COMMENT 'character id',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Role Permission Table';Copy the code

The following figure shows the table relationship. One user corresponds to multiple roles, and one role pair has multiple rights

Forgive me for the spicy chicken drawing



Four: use the code generator to generate four new tables of mapper, DAO, Service and Controller

We can directly generate, because the code is too much, here do not show, details can go to the code cloud reference

Five: Add methods for querying roles and permissions

UserRoleMapper.xml

<! --> <select id="getRolesByUserId" resultType="string" parameterType="string">
  select sr.role_value
  from user_role ur
  left join sys_role sr on ur.role_id = sr.id
  where ur.user_id = #{userId,jdbcType=VARCHAR}
  and sr.is_disable = 0
</select>Copy the code

UserRoleMapper.java

List<String> getRolesByUserId(String userId);Copy the code

RolePermMapper.xml

<select id="getPermsByUserId" resultType="string" parameterType="string">
  select distinct
      p.perm_value
  from
      sys_perm p,
      role_perm rp,
      user_role ur
  where
      p.id = rp.perm_id
      and ur.role_id = rp.role_id
      and ur.user_id = #{userId,jdbcType=VARCHAR}
      and p.is_disable = 0
</select>Copy the code

All permissions of the user are queried. Because roles and permissions are many-to-many, the permissions of the users may be duplicated and distinct must be deleted.

RolePermMapper.java

List<String> getPermsByUserId(String userId);Copy the code

Change the userInfo entity class to the following

package com.example.demo.model; import javax.persistence.Column; import javax.persistence.Id; import javax.persistence.Transient; import java.util.HashSet; import java.util.Set; /** * @author @description: * @time 2018/4/18 11:55 */ public class UserInfo {/** * private String Id; /** * user name */ @column (name ="user_name") private String userName; private String password; /** * private String salt; /** * Transient private Set<String> roles; /** * Transient private Set<String> perms; public StringgetId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Set<String> getRoles() {
        return roles;
    }

    public void setRoles(Set<String> roles) {
        this.roles = roles;
    }

    public Set<String> getPerms() {
        return perms;
    }

    public void setPerms(Set<String> perms) {
        this.perms = perms;
    }

    public String getSalt() {
        return salt;
    }

    public void setSalt(String salt) { this.salt = salt; }}Copy the code

Customize the Realm

To create the core – shiro – CustomRealm. Java

1: realizes login authentication

In Shiro, user, role, and permission information in your application is ultimately obtained through Realm. Normally, Shiro’s authentication information is fetched directly from our data source in Realm. A Realm is a DAO dedicated to the security framework. Shiro’s authentication process is eventually committed to a Realm by calling its getAuthenticationInfo(Token) method.

This method performs the following operations:

  • Check the submitted token information for authentication
  • Get user information from a data source (usually a database) based on the token information
  • Verify user information to match.
  • The authentication pass will return an encapsulation of the user’s informationAuthenticationInfoInstance.
  • Thrown if validation failsAuthenticationExceptionException information.

In our application, we need to define a Realm class, inherit the AuthorizingRealm abstract class, override doGetAuthenticationInfo(), and override the method that gets the user information.

2: implementation of link permissions

Override doGetAuthorizationInfo() to define how to obtain the user’s roles and permissions for Shiro to determine permissions

The complete code is as follows

package com.example.demo.core.shiro; import com.example.demo.model.UserInfo; import com.example.demo.service.RolePermService; import com.example.demo.service.UserInfoService; import com.example.demo.service.UserRoleService; import org.apache.shiro.authc.*; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.authz.AuthorizationException; 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.ByteSource; import org.springframework.beans.factory.annotation.Autowired; import java.util.HashSet; import java.util.List; import java.util.Set; /** * Customize how to query user information, and how to query user roles and permissions. */ Public class CustomRealm extends AuthorizingRealm {@autoWired private UserInfoService userService; @Autowired private UserRoleService userRoleService; @Autowired private RolePermService rolePermService; /** * tell Shiro how to verify the password against the password and salt value in the obtained user information */ {// set the CredentialsMatcher HashedCredentialsMatcher used to match the passwordhashMatcher = new HashedCredentialsMatcher();
        hashMatcher.setHashAlgorithmName("md5");
        hashMatcher.setStoredCredentialsHexEncoded(true); // The number of times to encrypthashMatcher.setHashIterations(1024);
        this.setCredentialsMatcher(hashMatcher); */ Override protected AuthorizationInfo;} / Override protected AuthorizationInfodoGetAuthorizationInfo(PrincipalCollection principals) {
        if (principals == null) {
            throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
        }
        UserInfo user = (UserInfo) getAvailablePrincipal(principals);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setRoles(user.getRoles());
        info.setStringPermissions(user.getPerms());
        returninfo; } /** * define the business logic of how to get user information and log in to Shiro */ @override protected AuthenticationInfodoGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        String username = upToken.getUsername();
        if (username == null) {
            throw new AccountException("Null usernames are not allowed by this realm.");
        }
        UserInfo userDB = userService.selectBy("userName",username);
        if (userDB == null) {
            throw new UnknownAccountException("No account found for admin [" + username + "]"); } / / query user roles and permissions endures SimpleAuthenticationInfo, such elsewhere. / / the SecurityUtils getSubject () getPrincipal () will be able to take out all of the user's information, Including roles and permissions List < String > roleList = userRoleService. GetRolesByUserId (userDB. GetId ()); List<String> permList = rolePermService.getPermsByUserId(userDB.getId()); Set<String> roles = new HashSet(roleList); Set<String> perms = new HashSet(permList); userDB.setRoles(roles); userDB.setPerms(perms); SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(userDB, userDB.getPassword(), getName()); info.setCredentialsSalt(ByteSource.Util.bytes(userDB.getSalt()));returninfo; }}Copy the code

Seven: Add Shiro configuration

To create the core – configurer – ShiroConfigurer

package com.example.demo.core.configurer; import com.example.demo.core.shiro.CustomRealm; import org.apache.shiro.realm.Realm; import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition; import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.annotation.Resource; @configuration Public class ShiroConfigurer {/** * inject a custom realm to tell Shiro how to obtain user information for login or permission control */ @bean public realmrealm() {
        return new CustomRealm();
    }

    @Bean
    public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator(); / * * *setUsePrefix(false) to solve a strange bug. In the case of Spring AOP. * Adding the @requiresRole annotation to the method of the @Controller annotated class causes the method to fail to map the request, resulting in a 404 return. * add this configuration to fix this bug */ creator. SetUsePrefix (true);
        returncreator; } /** * Authentication is used to determine which request paths require user login and which request paths do not require user login * @return
     */
    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
        DefaultShiroFilterChainDefinition chain = new DefaultShiroFilterChainDefinition();
        chain.addPathDefinition( "/userInfo/selectById"."authc, roles[admin]");
        chain.addPathDefinition( "/logout"."anon");
        chain.addPathDefinition( "/userInfo/selectAll"."anon");
        chain.addPathDefinition( "/userInfo/login"."anon");
        chain.addPathDefinition( "/ * *"."authc");
        returnchain; }}Copy the code

Shiro provides and several default filters that we can use to configure and control permissions on specified urls:

Configuration for Corresponding filter function
anon AnonymousFilter Specifies that the URL can be accessed anonymously
authc FormAuthenticationFilter Specifies that the URL requires a form login, which is obtained from the request by defaultusername,password.rememberMeIf the login fails, the system switches to the loginUrl path. We can also use this filter as the default login logic, but we usually write the login logic in the controller ourselves, and the error message returned by ourselves can be customized.
authcBasic BasicHttpAuthenticationFilter Basic login is required to specify the URL
logout LogoutFilter Logout filter, configure the specified URL can realize the exit function, very convenient
noSessionCreation NoSessionCreationFilter Disabling session creation
perms PermissionsAuthorizationFilter You need to specify permission to access
port PortFilter You need to specify a port for access
rest HttpMethodPermissionFilter Convert the HTTP request method to the corresponding verb to construct a permission string
roles RolesAuthorizationFilter You need to specify a role to access
ssl SslFilter An HTTPS request is required for access
user UserFilter You need to be logged in or Remember Me to access it

Add the login method to UserInfoController

@PostMapping("/login") public RetResult<UserInfo> login(String userName, String password) { Subject currentUser = SecurityUtils.getSubject();  Currentuser. login(new UsernamePasswordToken(userName, password)); }catch (IncorrectCredentialsException i){ throw new ServiceException("Incorrect password entry"); } UserInfo user = (UserInfo) currentUser.getPrincipal();return RetResponse.makeOKRsp(user);
}Copy the code

Nine: Add permission data to the database

INSERT INTO `sys_role` VALUES ('1'.'financial'.'Responsible for payroll'.'cw'.'the 2018-05-26 00:37:52', null, '0');
INSERT INTO `sys_role` VALUES ('2'.'personnel'.'Responsible staff'.'rs'.'the 2018-05-26 00:38:18', null, '0');
INSERT INTO `user_role` VALUES ('1'.'1'.'1');
INSERT INTO `user_role` VALUES ('2'.'1'.'2');
INSERT INTO `sys_perm` VALUES ('1'.'create'.'Create Permission'.'create'.'the 2018-05-26 00:39:16', null, '0');
INSERT INTO `sys_perm` VALUES ('2'.'delete'.'Delete permission'.'delete'.'the 2018-05-26 00:39:39', null, '0');
INSERT INTO `sys_perm` VALUES ('3'.'change'.'Modify Permissions'.'update'.'the 2018-05-26 00:39:58', null, '0');
INSERT INTO `sys_perm` VALUES ('4'.'query'.'Query permission'.'select'.'the 2018-05-26 00:40:16', null, '0');
INSERT INTO `role_perm` VALUES ('1'.'1'.'1');
INSERT INTO `role_perm` VALUES ('2'.'2'.'1');
INSERT INTO `role_perm` VALUES ('3'.'1'.'2');
INSERT INTO `role_perm` VALUES ('4'.'2'.'2');
INSERT INTO `role_perm` VALUES ('5'.'3'.'2');
INSERT INTO `role_perm` VALUES ('6'.'4'.'2');Copy the code

Add shiroUtilsController

package com.example.demo.controller;

import com.example.demo.core.ret.ServiceException;
import com.example.demo.model.UserInfo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("shiroUtils")
public class ShiroUtilsController {

    @GetMapping("/noLogin")
    public void noLogin() {
        throw new UnauthenticatedException();
    }

    @GetMapping("/noAuthorize")
    public void noAuthorize() {
        throw new UnauthorizedException();
    }


    @PostMapping("/getNowUser")
    public UserInfo getNowUser() {
        UserInfo u = (UserInfo) SecurityUtils.getSubject().getPrincipal();
        returnu; }}Copy the code

Eleven: Add error exception codes

package com.example.demo.core.ret; /** * @Description: Enumeration of response codes, * @author * @date 2018/4/19 09:42 */ public enum RetCode {// SUCCESS(200), // failure (400), // UNAUTHORIZED(401), /** UNAUTHORIZED(4401), /** UNAUTHORIZED(4401), Access denied */ UNAUTHZ(4403), // server internal error INTERNAL_SERVER_ERROR(500); public int code; RetCode(int code) { this.code = code; }}Copy the code

12: Add exception interception

@Override
	public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
		exceptionResolvers.add(new HandlerExceptionResolver() { @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) { RetResult<Object> result = new RetResult<Object>(); // Service failure exception, such as "incorrect account or password"if (e instanceof ServiceException) {
					result.setCode(RetCode.FAIL).setMsg(e.getMessage()).setData(null);
					LOGGER.info(e.getMessage());
				} else if (e instanceof NoHandlerFoundException) {
					result.setCode(RetCode.NOT_FOUND).setMsg("Interface [" + request.getRequestURI() + "] Does not exist");
				} else if (e instanceof UnauthorizedException) {
					result.setCode(RetCode.UNAUTHEN).setMsg("User does not have access rights").setData(null);
				}else if (e instanceof UnauthenticatedException) {
					result.setCode(RetCode.UNAUTHEN).setMsg("User not logged in").setData(null);
				}else if (e instanceof ServletException) {
					result.setCode(RetCode.FAIL).setMsg(e.getMessage());
				} else {
					result.setCode(RetCode.INTERNAL_SERVER_ERROR).setMsg("Interface [" + request.getRequestURI() + "] Internal error, please contact administrator");
					String message;
					if (handler instanceof HandlerMethod) {
						HandlerMethod handlerMethod = (HandlerMethod) handler;
						message = String.format("Interface [%s] exception, method: %s.%s, exception Summary: %s", request.getRequestURI(), handlerMethod.getBean().getClass().getName(), handlerMethod.getMethod()
								.getName(), e.getMessage());
					} else {
						message = e.getMessage();
					}
					LOGGER.error(message, e);
				}
				responseResult(response, result);
				returnnew ModelAndView(); }}); }Copy the code

13: Add shiro path configuration

Add in application.properties

# shiro configuration
The user is not logged in
shiro.loginUrl=/shiroUtils/noLogin
The user does not have permission
shiro.unauthorizedUrl=/shiroUtils/noAuthorizeCopy the code

Fourteen: Test

Enter localhost: 8080 / the userInfo/selectAll

We can see that we can get the data



Enter localhost: 8080 / the userInfo/selectById



Then login



Again access localhost: 8080 / the userInfo/selectById, we can see shiro has to take effect



Modify user access permission, restart, and log in again

chain.addPathDefinition( "/userInfo/selectById"."authc, roles[cw]");Copy the code

Again access localhost: 8080 / the userInfo/selectById



Fifteen: Optimization

Optimization 1: The permission cannot remain unchanged forever, when we need to change the permission, we need to manually modify shiro configuration file, obviously is not reasonable, the best way is to store the permission in the database, modify the database when changing

1: Create the URL resource table and add data

CREATE TABLE `sys_permission_init` (
  `id` varchar(255) NOT NULL,
  `url` varchar(255) DEFAULT NULL COMMENT 'Program url',
  `permission_init` varchar(255) DEFAULT NULL COMMENT 'Corresponding Shiro permissions',
  `sort` int(100) DEFAULT NULL COMMENT 'order',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `sys_permission_init` VALUES ('1'.'/userInfo/login'.'anon'.'1');
INSERT INTO `sys_permission_init` VALUES ('2'.'/userInfo/selectAll'.'anon'.'2');
INSERT INTO `sys_permission_init` VALUES ('3'.'/logout'.'anon'.'3');
INSERT INTO `sys_permission_init` VALUES ('4'.'/ * *'.'authc'.'0');
INSERT INTO `sys_permission_init` VALUES ('5'.'/userInfo/selectAlla'.'authc, roles[admin]'.'6');
INSERT INTO `sys_permission_init` VALUES ('6'.'/sysPermissionInit/aaa'.'anon'.'5');Copy the code

Here we need to keep ‘/**’ always at the end, so we need to add sort

2. Generate mapper, DAO, Service and Controller according to the tool and add the query methods we need

SysPermissionInitMapper.xml

<sql id="Base_Column_List">
  id, url, permission_init, sort
</sql>

<select id="selectAllOrderBySort" resultMap="BaseResultMap">
  SELECT
  <include refid="Base_Column_List"/>
  from sys_permission_init
  order by sort desc
</select>Copy the code

SysPermissionInitMapper.java

List<SysPermissionInit> selectAllOrderBySort();Copy the code

3: Modify ShiroConfigurer. Java

The modification is as follows

package com.example.demo.core.configurer; import com.example.demo.core.shiro.CustomRealm; import com.example.demo.model.SysPermissionInit; import com.example.demo.service.SysPermissionInitService; import org.apache.shiro.realm.Realm; import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition; import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.annotation.Resource; import java.util.List; @Configuration public class ShiroConfigurer { @Resource private SysPermissionInitService sysPermissionInitService; /** * Inject a custom realm to tell Shiro how to get user information for login or permission control */ @bean public realmrealm() {
        return new CustomRealm();
    }

    @Bean
    public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator(); / * * *setUsePrefix(false) to solve a strange bug. In the case of Spring AOP. * Adding the @requiresRole annotation to the method of the @Controller annotated class causes the method to fail to map the request, resulting in a 404 return. * add this configuration to fix this bug */ creator. SetUsePrefix (true);
        returncreator; } /** * Authentication is used to determine which request paths require user login and which request paths do not require user login * @return
     */
    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
        DefaultShiroFilterChainDefinition chain = new DefaultShiroFilterChainDefinition();
        List<SysPermissionInit> list = sysPermissionInitService.selectAllOrderBySort();
        for(int i = 0,length = list.size(); i<length; i++){ SysPermissionInit sysPermissionInit = list.get(i); chain.addPathDefinition(sysPermissionInit.getUrl(), sysPermissionInit.getPermissionInit()); }returnchain; }}Copy the code

4: testing

Enter localhost: 8080 / the userInfo/selectById



Then login

Again access localhost: 8080 / the userInfo/selectById, we can see shiro has to take effect



Modify the database user access permission, restart, and log in again

UPDATE sys_permission_init
SET permission_init = 'authc, roles[cw]'
WHERE
	id = 5Copy the code

Again access localhost: 8080 / the userInfo/selectById

Optimization 2: Every time we modify the permission information, we need to restart the server, which is obviously not reasonable

1: Creates shiroService

package com.example.demo.service; import java.util.Map; / * * * shiro dynamic update permissions * / public interface ShiroService {Map < String, the String > loadFilterChainDefinitions (); /** * Dynamic change permission */ void updatePermission(); }Copy the code

2: Create shiroServiceImpl

package com.example.demo.service.impl; import com.example.demo.model.SysPermissionInit; import com.example.demo.service.ShiroService; import com.example.demo.service.SysPermissionInitService; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager; import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver; import org.apache.shiro.web.servlet.AbstractShiroFilter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.HashMap; import java.util.List; import java.util.Map; @Service public class ShiroServiceImpl implements ShiroService { @Autowired ShiroFilterFactoryBean shiroFilterFactoryBean; @Autowired SysPermissionInitService sysPermissionInitService; Public Map<String, String>loadFilterChainDefinitions<String, String> filterChainDefinitionMap = new HashMap<>(); List<SysPermissionInit> list = sysPermissionInitService.selectAllOrderBySort();for (SysPermissionInit sysPermissionInit : list) {
            filterChainDefinitionMap.put(sysPermissionInit.getUrl(),
                    sysPermissionInit.getPermissionInit());
        }
        returnfilterChainDefinitionMap; } /** * reload permission */ @override public voidupdatePermission() {
        synchronized (shiroFilterFactoryBean) {
            AbstractShiroFilter shiroFilter = null;
            try {
                shiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean
                        .getObject();
            } catch (Exception e) {
                throw new RuntimeException("get ShiroFilter from shiroFilterFactoryBean error!"); } PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter .getFilterChainResolver(); DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver .getFilterChainManager(); // Clear the old permission control manager.getFilterChains().clear(); shiroFilterFactoryBean.getFilterChainDefinitionMap().clear(); shiroFilterFactoryBean.setFilterChainDefinitionMap(loadFilterChainDefinitions()); / / rebuild generates a Map < String, the String > chains. = shiroFilterFactoryBean getFilterChainDefinitionMap ();for (Map.Entry<String, String> entry : chains.entrySet()) {
                String url = entry.getKey();
                String chainDefinition = entry.getValue().trim().replace(""."");
                manager.createChain(url, chainDefinition);
            }
            System.out.println("Update permissions successful!!"); }}}Copy the code

3: Modify shiroUtilsController

Add the following code

/** * @description: Reload shiro permission * @throws Exception */ @postMapping ("/updatePermission")
public void updatePermission() throws Exception {
    shiroService.updatePermission();
}Copy the code

4: testing

Enter localhost: 8080 / the userInfo/selectById



Modify the permissions

UPDATE sys_permission_init
SET permission_init = 'authc, roles[cw1]'
WHERE
id = 5Copy the code

Enter localhost: 8080 / shiroUtils/updatePermission reload the permissions

Note: We are not modifying any part of the program or restarting the server at this time

Enter localhost: 8080 / the userInfo/selectById



Success!


Add: generate the encrypted user password

The files in the core – utils – test. Java

Public static void main(String []ages){// Encryption type StringhashAlgorithmName = "md5"; // The old password String credentials ="123456"; // Encryption times inthashIterations = 1024; // Encrypt the salt value, you can use the String generation method Stringhash = "wxKYXuTPST5SG0jMQzVPsg==";
    ByteSource credentialsSalt = ByteSource.Util.bytes(hash);
    String password = new SimpleHash(hashAlgorithmName, credentials, credentialsSalt, hashIterations).toHex();
    System.out.println(password);
}Copy the code


The project address

Code cloud address: gitee.com/beany/mySpr…

GitHub address: github.com/MyBeany/myS…

Writing articles is not easy, if it is helpful to you, please help click star

At the end

The interface function of adding Shiro permission protection has been completed, and the subsequent functions will be updated successively. If you have any questions, please contact me at [email protected]. Ask for directions from various gods, thank you.