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 information
AuthenticationInfo
Instance. - Thrown if validation fails
AuthenticationException
Exception 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 .rememberMe If 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.