这篇是大体就是做整合shiro,在登陆的时候加入一些校验和拦截,
顺便把信息设置做出来,上篇篇幅太长就没把info.html写出来,
上篇中有部分使用Element UI ,下拉是select,之前使用Layui,
但是展示有问题,无奈采用Element的el-select,还有新增和修改的详情窗口,也是采用Element ui
只是大概的描述了一下其中的流程,一些细节没有画出来,如果刚学shiro,
或者没学shiro,可以看一下这篇潮汐先生的一篇适合小白的Shiro教程
templates文件夹下新增info.html文件
基本资料js我的资料![]()
js文件夹下新建info.js
// 基本资料
var vm = new Vue({
el:"#app",
data:{
user:{
niceName:null,
username:null,
password:null,
sex:"",
avatar:""
}
},
mounted(){
axios({
url:"sysUser/setting",
methods: "get"
}).then(res => {
vm.user = res.data.data;
vm.user.sex = vm.user.sex.toString();
});
},
methods:{
success(res,file){
vm.user.avatar = res.data;
},
reload(){
vm.user={
niceName:null,
username:null,
password:null,
sex:"0",
avatar:""
}
},
//保存或者更新
saveOrUpdate(){
axios({
url:"sysUser/update",
method: "post",
headers:{
"Content-Type": "application/json"
},
data:JSON.stringify(vm.user)
}).then(res =>{
console.log(res);
});
},
}
});
添加新接口
上一篇ifame中写了info.html只不过没有添加这个html文件
sysUserController 新增setting接口
id暂时设置为1,整合完之后会直接从shiro中获取用户id的
@GetMapping("setting")
public Result setting(){
UserEntity userEntity = userService.getById(1);
return Result.success(userEntity);
}
启动看一下结果,没啥问题,目前登陆的账号昵称和头像都是写死的,之后全都会去做加载的!
pom.xml
新建文件夹和文件 CustomerByteSource1.5.3 org.apache.shiro shiro-spring-boot-starter ${shiro.version}
这个是序列化+盐值salt加密,这是一个坑,坑了我好久,不要用自带的ByteSource.Util.bytes
要不然在后面的整合redis中,从redis获取认证信息会异常,
import org.apache.shiro.codec.base64;
import org.apache.shiro.codec.CodecSupport;
import org.apache.shiro.codec.Hex;
import org.apache.shiro.util.ByteSource;
import java.io.File;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Arrays;
//自定义salt实现 实现序列化接口
public class CustomerByteSource implements ByteSource, Serializable {
private byte[] bytes;
private String cachedHex;
private String cachedbase64;
public CustomerByteSource() {
}
public CustomerByteSource(byte[] bytes) {
this.bytes = bytes;
}
public CustomerByteSource(char[] chars) {
this.bytes = CodecSupport.toBytes(chars);
}
public CustomerByteSource(String string) {
this.bytes = CodecSupport.toBytes(string);
}
public CustomerByteSource(ByteSource source) {
this.bytes = source.getBytes();
}
public CustomerByteSource(File file) {
this.bytes = (new BytesHelper()).getBytes(file);
}
public CustomerByteSource(InputStream stream) {
this.bytes = (new BytesHelper()).getBytes(stream);
}
public static boolean isCompatible(Object o) {
return o instanceof byte[] || o instanceof char[] || o instanceof String || o instanceof ByteSource || o instanceof File || o instanceof InputStream;
}
public byte[] getBytes() {
return this.bytes;
}
public boolean isEmpty() {
return this.bytes == null || this.bytes.length == 0;
}
public String toHex() {
if (this.cachedHex == null) {
this.cachedHex = Hex.encodeToString(this.getBytes());
}
return this.cachedHex;
}
public String tobase64() {
if (this.cachedbase64 == null) {
this.cachedbase64 = base64.encodeToString(this.getBytes());
}
return this.cachedbase64;
}
public String toString() {
return this.tobase64();
}
public int hashCode() {
return this.bytes != null && this.bytes.length != 0 ? Arrays.hashCode(this.bytes) : 0;
}
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (o instanceof ByteSource) {
ByteSource bs = (ByteSource) o;
return Arrays.equals(this.getBytes(), bs.getBytes());
} else {
return false;
}
}
private static final class BytesHelper extends CodecSupport {
private BytesHelper() {
}
public byte[] getBytes(File file) {
return this.toBytes(file);
}
public byte[] getBytes(InputStream stream) {
return this.toBytes(stream);
}
}
}
UserRealm
后面会写关于这两个的详细信息
import com.macro.entity.UserEntity;
import com.macro.service.UserService;
import org.apache.shiro.authc.*;
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 UserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("这里是授权");
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("这里是认证");
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
String username = token.getUsername();
UserEntity user = userService.findByUserName(username);
if(user == null){
throw new UnknownAccountException("账号或者密码错误");
}
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes("1234"), getName());
return info;
}
}
ShiroConfig
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
//Shiro的核心配置类,用来整合shiro框架
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//给filter设置安全管理器
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
//配置系统受限资源
//配置系统公共资源
Map map = new HashMap<>();
//无需权限访问
map.put("/statics
public class ShiroUtils {
public static UserEntity getUser(){
UserEntity user = (UserEntity) SecurityUtils.getSubject().getPrincipal();
return user;
}
public static Integer getUserId(){
UserEntity user = getUser();
return user.getId();
}
public static String getMdPassWord(String password){
Md5Hash md = new Md5Hash(password,"1234",1024);
return md.toHex();
}
public static void main(String[] args) {
System.out.println(getMdPassWord("123456"));
}
}
记得重新去生成一个密码,要不然登陆不上去的
改造sysUserController
只有两个方法需要改造,add和update以及setting,用户信息直接从Subject中获取的,不知道的这是啥的可以看看文章最上面推荐的一篇文章
@PostMapping("add")
public Result add(@RequestBody UserEntity user){
//新加,密码加密
user.setPassword(ShiroUtils.getMdPassWord(user.getPassword()));
boolean save = userService.save(user);
if(save){
return Result.success();
}
return Result.error("添加失败");
}
@PostMapping("update")
public Result update(@RequestBody UserEntity user){
//新加,密码加密
user.setPassword(ShiroUtils.getMdPassWord(user.getPassword()));
boolean type = userService.updateById(user);
return type ? Result.success() : Result.error("更新失败");
}
@GetMapping("setting")
public Result setting(){
//新改动,直接通过ShiroUtils.getUserId()获取用户id
UserEntity userEntity = userService.getById(ShiroUtils.getUserId());
return Result.success(userEntity);
}
启动测试一下,密码错误提示和个人信息,都是正常的
在index.html引入axios.js前面忘了引入了
修改index.html中名字和图片
{{niceName}}
只修改了这一小块
修改index.html中js部分
var vm = new Vue({
el: '#rapp',
data: {
main:"./main.html",
val:"",
niceName:"",
avatar:""
},
mounted(){
this.info();
},
methods:{
info() {
axios({
url: "sysUser/setting",
methods: "get"
}).then(res => {
vm.niceName = res.data.data.niceName;
vm.avatar = res.data.data.avatar;
});
},
logout(){
window.location = "/logout"
}
},
update:function(){
console.log("###");
}
});
这几块都是他添加部分
效果如下,没啥问题:
在公众号内发送后台即可获取源码和数据库



