想要进行认证,授权,加密需要进行以下操作
pom.xml
需要配置的依赖
<!-- Shiro权限管理的Thymeleaf额外功能 -->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
<!-- Thymeleaf布局方言,用于简化页面布局 -->
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>
<!-- Apache Shiro的Spring集成 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.1</version>
</dependency>
<!-- Shiro的Redis缓存支持 -->
<dependency>
<groupId>org.crazycake</groupId>
<artifactId>shiro-redis</artifactId>
<version>3.1.0</version>
</dependency>
Config配置
ShiroConfig配置信息
@Configuration
public class ShiroConfig {
@Autowired
ISysRightService sysRightService;
/*** 创建ShiroDialect bean
* ShiroDialect是用于集成Shiro和Spring的一个重要组件它作为Shiro和Spring之间的桥梁,
* 允许在Spring的配置中使用Shiro的标签和功能这个方法通过标注@Bean来定义一个bean,
* 使得Spring IoC容器可以管理这个bean,并将其注入到需要的地方
* @return 新创建的ShiroDialect实例*/
@Bean(name = "shiroDialect")
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}
/*** 配置并创建一个Realm实例
* 在Spring框架中,通过在方法上添加@Bean注解来声明一个Bean
* 这个方法负责初始化并返回一个MyRealm实例,MyRealm是Realm接口的具体实现
* @return Realm 实例,它是一个自定义的Realm,用于安全管理,如用户身份验证和授权*/
@Bean
public Realm realm() {
Realm realm = new MyRealm();
return realm;
}
/*** 配置并创建RedisManager bean实例
*此方法无需外部参数,通过new操作符直接实例化RedisManager对象
*主要作用是整合RedisManager与Spring容器,使其能被自动管理与注入
*@return RedisManager 实例化的RedisManager对象,用于操作Redis数据存储*/
@Bean
public RedisManager redisManager() {
return new RedisManager();
}
/*** 配置Redis缓存管理器的Bean
* 该方法在Spring容器中创建并配置一个RedisCacheManager实例
* @param redisManager Redis管理器,用于执行Redis缓存操作
* @return 返回一个配置好的Redis缓存管理器实例*/
@Bean
public RedisCacheManager redisCacheManager(RedisManager redisManager) {
// 创建Redis缓存管理器实例
RedisCacheManager cacheManager = new RedisCacheManager();
// 设置Redis管理器,用于缓存操作
cacheManager.setRedisManager(redisManager);
// 设置缓存中主体ID的字段名称,这里使用用户名作为主体ID
cacheManager.setPrincipalIdFieldName("usrName");
// 返回配置好的缓存管理器实例
return cacheManager;
}
/*** 配置并创建一个DefaultWebSecurityManager实例
* 该实例用于管理Web应用的安全,包括认证和授权
* @param realm 自定义的Realm实现,用于与数据源交互进行身份验证和授权
* @param redisCacheManager Redis缓存管理器,用于存储和管理安全相关的缓存数据
* @return 返回配置好的DefaultWebSecurityManager实例*/
@Bean
public DefaultWebSecurityManager securityManager(Realm realm, RedisCacheManager redisCacheManager) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realm);
securityManager.setCacheManager(redisCacheManager);
return securityManager;
}
/*** 创建并配置Shiro过滤器工厂豆
* @param securityManager 默认的Web安全管理者,是Shiro的核心安全管理对象
* @return 返回配置好的ShiroFilterFactoryBean实例*/
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
// 初始化Shiro过滤器工厂豆
ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
// 设置安全管理器
filterFactoryBean.setSecurityManager(securityManager);
// 设置未登录时的跳转URL
filterFactoryBean.setLoginUrl("/index");
// 设置未授权时的跳转URL
filterFactoryBean.setUnauthorizedUrl("/403");
// 创建一个有序的Map用于存放过滤规则
Map<String, String> map = new LinkedHashMap<>();
// 配置公共资源,这些资源不需要认证就可以访问
map.put("/css/**", "anon");
map.put("/fonts/**", "anon");
map.put("/images/**", "anon");
map.put("/js/**", "anon");
map.put("/localcss/**", "anon");
map.put("/localjs/**", "anon");
map.put("/dologin", "anon");
// 配置退出登录的URL
map.put("/logout", "logout");
// 从数据库中获取所有权限,并为每个权限配置相应的过滤规则
List<SysRight> rights = sysRightService.list();
for (SysRight right : rights) {
// 只有当权限URL不为空时,才添加到过滤规则中
if (right.getRightUrl() != null && !right.getRightUrl().trim().equals("")) {
map.put(right.getRightUrl(), "perms[" + right.getRightCode() + "]");
}
}
// 所有页面都要认证
map.put("/**", "authc");
filterFactoryBean.setFilterChainDefinitionMap(map);
return filterFactoryBean;
}
}
Realm配置信息
public class MyRealm extends AuthorizingRealm {
@Autowired
private ISysUserService sysUserService;
/** 授权方法
* 该方法用于获取用户的授权信息,包括角色和权限
* @param principalCollection 主体标识集合,用于获取用户信息
* @return AuthorizationInfo 授权信息对象,包含用户的角色和权限*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
// 输出日志,表明开始授权
System.out.println("进入了授权");
// 获取用户信息
SysUser sysUser = (SysUser) principalCollection.getPrimaryPrincipal();
// 创建一个简单的授权信息对象
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// 如果用户的角色不为空,则添加角色到授权信息中
if (sysUser.getRole() != null) {
info.addRole(sysUser.getRole().getRoleName());
// 获取用户角色的权限列表
List<SysRight> rights = sysUser.getRole().getRights();
// 如果权限列表不为空,则遍历权限列表,添加权限到授权信息中
if (rights != null && rights.size() > 0) {
for (SysRight sysRight : rights) {
// 输出日志,显示权限代码
System.out.println("权限:" + sysRight.getRightCode());
// 添加权限到授权信息中
info.addStringPermission(sysRight.getRightCode());
}
}
}
// 返回授权信息对象
return info;
}
/*** 认证方法
* 该方法用于验证用户身份,通过用户名和密码检查用户是否合法
* @param authenticationToken 认证令牌,包含用户提交的用户名和密码
* @return AuthenticationInfo对象,包含用户信息和密码等数据
* @throws AuthenticationException 如果认证失败,抛出此异常*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
// 输出日志,表示进入认证流程
System.out.println("进入了认证");
// 将认证令牌转换为用户名密码令牌
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
// 调用sysUserService的login方法,根据用户名获取用户信息
SysUser login = sysUserService.login(token.getUsername());
// 如果用户信息为null,抛出认证异常,表示认证失败
if (login == null) {
throw new AuthenticationException("认证失败");
}
// 创建SimpleAuthenticationInfo对象,用于存储认证信息
// 参数分别为:用户信息、密码、盐值、领域名称
SimpleAuthenticationInfo info =
new SimpleAuthenticationInfo(login, login.getUsrPassword(),
ByteSource.Util.bytes("mym"), getName());
// 返回认证信息
return info;
}
}
测试类测试
测试类代码
@SpringBootTest
public class Shiro2ApplicationTests {
@Autowired
ISysUserService sysUserService;
@Autowired
ISysRoleService sysRoleService;
@Test
public void contextLoads() {
SysUser login = sysUserService.login("admin");
SysRole rightsByRole = sysRoleService.find(login.getUsrRoleId());
login.setRole(rightsByRole);
System.out.println(login.getRole());
}
}
Controller类
controller使用代码
/** 处理用户登录请求
* @param session HttpSession对象,用于存储用户登录信息
* @param usrName 用户名
* @param usrPassword 密码
* @param model Model对象,用于传递消息
* @return 登录成功则重定向到主页面,失败则返回登录页面*/
@RequestMapping("/dologin")
public String doLogin(HttpSession session, String usrName, String usrPassword, Model model) {
try {
// 获取当前用户主体
Subject subject = SecurityUtils.getSubject();
// 创建用户名和密码令牌
UsernamePasswordToken token = new UsernamePasswordToken(usrName, usrPassword);
// 执行登录操作
subject.login(token);
// 获取登录成功的用户信息
SysUser sysUser = (SysUser) subject.getPrincipal();
// 根据用户角色ID获取角色信息
SysRole sysRole = sysRoleService.find(sysUser.getSysRole().getRoleId());
// 更新用户的角色信息
sysUser.setSysRole(sysRole);
// 将用户信息存储到会话中
session.setAttribute("loginUser", sysUser);
// 登录成功,重定向到主页面
return "redirect:/main";
} catch (IncorrectCredentialsException e) {
// 捕获密码错误异常
model.addAttribute("msg", "密码错误");
} catch (AuthenticationException e) {
// 捕获用户认证失败异常
model.addAttribute("msg", "用户不存在");
}
// 登录失败,返回登录页面
return "login";
}
controller里面的find方法
mapper:
mapper.xml:
resultMap:
代码如下:
<!--定义一个名为allMap的结果映射,用于将查询结果映射到SysRole类
type属性指定了映射的目标类是com.atguigu.shiro3.pojo.SysRole-->
<resultMap id="allMap" type="com.atguigu.shiro3.pojo.SysRole">
<!-- 定义SysRole类中roleId属性与数据库中role_id字段的映射关系
property属性指定SysRole类中的属性名
column属性指定数据库查询结果集中的列名-->
<id column="role_id" property="roleId"/>
<!-- 定义SysRole类中sysRight属性的映射关系,该属性是一个集合,包含多个SysRight对象
ofType属性指定了集合中元素的类型是com.atguigu.shiro3.pojo.SysRight-->
<collection property="sysRight" ofType="com.atguigu.shiro3.pojo.SysRight">
<!--定义SysRight类中rightCode属性与数据库中rf_right_code字段的映射关系
同样,property属性指定SysRight类中的属性名
column属性指定数据库查询结果集中的列名-->
<id column="rf_right_code" property="rightCode"/>
</collection>
</resultMap>
service:
serviceImpl:
标签:map,return,用户,认证,new,授权,login,加密 From: https://blog.csdn.net/ou050719/article/details/143619066