1.引入shiro综合嫁包
<!-- shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.7.0</version>
</dependency>
2.config配置
package com.sun.springboootshiro.config;
import com.sun.springboootshiro.realm.MyRealm;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
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 javax.servlet.Filter;
import java.util.HashMap;
import java.util.Map;
/**
* @program: springbooot-shiro
* @description: shiro的配置
* @author: 孙彦伟
* @create: 2021-07-05 14:32
**/
@Configuration
public class ShiroConfig {
//spring容器创建SecurityManager对象
@Bean
public DefaultWebSecurityManager securityManager(Realm realm){
//创建一个SecurityManager对象
DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
//自定义realm对象
securityManager.setRealm(realm);
return securityManager;
}
//自定义realm
@Bean
public Realm realm(CredentialsMatcher credentialsMatcher){
MyRealm myRealm=new MyRealm();
//设置密码匹配器
myRealm.setCredentialsMatcher(credentialsMatcher);
return myRealm;
}
//创建一个密码匹配器
@Bean
public CredentialsMatcher credentialsMatcher(){
HashedCredentialsMatcher credentialsMatcher=new HashedCredentialsMatcher();
//指定加密方式
credentialsMatcher.setHashAlgorithmName("MD5");
//加密的次数
credentialsMatcher.setHashIterations(1024);
return credentialsMatcher;
}
//创建shiro的过滤工厂
@Bean("shiroFilter")
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
//设置SecurityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);
//没有认证(登录)返回地址
shiroFilterFactoryBean.setLoginUrl("/login");
//没有授权返回地址
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
//anon---不登录就能访问---authc必须登录才可以访问
Map<String,String> map=new HashMap<>();
map.put("/login","anon");
map.put("/**","authc");
//拦截的路径
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
return shiroFilterFactoryBean;
}
//注入过滤器组件
@Bean
public FilterRegistrationBean<Filter> filter(){
FilterRegistrationBean registrationBean=new FilterRegistrationBean();
//要过滤的配置
registrationBean.setName("shiroFilter");
//路径
registrationBean.addUrlPatterns("/*");
//
registrationBean.setFilter(new DelegatingFilterProxy());
return registrationBean;
}
}
3.控制层
@RestController
//跨域
@CrossOrigin
public class LoginController {
//登录
@PostMapping("login")
public Result login(@RequestBody TabAccount tabAccount){
String username=tabAccount.getUsername();
String password=tabAccount.getPassword();
//那subject安全实用程序
Subject subject= SecurityUtils.getSubject();
//token传参
UsernamePasswordToken token=new UsernamePasswordToken(username,password);
try {
//自动调用realm认证
subject.login(token);
return new Result(200,"登录成功",null);
}catch (Exception e){
return new Result(400,"登陆失败",null);
}
}
// public static void main(String[] args) {
// Md5Hash md5Hash=new Md5Hash("admin","sun",1024);
// System.out.println(md5Hash);
// }
}
4.realm认证类
public class MyRealm extends AuthorizingRealm {
//
@Autowired
private AccountMapper accountMapper;
//AuthorizationInfo授权信息
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
//AuthenticationInfo认证信息
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//得到登录账号
String username=authenticationToken.getPrincipal().toString();
//根据账号查询用户信息
//查询条件‘
QueryWrapper<TabAccount> wrapper=new QueryWrapper<>();
wrapper.eq("username",username);
//查询结果
TabAccount tabAccount=accountMapper.selectOne(wrapper);
//如果查到
if (tabAccount!=null){
//获取盐
ByteSource byteSource=ByteSource.Util.bytes(tabAccount.getSalt());
//shiro自动进行密码对比-----
//shiro先把用户输入的密码按自己指定的盐进行加密
// 在与数据库查询出来的密码进行对比
SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(username,tabAccount.getPassword(),byteSource,this.getName());
return info;
}
//自动返回登录失败
return null;
}
}
实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("tab_account")
public class TabAccount {
private Long accountId;
private Long empId;
private String username;
private String password;
private Long accountState;
private String salt;
private Long operatorId;
private Date operatorTime;
}