这里写自定义目录标题
Shiro整合SpringBoot
Shiro以及SpringBoot环境配置
maven环境配置
<!--web启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--thymeleaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1.tmp</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<! --jdbc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
实体类的创建
User类的创建
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
*
* </p>
*
* @author jobob
* @since 2020-01-29
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("sys_user")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private String name;
private String loginname;
private String address;
private Integer sex;
private String remark;
private String pwd;
private Integer deptid;
private Date hiredate;
private Integer mgr;
private Integer available;
private Integer ordernum;
/**
* 用户类型[0超级管理员1,管理员,2普通用户]
*/
private Integer type;
/**
* 头像地址
*/
private String imgpath;
private String salt;
}
UserVo的创建
解释一下Vo
对实体类的二次封装,封装了一些对改类的额外属性,继承与User模块
UserVo代码块
import com.victoria.Warehouse.sys.pojo.User;
public class UserVo extends User {
}
SpringBoot的配置
application.properties中的配置
spring.resources.static-locations=classpath:/templates/,classpath:/static/
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/0520erp?useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
application.yml中的配置
#shiro的配置
shiro:
#密码加密方式
hash-algorithm-name: md5
#散列次数
hash-iterations: 2
#没有认证钱能访问的资源路径
anon-urls:
- /index.html*
- /sys/login*
- /login/login*
- /resources/**
#登录成功后的路径
login-url: /index.html
#退出后的路径
log-out-url: /login/logout*
#拦截路径
authc-ulrs:
- /**
配置合并
application.properties中的配置可以移到application.yml中,最好移到yml文件中,SpringBoot会最先加载yml文件
Shiro的配置
ShiroConfig文件
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import com.victoria.Warehouse.sys.realm.UserRealm;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.DelegatingFilterProxy;
import lombok.Data;
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(value = { SecurityManager.class })
@ConfigurationProperties(prefix = "shiro")
@Data
public class shiroConfig {
private static final String SHIRO_DIALECT = "shiroDialect";
private static final String SHIRO_FILTER = "shiroFilter";
private String hashAlgorithmName = "md5";// 加密方式
private int hashIterations = 2;// 散列次数
private String loginUrl = "/index.html";// 默认的登陆页面
private String[] anonUrls;
private String logOutUrl;
private String[] authcUlrs;
/**
* 声明凭证匹配器
*/
@Bean("credentialsMatcher")
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
credentialsMatcher.setHashAlgorithmName(hashAlgorithmName);
credentialsMatcher.setHashIterations(hashIterations);
return credentialsMatcher;
}
/**
* 声明userRealm
*/
@Bean("userRealm")
public UserRealm userRealm(CredentialsMatcher credentialsMatcher) {
UserRealm userRealm = new UserRealm();
// 注入凭证匹配器
userRealm.setCredentialsMatcher(credentialsMatcher);
return userRealm;
}
/**
* 配置SecurityManager
*/
@Bean("securityManager")
public SecurityManager securityManager(UserRealm userRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 注入userRealm
securityManager.setRealm(userRealm);
return securityManager;
}
/**
* 配置shiro的过滤器
*/
@Bean(SHIRO_FILTER)
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
// 设置安全管理器
factoryBean.setSecurityManager(securityManager);
// 设置未登陆的时要跳转的页面
factoryBean.setLoginUrl(loginUrl);
Map<String, String> filterChainDefinitionMap = new HashMap<>();
// 设置放行的路径
if (anonUrls != null && anonUrls.length > 0) {
for (String anon : anonUrls) {
filterChainDefinitionMap.put(anon, "anon");
}
}
// 设置登出的路径
if (null != logOutUrl) {
filterChainDefinitionMap.put(logOutUrl, "logout");
}
// 设置拦截的路径
if (authcUlrs != null && authcUlrs.length > 0) {
for (String authc : authcUlrs) {
filterChainDefinitionMap.put(authc, "authc");
}
}
Map<String, Filter> filters=new HashMap<>();
// filters.put("authc", new ShiroLoginFilter());
//配置过滤器
factoryBean.setFilters(filters);
factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return factoryBean;
}
/**
* 注册shiro的委托过滤器,相当于之前在web.xml里面配置的
*
* @return
*/
@Bean
public FilterRegistrationBean<DelegatingFilterProxy> delegatingFilterProxy() {
FilterRegistrationBean<DelegatingFilterProxy> filterRegistrationBean = new FilterRegistrationBean<DelegatingFilterProxy>();
DelegatingFilterProxy proxy = new DelegatingFilterProxy();
proxy.setTargetFilterLifecycle(true);
proxy.setTargetBeanName(SHIRO_FILTER);
filterRegistrationBean.setFilter(proxy);
return filterRegistrationBean;
}
/* 加入注解的使用,不加入这个注解不生效--开始 */
/**
*
* @param securityManager
* @return
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
@Bean
public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
advisorAutoProxyCreator.setProxyTargetClass(true);
return advisorAutoProxyCreator;
}
/* 加入注解的使用,不加入这个注解不生效--结束 */
}
UserRealm.java文件
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.victoria.Warehouse.sys.pojo.User;
import com.victoria.Warehouse.sys.service.IUserService;
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;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
public class UserRealm extends AuthorizingRealm {
@Autowired
private IUserService iUserService;
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//获取用户名
String loginname = authenticationToken.getPrincipal().toString();
//条件
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq(StringUtils.isNotBlank(loginname),"loginname",loginname);
//查询出来的user对象
User user = iUserService.getOne(queryWrapper);
//盐的创建
ByteSource salt = ByteSource.Util.bytes(user.getSalt());
/*
* SimpleAuthenticationInfo可以有三个参数或者四个参数
* 三个参数:
* 1.第一个是对象,可以供授权使用的对象
* 2.user.pwd,根据用户名查询到的密码,判断密码是否相等用
* 3.realm名
* 四个参数:
* 1.第一个是对象,可以供授权使用的对象
* 2.user.pwd,根据用户名查询到的密码,判断密码是否相等用
* 3.盐
* 4.realm名
* */
AuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPwd(),salt,this.getName());
//返回给调用者,是否成功
return info;
}
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
}
Controller文件
import com.victoria.Warehouse.sys.vo.UserVo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/login")
@RestController
public class LoginController {
@RequestMapping("login")
public void login(UserVo userVo){
//创建一个subject对象
Subject subject = SecurityUtils.getSubject();
// 把用户名和密码封装为 UsernamePasswordToken 对象
AuthenticationToken token = new UsernamePasswordToken(userVo.getLoginname(),userVo.getPwd());
try {
//进行登录认证
subject.login(token);
} catch (AuthenticationException e) {
System.out.println("用户名或者密码错误");
}
}
}