Shiro
I Shiro permissions
- What is permission control:
- Ignore particularly detailed concepts. For example, permissions can be subdivided into many types, such as function permissions, data permissions, management permissions, etc
- Understand two concepts: user and resource, so that the specified user can only operate the specified resource (CRUD)
- What to do when learning java web
- There is a doFilter method in the Filter interface. Write your own business Filter and configure which web resource to intercept
- If the access path hits the corresponding Filter, the doFilter() method will be executed, and then judge whether you have permission to access the corresponding resources
- /api/user/info?id=1
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) { HttpServletRequest httpRequest=(HttpServletRequest)request; HttpServletResponse httpResponse=(HttpServletResponse)response; HttpSession session=httpRequest.getSession(); if(session.getAttribute("username")!=null){ chain.doFilter(request, response); //If it can be released } else { httpResponse.sendRedirect(httpRequest.getContextPath()+"/login.jsp"); } }
II Permission framework ACL and RBAC
2.1 what are ACL and RBAC
- ACL: Access Control List
- The core of a previously popular permission design is that users are directly linked to permissions
- Advantages: simple and easy to use, convenient development
- Disadvantages: users and permissions are directly linked, resulting in complexity and dispersion during authorization, which is not easy to manage
- Example: common file system permission design directly adds permissions to users
- RBAC: Role Based Access Control
- Role based access control system. Permissions are associated with roles. Users get the permissions of these roles by becoming members of the appropriate roles
- Advantages: it simplifies the management of users and permissions. By classifying users, roles and permissions are associated
- Disadvantages: the development of ACL is relatively complex
- Example: authorization verification framework and application based on RBAC model Apache Shiro and spring Security
- BAT enterprise ACL S are generally used for the report system and Alibaba ODPS
- Conclusion: it should not be too complex. If there are too many rules, the maintainability and performance will be reduced. More classification ABAC, PBAC, etc
2.2 introduction to mainstream authority framework and explanation of technical selection
-
What is spring Security: introduction to the official website
- Official website: https://spring.io/projects/spring-security
Spring Security is a security framework that can provide declarative security access control solutions for spring based enterprise applications. It provides a set of beans that can be configured in the spring application context, and makes full use of Spring IoC, DI (inversion of control, DI: dependency injection) and AOP (aspect oriented programming) functions to provide declarative security access control function for the application system and reduce the work of writing a large amount of repeated code for enterprise system security control.
Bottom line: the predecessor of Spring Security is Acegi Security, which is the framework used by the Spring project team to provide security authentication services -
What is Apache Shiro: introduction to the official website
- https://github.com/apache/shiro
Apache Shiro is a powerful and easy-to-use Java security framework that performs authentication, authorization, password, and session management. With Shiro's easy to understand API, you can get any application quickly and easily, from the smallest mobile application to the largest network and enterprise application. Bottom line: Shiro is a powerful and easy-to-use Java security framework that provides authentication, authorization, encryption and session management
-
Two advantages and disadvantages, how to choose
- Apache Shiro is simpler to use than Spring Security
- Shiro is powerful, simple and flexible. It does not bind to any framework or container and can run independently
- Spring Security supports spring system well, but it is difficult to develop without spring system
- Spring security supports Oauth authentication https://spring.io/projects/spring-security-oauth , Shiro needs to implement it himself
III Apache Shiro basic concepts and architecture
3.1 architecture diagram and four modules of Shiro core knowledge
- Direct access to Apache Shiro official website http://shiro.apache.org/introduction.html
- What is identity authentication
- Authentication, ID card authentication, is generally login
- What is authorization
- Authorization, which assigns users roles or permissions to access certain resources
- What is session management
- Session Management is the user's session administrator. In most cases, it is a web session
- What is encryption
- Cryptography, data encryption and decryption, such as password encryption and decryption
[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-u4yz1exu-1624780881563)( http://shiro.apache.org/assets/images/ShiroFeatures.png )]
3.2 Shrio authority control process and concept
- Subject
- We refer to users or programs as principals (such as users, third-party services, cron jobs), and principals access systems or resources
- SecurityManager
- The authentication and authorization of the security manager and Subject shall be carried out under the security manager
- Authenticator
- Authenticator, which is mainly responsible for the authentication of Subject
- Realm
- Data domain, Shiro and security data connector, such as jdbc connection database; Obtain information related to authentication and authorization through realm
- Authorizer
- The authorizer is mainly responsible for the authorization of the subject and controlling the role or permission of the subject
- Cryptography
- Encryption and decryption, Shiro contains easy-to-use and understandable data encryption and decryption methods, simplifying many complex APIs
- Cache Manager
- Cache managers, such as authentication or authorization information, manage through cache to improve performance
More information navigation: http://shiro.apache.org/reference.html
IV Spring boot integration Shiro
4.1 dependence
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP-java7</artifactId> <version>2.4.13</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.3.2</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.1</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies>
4.2 design of database table
Five tables of authority standards:
- sys_user
- sys_role
- sys_user_role
- sys_permission
- sys_role_permission
4.3 custom realm
/** * Create a realm. There are two methods in the realm. */ public class CustomizeRealm extends AuthorizingRealm { // Authentication. As long as the AuthenticationInfo is returned successfully, @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { System.out.println("Start certification"); if(authenticationToken instanceof UsernamePasswordToken) { UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken; String username = token.getUsername(); String password = new String(token.getPassword()).intern(); // To db validation System.out.println("username: " + username + "## password: " + password); AuthenticationInfo info = new SimpleAuthenticationInfo(username, password, "XX"); return info; } return null; } // to grant authorization @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { System.out.println("to grant authorization"); return null; } }
SecurityUtils. getSubject(). Where is the user information obtained by getprincipal () set?
Custom realm – "doGetAuthenticationInfo" – "simpleauthenticationinfo" = new simpleauthenticationinfo (user, user. Getpassword(), bytesourcesalt, getname());
The first parameter of the method is securityutils getSubject(). The value obtained by getprincipal () can set String and object.
It has been difficult to distinguish between authentication and authorization before. In fact, it is very simple. For example:
If you want to board the plane, you need to show your ID card and ticket. The ID card is to prove that you Zhang San is indeed you Zhang San. This is authentication; The ticket is to prove that you Zhang San did buy a ticket to get on the plane. This is authorization.
4.3 shiro configuration
@Configuration public class ShiroConfig { @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean(); // Set up the SecurityManager to be responsible for the operation of the whole shiro factoryBean.setSecurityManager(securityManager); factoryBean.setLoginUrl("/login.html"); Map<String, String> filterMap = new HashMap<>(); /** * map The key of the map is the access path, and the value of the map is a fixed value: anno, authc * anon -> anonymous((anonymous) * authc -> authencation((certified) */ filterMap.put("/login", "anon"); // Access is not allowed until authentication is passed // filterMap.put("/user", "authc"); // Access is not allowed until authentication is passed // filterMap.put("/test", "authc"); // It can be accessed anonymously. To put it bluntly, you don't need to log in filterMap.put("/**", "authc"); factoryBean.setFilterChainDefinitionMap(filterMap); return factoryBean; } /** * SecurityManager Configuration of */ @Bean public SecurityManager securityManager(SessionManager manager, Realm realm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setSessionManager(sessionManager); securityManager.setRealm(realm); return securityManager; } /** * This class is used to set permissions by implementing annotations */ @Bean public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){ DefaultAdvisorAutoProxyCreator advisor = new DefaultAdvisorAutoProxyCreator(); advisor.setProxyTargetClass(true); return advisor; } /** * Configure permissions by implementing annotations */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){ AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } /** @Bean public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } */ /** * SessionManager Configuration of */ @Bean public SessionManager sessionManager(){ SessionManager sessionManager = new CustomSessionManager(); return sessionManager; } /** * Realm * @param addSaltCredentialsMatch * @return */ @Bean public Realm realm(AddSaltCredentialsMatch addSaltCredentialsMatch) { CustomRealm realm = new CustomRealm(); realm.setCredentialsMatcher(addSaltCredentialsMatch); //Password rules return realm; } /** * Custom password salt rules * @return */ @Bean public AddSaltCredentialsMatch addSaltCredentialsMatch() { return new AddSaltCredentialsMatch(); } }
4.4 user login
@RequestMapping("/login") @RestController public class LoginController { @GetMapping public String login(String username, String password) { // Get a topic (user) Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(username, password); subject.login(token); return "success"; } }
4.5 custom SessionManager
public class CustomSessionManager extends DefaultWebSessionManager { /** * Override the default session * @param request * @param response * @return */ @Override protected Serializable getSessionId(ServletRequest request, ServletResponse response) { String sessionId = WebUtils.toHttp(request).getHeader("Authencation"); if(null != sessionId) { request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, ShiroHttpServletRequest.COOKIE_SESSION_ID_SOURCE); request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, sessionId); //automatically mark it valid here. If it is invalid, the //onUnknownSession method below will be invoked and we'll remove the attribute at that time. request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE); return sessionId; }else { return super.getSessionId(request, response); } } }
V Permission data cache
As the middleware most frequently used by enterprises, redis is used to cache various business data. When shiro's cache is used, redis is still used as the caching Middleware in the course. Download address: https://github.com/MicrosoftArchive/redis/releases
5.1 introducing dependencies
<dependency> <groupId>org.crazycake</groupId> <artifactId>shiro-redis</artifactId> <version>3.2.3</version> </dependency>
5.2 configuring RedisManager
@Bean public RedisManager redisManager() { RedisManager redisManager = new RedisManager(); redisManager.setHost("localhost:6379"); return redisManager; }
5.3 configuring CacheManager
@Bean public CacheManager cacheManager(RedisManager redisManager) { RedisCacheManager cacheManager = new RedisCacheManager(); cacheManager.setRedisManager(redisManager); return cacheManager; }
5.4 add cache management in SecurityManager
securityManager.setCacheManager(cacheManager);
Vi Session data cache
6.1 configuring RedisSessionDao
@Bean public RedisSessionDAO redisSessionDAO(RedisManager redisManager) { RedisSessionDAO redisSessionDAO = new RedisSessionDAO(); redisSessionDAO.setRedisManager(redisManager); return redisSessionDAO; }
6.2 setting of SessionManager
@Bean public SessionManager sessionManager(RedisSessionDAO redisSessionDAO){ CustomSessionManager sessionManager = new CustomSessionManager(); sessionManager.setSessionDAO(redisSessionDAO); return sessionManager; }
Appendix:
/** shiro Two md5 processes are provided internally. However, the data obtained is inconsistent with the md5 data obtained by other tool classes. */ @Bean public CredentialsMatcher credentialsMatcher() { HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); hashedCredentialsMatcher.setHashAlgorithmName("MD5"); //Set encryption method hashedCredentialsMatcher.setHashIterations(2); //md5 encryption twice return hashedCredentialsMatcher; }
Processing method: when the user registers and stores the password, the password is stored according to shiro's rules.
new SimpleHash("md5", "123", null, 2).toString() // The password obtained by this processing method is stored in the database.