SpringBoot整合Shiro
步骤
1、导入shiro整合spring的包:
org.apache.shiro
shiro-spring
1.4.0
2、自定义类ShiroConfig,使用注解@Config修饰,在该配置类中注册Shiro的realm和securityManager对象为容器中的bean,并配置过滤器
@Configuration
public class ShiroConfig {
//shiroFilterFactoryBean
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
//设置安全管理器
bean.setSecurityManager(securityManager);
//添加shiro的内置过滤器
/*
anon:无需认证就可以访问
authc:必须认证才能访问
user:必须拥有 记住我功能才能用
perms:拥有对某个资源的权限才能访问
role:有用某个角色权限才能访问
**/
//拦截
LinkedHashMap<String, String> filterMap = new LinkedHashMap<>();
//授权,拦截/user/add ,必须有指定的权限user:add权限才能访问
filterMap.put("/user/add","perms[user:add]");
filterMap.put("/user/update","perms[user:update]");
//拦截/user/下的所有请求,并指定必须登录认证才能访问
filterMap.put("/user/*","authc");
bean.setFilterChainDefinitionMap(filterMap);
//设置登录页面,
bean.setLoginUrl("/toLogin");
//默认情况下,没有授权会跳转到错误页面Unauthorized:401 未授权,
bean.setUnauthorizedUrl("/noauth");//定制未授权跳转的请求页面
return bean;
}
//DefaultWebSecurityManager
@Bean(name="securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("realm") UserRealm realm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联UserRealm
securityManager.setRealm(realm);
return securityManager;
}
//创建realm对象,需要自定义1
@Bean(name="realm")
public UserRealm userRealm(){
return new UserRealm();
}
/*如果需要对密码进行散列算法和加盐验证,才需要配置该凭证Bean*/
// @Bean
// public HashedCredentialsMatcher credentialsMatcher(){
//
// HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
// credentialsMatcher.setHashAlgorithmName("md5");//散列算法
// credentialsMatcher.setHashIterations(2);//散列次数
// return credentialsMatcher;
// }
//ShiroDialect:用来整合shiro和thymeleaf,方言类,配置后可以在html页面使用shiro方言
@Bean
public ShiroDialect getShiroDialect(){
return new ShiroDialect();
}
}
3、配置自定义的Realm类,继承AuthorizingRealm类,并实现doGetAuthenticationInfo和doGetAuthorizationInfo方法:
public class UserRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了=》授权doGetAuthorizationInfo");
//验证密码正确后跳转到此处,
//创建授权类
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//拿到当前登录的对象
Subject subject = SecurityUtils.getSubject();
User currentUser = (User) subject.getPrincipal();//拿到User
info.addStringPermission(currentUser.getPermission());//添加验证
return info;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("执行了=》认证doGetAuthorizationInfo");
//控制器负责通过获取请求参数的username和password将其封装成token,
//UsernamePasswordToken token = new UsernamePasswordToken(username, password);
//获取当前的用户Subject subject = SecurityUtils.getSubject();
//使用subject的login方法传入token登录:subject.login(token),该方法会调用
//SecurityManager.login(this,token)将token传入到该认证方法。交给realm执行认证
UsernamePasswordToken userToken = (UsernamePasswordToken)token;
//用户名,密码,数据中取
User user = userService.queryUserByName(userToken.getUsername());
if (user==null){
return null;//实际会抛出异常UnknownAccountException用户名不存在
}
//将用户存放到session中,该session是shiro提供的,不是servlet的session
Subject subject = SecurityUtils.getSubject();
Session session = subject.getSession();
session.setAttribute("loginUser",user);
//密码认证,由shiro做
//根据用户名找到对应的正确密码,传入SimpleAuthenticationInfo中,SimpleAuthenticationInfo会自动
//将用户登录传来的token与创建实例时传入的password匹配
//可以使用多种散列算法方式加密:如:MD5、SHA加密后不可逆,但是只要密码相同,通过算法加密后的值一致,容易被破解
// 采用MD5盐值加密,即MD5加盐
//如果希望使用散列算法加密,需要4个参数:正确的验证主体。正确的密码,盐,当前realm名称,还需要配置一个凭证Bean:
// return new SimpleAuthenticationInfo(user,user.getPwd(), ByteSource.Util.bytes("addSalt"),this.getName());
//若不使用加密,只需要3个参数:正确的验证主体principal。正确的密码,当前realm名称
//传递参数principle后,就可以通过当前用户subject.getPrincipal()获取到用户实际主体user
return new SimpleAuthenticationInfo(user,user.getPwd(),this.getName());
}
}
4、Shiro整合Thymeleaf,导入依赖包:
```xml
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
5、在HTML页面导入命名空间:
xmlns:shiro=“http://www.thymeleaf.org/thymeleaf-extras-shiro”
然后就可以在页面使用标签判断用户的情况:
th:if="${session.loginUser==null}" 判断session中loginUser是否为空,如果为空,则不显示该标签,loginUser为自己添加shiro的session中的属性,为用户属性。
shiro:hasPermission=“user:add” 判断用户是否有user:add这个权限,如果没有则不显示该标签
shiro:hasRole=“xxxx” 判断是否有这个角色
在页面中直接
**整合springboot后:**
在用户注册操作或者登录操作时:对用户的密码进行加盐加密:
//通过如下代码对用户注册或登录的密码进行加盐加密,散列两次,并转换成字符串
Md5Hash md5Hash= New Md5Hash(String password,‘addSalt’,2);
String newPassword=md5Hash.toString();
则添加到数据当中的密码就是加密后的密码。