SpringBoot整合Shiro并实现登录
在项目中要对不同的用户有不同的权限,那么这些权限将由Shiro来控制
导入Shiro的MAVEN依赖
-
pom.xml
-
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
-
导入完成后按
ctrl+o
,IDEA快捷键
Java代码
-
首先创建一个类,这个类要继承
AuthorizingRealm
,并实现两个方法 -
//返回用户的角色权限 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { //设置用户的权限 return null; } //实现用户的登录行为 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //访问数据库进行用户的用户名和密码的校验 return null; }
-
还需要又一个Shiro配置类
-
package com.mucd.shiro.config; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.mgt.SessionsSecurityManager; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.LinkedHashMap; import java.util.Map; /** * User: Mucd */ @Configuration public class ShiroConfig { @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean(); factoryBean.setSecurityManager(securityManager); //设置登录的地址 factoryBean.setLoginUrl("/login"); Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>(); filterChainDefinitionMap.put("/", "anon"); //anon 不需要登录 filterChainDefinitionMap.put("/login", "anon"); //anon 不需要登录 filterChainDefinitionMap.put("/dologin", "anon"); //authc 需要登录才能访问 平时开发改成anon,允许匿名访问 filterChainDefinitionMap.put("/**", "authc"); factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return factoryBean; } @Bean public SessionsSecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(authRealm()); securityManager.setSessionManager(sessionManager()); return securityManager; } @Bean public AuthRole authRealm() { return new AuthRole(); } //去掉jsessionid小尾巴 @Bean public DefaultWebSessionManager sessionManager() { //SessionIdUrlRewritingEnabled的默认值是false return new DefaultWebSessionManager(); } }
-
shiroFilterFactoryBean()
方法中有个anon
和authc
,这两个是什么意思呢anon
代表不需要拦截验证,authc
需要拦截验证,验证通过了,才能继续下一个页面. , 如果没有验证通过,那么跳转到factoryBean.setLoginUrl("/login")
这个地址
-
编写Controller
-
package com.mucd.shiro.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; /** * @author mucd * @time 2022/2/14 20:40 */ @Controller public class ShiroController { @RequestMapping("/login") public ModelAndView toLogin(){ return new ModelAndView("login"); } @RequestMapping("/content") public ModelAndView toContent(){ return new ModelAndView("content"); } }
-
-
按照
ShiroConfig
配置配置类的规则,进入login和/这两个路径是不会被拦截的, 而访问content被拦截并且跳转到 login 中 -
基础配置就到这里. 下面实现 登录
Shiro实现登录
-
现在实现登录和退出登录
-
实体类
-
@Data public class User implements Serializable { private String username; private String password; }
-
-
dao
-
@Mapper public interface UserDao { @Select("select * from users.person where username =#{username} and password = #{password}") User login(String username, String password); }
-
-
ShiroConfig
-
@Configuration public class ShiroConfig { @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean(); factoryBean.setSecurityManager(securityManager); //设置登录的地址 factoryBean.setLoginUrl("/login"); Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>(); filterChainDefinitionMap.put("/", "anon"); //anon 不需要登录 filterChainDefinitionMap.put("/login", "anon"); //anon 不需要登录 filterChainDefinitionMap.put("/dologin", "anon"); //authc 需要登录才能访问 平时开发改成anon,允许匿名访问 filterChainDefinitionMap.put("/**", "authc"); factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return factoryBean; } @Bean public SessionsSecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(authRealm()); securityManager.setSessionManager(sessionManager()); return securityManager; } @Bean public AuthRole authRealm() { return new AuthRole(); } //去掉jsessionid小尾巴 @Bean public DefaultWebSessionManager sessionManager() { //SessionIdUrlRewritingEnabled的默认值是false return new DefaultWebSessionManager(); } }
-
-
ShiroController
-
@Controller public class ShiroController { @RequestMapping("/login") public ModelAndView toLogin(){ return new ModelAndView("login"); } @RequestMapping("/content") public ModelAndView doLogin(){ return new ModelAndView("content"); } //登录功能 @RequestMapping("/dologin") @ResponseBody public String toContent(String username,String password){ Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(username,password); try { subject.login(token); return "success"; } catch (AuthenticationException e) { e.printStackTrace(); return "error"; } } //登出功能 @RequestMapping("/logout") public Object logout(){ SecurityUtils.getSubject().logout(); //重定向到登录页面 return new ModelAndView("redirect:login"); } }
-
-
AuthRole.java
-
package com.mucd.shiro.config; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; /** * @author mucd * @time 2022/2/14 20:18 */ public class AuthRole extends AuthorizingRealm { //返回用户的角色权限 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { //设置用户的权限 return null; } //实现用户的登录行为 //实现用户的登录行为 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //访问数据库进行用户的用户名和密码的校验 //获取到username and password String username = (String) authenticationToken.getPrincipal(); String password = new String((char[]) authenticationToken.getCredentials()); System.out.println("username = " + username); System.out.println("password = " + password); final User login = userDao.login(username, password); System.out.println("login = " + login); if (login != null) { return new SimpleAuthenticationInfo(username, password, getName()); } throw new AuthenticationException("登录验证失败"); } }
-
-
前端页面
-
index.html
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>首页</title> </head> <body> <h1>这是首页</h1> </body> </html>
-
-
login.html
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登录</title> </head> <body> <h1>Login view</h1> <form action="/dologin" method="post"> <input type="text" name="username"> <br> <input type="password" name="password"> <br> <input type="submit"> </form> </body> </html>
-
-
content.html
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>内容页面</title> </head> <body> <h1>验证已经通过</h1> <a href="/logout">logout</a> </body> </html>
-
-
ok!!!
-
-
启动项目, 打开浏览器测试
- 未登录访问首页 ok
- 未登录访问 login.html ok
- 未登录访问 content.html 失败
- 登录后访问首页 ok
- 登录后访问 content.html 成功!!!