Shiro is a powerful and easy-to-use Java security framework on the official website: https://shiro.apache.org/.
The main functions are authentication, authorization, encryption, and session management.
Other features include Web support, caching, test support, allowing one user to access as another user, and remembering me.
Shiro has three core components: Subject, SecurityManager, and Realm.
Subject: That is, the current operation "user", "user" does not only refer to people, but also third-party processes, background accounts, or other similar things.
SecurityManager: Security Manager, the core of Shiro framework, manages all Subject s through SecurityManager and provides various services for security management.
Realm: Domain, acting as a "bridge" or "connector" between Shiro and application security data.That is, when authenticating (login) and authorizing (access control) users, Shiro will look up the user and its permission information from the Relm in the application configuration.When configuring Shiro, you must specify at least one Realm for authentication and/or authorization.
Shiro is integrated in Spring Boot and there are two different approaches depending on the introduced dependent packages shiro-spring and shiro-spring-boot-web-starter (both version 1.4.2).
Method 1: Introduce dependent package shiro-spring
1. Create a new SpringBoot project in IDEA with the following dependent packages referenced by pom.xml:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.2</version> </dependency>
2. Create Realm and configure shiro
(1) Create Realm
package com.example.demo.config; import org.apache.shiro.authc.*; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; public class MyRealm extends AuthorizingRealm { /**Permission information, not implemented yet*/ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { return null; } /**Authentication: Verify that the user has entered the correct account and password.*/ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { //Get account entered by user String userName = (String) token.getPrincipal(); //Authenticate User admin And password 123456 are correct if (!"admin".equals(userName)) { throw new UnknownAccountException("Account does not exist!"); } SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(userName, "123456", getName()); return authenticationInfo; //In the actual project, the above account retrieves the user object from the database to determine if it exists /*User user = userService.findByUserName(userName); if (user == null) { throw new UnknownAccountException("Account does not exist! "; } SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user,user.getPassword(), getName()); return authenticationInfo; */ } }
(2) Configure Shiro
package com.example.demo.config; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.LinkedHashMap; import java.util.Map; @Configuration public class ShiroConfig { @Bean MyRealm myRealm() { return new MyRealm(); } @Bean DefaultWebSecurityManager securityManager() { DefaultWebSecurityManager manager = new DefaultWebSecurityManager(); manager.setRealm(myRealm()); return manager; } @Bean ShiroFilterFactoryBean shiroFilterFactoryBean() { ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); bean.setSecurityManager(securityManager()); //If you do not set the default, it will look for it automatically Web Project Root"/login.jsp"page bean.setLoginUrl("/login"); //Links to jump after successful login bean.setSuccessUrl("/index"); //Unauthorized interface bean.setUnauthorizedUrl("/403"); //Configure links that will not be blocked Map<String, String> map = new LinkedHashMap<>(); map.put("/doLogin", "anon"); map.put("/**", "authc"); bean.setFilterChainDefinitionMap(map); return bean; } }
3. Controller Test Method
package com.example.demo.controller; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.UnknownAccountException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class LoginController { @GetMapping("/login") public String login() { return "Logon Page..."; } @PostMapping("/doLogin") public String doLogin(String userName, String password) { Subject subject = SecurityUtils.getSubject(); try { subject.login(new UsernamePasswordToken(userName, password)); return "Login Successful!"; } catch (UnknownAccountException e) { return e.getMessage(); } catch (AuthenticationException e) { return "Logon failure, bad password!"; } } //If you don't log in first, the visit skips to/login @GetMapping("/index") public String index() { return "index"; } @GetMapping("/403") public String unauthorizedRole(){ return "No privileges"; } }
Method 2: Introduce dependent package shiro-spring-boot-web-starter
1. Remove shiro-spring from pom.xml and introduce shiro-spring-boot-web-starter
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-web-starter</artifactId> <version>1.4.2</version> </dependency>
2. Create Realm and configure shiro
(1) Create Realm, the same code and method.
(2) Configure Shiro
package com.example.demo.config; import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition; import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ShiroConfig { @Bean MyRealm myRealm() { return new MyRealm(); } @Bean DefaultWebSecurityManager securityManager() { DefaultWebSecurityManager manager = new DefaultWebSecurityManager(); manager.setRealm(myRealm()); return manager; } @Bean ShiroFilterChainDefinition shiroFilterChainDefinition() { DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition(); definition.addPathDefinition("/doLogin", "anon"); definition.addPathDefinition("/**", "authc"); return definition; } }
(3) application.yml configuration
shiro: unauthorizedUrl: /403 successUrl: /index loginUrl: /login