背景:
本章将进一步的落地实践学习,在springboot中如何去整合shrio,整个过程步骤有个清晰的了解。
利用Shiro进行登录认证主要步骤:
1. 添加依赖:首先,在pom.xml
文件中添加Spring Boot和Shiro的相关依赖。
<!-- Spring Boot --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Shiro --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-starter</artifactId> <version> 1.7 . 1 </version> </dependency> |
2. 创建Shiro配置类:创建一个ShiroConfig
类,用于配置Shiro的相关信息和组件。(对于配置的解释和作用见第三章杂谈)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | @Configuration public class ShiroConfig { // 配置安全管理器 @Bean public DefaultWebSecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myRealm()); return securityManager; } // 配置自定义Realm @Bean public MyRealm myRealm() { return new MyRealm(); } // 配置Shiro过滤器 @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean() { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager()); shiroFilterFactoryBean.setLoginUrl( "/login" ); // 设置登录页面 shiroFilterFactoryBean.setUnauthorizedUrl( "/unauthorized" ); // 设置未授权页面 Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>(); // 允许匿名访问的路径 filterChainDefinitionMap.put( "/login" , "anon" ); filterChainDefinitionMap.put( "/static/**" , "anon" ); // 需要认证才能访问的路径 filterChainDefinitionMap.put( "/**" , "authc" ); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } } |
3. 创建自定义Realm:创建一个MyRealm
类,继承AuthorizingRealm
并实现相关方法,用于处理认证和授权逻辑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | public class MyRealm extends AuthorizingRealm { // 处理认证逻辑 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { // 从token中获取用户名 String username = (String) authenticationToken.getPrincipal(); // 模拟从数据库或其他存储中获取用户信息 // 例如,从数据库中查询用户信息并返回 String dbPassword = "123456" ; // 假设从数据库中查询的密码是123456 // 返回认证信息,包括用户名和密码 return new SimpleAuthenticationInfo(username, dbPassword, getName()); } // 处理授权逻辑 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { // 从PrincipalCollection中获取用户名 String username = (String) principalCollection.getPrimaryPrincipal(); // 模拟从数据库或其他存储中获取用户角色和权限信息 // 例如,从数据库中查询用户对应的角色和权限并返回 Set<String> roles = new HashSet<>(); roles.add( "admin" ); // 假设用户拥有admin角色 Set<String> permissions = new HashSet<>(); permissions.add( "user:read" ); // 假设用户拥有user:read权限 // 创建授权信息 SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); authorizationInfo.setRoles(roles); authorizationInfo.setStringPermissions(permissions); return authorizationInfo; } } |
4. 创建登录接口和登录页面:创建一个登录接口处理用户的登录请求
@Controller public class LoginController { @GetMapping ( "/login" ) public String login() { return "login" ; } @PostMapping ( "/login" ) public String doLogin(String username, String password) { // 执行登录逻辑 Subject currentUser = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(username, password); try { currentUser.login(token); // 执行登录 return "redirect:/home" ; // 登录成功后跳转到首页 } catch (AuthenticationException e) { return "redirect:/login-error" ; // 登录失败后跳转到错误页面 } } } |
整体的执行流程:
-
用户在浏览器中访问登录页面,输入用户名和密码,并点击登录按钮。
-
Controller层的LoginController
类中的doLogin
方法被调用,该方法接收用户名和密码作为参数。
-
创建一个Subject
对象,该对象代表当前正在与应用程序交互的用户。
-
创建一个UsernamePasswordToken
对象,将用户名和密码设置为该对象的属性。
-
调用Subject
对象的login
方法,将UsernamePasswordToken
对象作为参数传递进去。
-
Subject
对象将UsernamePasswordToken
对象传递给Shiro进行认证。
-
Shiro框架会调用MyRealm
类中的doGetAuthenticationInfo
方法,该方法用于处理认证逻辑。
-
在doGetAuthenticationInfo
方法中,从UsernamePasswordToken
对象中获取用户名。
-
可以根据需要,从数据库或其他存储中获取与用户名对应的用户信息,例如密码等。
-
将获取到的用户信息与UsernamePasswordToken
对象中的密码进行比较,判断用户是否通过认证。
-
如果认证成功,创建一个SimpleAuthenticationInfo
对象,将用户名、数据库中的密码和Realm名称作为参数传递给它。
-
SimpleAuthenticationInfo
对象会被返回给Shiro框架,表示认证成功。
-
Shiro框架会将认证成功的信息保存在Subject
对象中。
-
如果认证失败,将抛出AuthenticationException
异常。
-
在doLogin
方法中,通过捕获AuthenticationException
异常,可以处理登录失败的情况,例如重定向到登录失败页面。
-
如果登录成功,可以根据需要执行一些操作,例如重定向到首页或其他需要登录后才能访问的页面。
总结起来,整个执行流程如下:
- 用户输入用户名和密码,并提交登录表单。
- Controller层的
LoginController
类中的doLogin
方法接收到登录请求。 - 创建
Subject
对象,代表当前用户。 - 创建
UsernamePasswordToken
对象,将用户名和密码设置为其属性。 - 调用
Subject
对象的login
方法,将UsernamePasswordToken
对象作为参数传入。 - Shiro框架调用
MyRealm
类中的doGetAuthenticationInfo
方法,处理认证逻辑。 - 在
doGetAuthenticationInfo
方法中,获取用户名和密码,并与数据库中的信息进行比较。 - 如果认证成功,返回一个
SimpleAuthenticationInfo
对象,表示认证通过。 - 如果认证失败,抛出
AuthenticationException
异常。 - 在
doLogin
方法中,根据认证结果执行相应的操作,例如重定向到登录成功页面或登录失败页面。
最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:
行动吧,在路上总比一直观望的要好,未来的你肯定会感谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入群: 731789136,里面有各种测试开发资料和技术可以一起交流哦。
这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!