Shiro is a common security authentication framework, which is simple and practical. There are two ways to integrate Shiro in Spring Boot:
- Implement the configuration in traditional SSM+Shiro in Java
- Use Shiro's official automated configuration dependency
This article chooses the second practical way to integrate, but when using Postman for testing, there are the following errors:
org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager accessible to the calling code, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton. This is an invalid application configuration.
- The Postman error message is as follows
I have found various online tutorials to find solutions, most of which are filter problems. To add DelegatingFilterProxy in web.xml. However, the integration of this paper is tested in the Spring Boot environment, without using the web.xml file. If you add the web.xml file, the whole project will look like nothing else. So abandon the solution. How to solve that?
After consulting with colleagues, we know that the following dependencies are needed to use Shiro's official automation configuration
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-web-starter</artifactId> <version>1.4.0</version> </dependency>
Instead of using Java to implement the dependency of configuration in SSM+Shiro
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>1.4.0</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version> </dependency>
The correct code example is as follows
- Add dependency
<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.0</version> </dependency>
- Customize a MyRealm
public class MyRealm extends AuthorizingRealm { @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { return null; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String username = ((UsernamePasswordToken) token).getUsername(); if (!"zhangsan".equals(username)) { throw new UnknownAccountException("Account does not exist"); } return new SimpleAuthenticationInfo(username, "123", getName()); } }
- Create ShiroConfig
@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; } }
- Create a Controller to test
@Controller public class ShiroController { @PostMapping("/doLogin") public String doLogin(String username, String password) { try { Subject subject = SecurityUtils.getSubject(); subject.login(new UsernamePasswordToken(username, password)); return "redirect:/index";//Verify successful page Jump } catch (AuthenticationException e) { e.printStackTrace(); } return "redirect:/login";//Verification failed jump page } @GetMapping("/index") @ResponseBody public String index() { return "index"; } @GetMapping("/login") @ResponseBody public String login() { return "login"; } }
- The test results are as follows
A little makes a lot!