SpringBoot整合shiro安全框架

1.SpringBoot整合shiro框架前后端分离

创建好springboot项目引入需引入一下依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.75</version>
</dependency>
<!--shiro和springboot整合的依赖-->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring-boot-starter</artifactId>
    <version>1.7.0</version>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.3.2</version>
</dependency>

1.1创建springboot工程

1.2导入数据库

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `userid` int(0) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL,
  `userpwd` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL,
  `sex` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL,
  `address` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL,
  `salt` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`userid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, 'zhangsan', '4b05a8716a430f71c6911d2e9149092f', '男', '武汉', '07f63bbf285e4719bfee1cc2bb81db33');
INSERT INTO `user` VALUES (2, 'lisi', '99cc11855b41ff3e5f7c0af3c5090a8c', '女', '北京', '2d7e37f019144764ac02aa7220929f93');
INSERT INTO `user` VALUES (3, 'wangwu', '6d70c027801af4dc892ab340d4bf73b6', '女', '成都', '99f6bf1b540145699e6e5c90480105b0');

1.3Application配置文件

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/shiro?serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root

mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
mybatis-plus.mapper-locations=classpath:/mapper/*.xml


#?????
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html


#??shiro?????
shiro.hashAlgorithmName=MD5
shiro.hashIterations=1024
shiro.map[/login]=anon
shiro.map[/doc.html]=anon
shiro.map[/webjars/**]=anon
shiro.map[/swagger-resources]=anon
shiro.map[/v2/**]=anon
shiro.map[/**]=authc

1.4编写配置文件

package com.aaa.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.aaa.filter.LoginFilter;
import com.aaa.realm.MyRealm;
import com.aaa.vo.ShiroProperties;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisManager;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
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;

@Configuration
@EnableConfigurationProperties(ShiroProperties.class)
public class MyConfig {
    private ShiroProperties shiroProperties;
    //有参构造
    public MyConfig(ShiroProperties shiroProperties) {
        this.shiroProperties = shiroProperties;
    }

    @Bean
    public DefaultWebSecurityManager securityManager(){
        DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
        securityManager.setRealm(myRealm());
        
        return securityManager;
    }
    

    @Bean
    public MyRealm myRealm(){
        MyRealm myRealm=new MyRealm();
        //设置密码加密器
        myRealm.setCredentialsMatcher(credentialsMatcher());
        return myRealm;
    }

   
    @Bean
    public HashedCredentialsMatcher credentialsMatcher(){
        HashedCredentialsMatcher credentialsMatcher=new HashedCredentialsMatcher();
        credentialsMatcher.setHashAlgorithmName(shiroProperties.getHashAlgorithmName());
        credentialsMatcher.setHashIterations(shiroProperties.getHashIterations());
        return credentialsMatcher;
    }

    
    @Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean factoryBean(){
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager());
        shiroFilterFactoryBean.setLoginUrl(shiroProperties.getLoginUrl());
     
        shiroFilterFactoryBean.setFilterChainDefinitionMap(shiroProperties.getMap());
        //自定义过滤
        LoginFilter loginFilter = new LoginFilter();
        Map<String,Filter> filterMap = new HashMap<>();
        filterMap.put("authc",loginFilter);
        shiroFilterFactoryBean.setFilters(filterMap);

        return shiroFilterFactoryBean;
    }

    //springboot如何注册web三大组件。
    @Bean
    public FilterRegistrationBean<Filter> filterRegistrationBean(){
        FilterRegistrationBean<Filter> filterRegistrationBean=new FilterRegistrationBean<>();
        filterRegistrationBean.setFilter(new DelegatingFilterProxy());
        filterRegistrationBean.setName("shiroFilter");
        filterRegistrationBean.addUrlPatterns("/*");
        return filterRegistrationBean;
    }
 

}
// 对应的ShiroProperties类

package com.aaa.vo;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.util.Map;

@Data
@ConfigurationProperties(prefix = "shiro")
public class ShiroProperties {
    private String hashAlgorithmName;
    private int hashIterations;
    private String loginUrl;
    private Map<String,String> map;
}

 1.5编写Realm类(shiro认证)

package com.aaa.realm;

import com.aaa.entity.User;
import com.aaa.service.PermissionService;
import com.aaa.service.UserService;
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.authz.SimpleAuthorizationInfo;
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;
import org.springframework.cache.annotation.Cacheable;

import javax.annotation.Resource;
import java.util.List;

public class MyRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService;
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String username = authenticationToken.getPrincipal().toString();
        User user = userService.findByUsername(username);
        if (user!=null){
            ByteSource byteSource = ByteSource.Util.bytes(user.getSalt());
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getUserpwd(),byteSource,this.getName());
            return info;
        }
        return null;
    }
}

1.6 entity+dao+service+serviceImpl

package com.aaa.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;

@Data
public class User {
    @TableId(type = IdType.AUTO)
    private Integer userid;
    private String username;
    private String userpwd;
    private String sex;
    private String address;
    private String salt;

}
package com.aaa.dao;

import com.aaa.entity.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

public interface UserDao extends BaseMapper<User> {
}
package com.aaa.service;

import com.aaa.entity.User;

public interface UserService {
    User findByUsername(String username);
}
package com.aaa.service.impl;

import com.aaa.dao.UserDao;
import com.aaa.entity.User;
import com.aaa.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class UserServiceImpl implements UserService {
    @Resource
    private UserDao userDao;
    @Override
    public User findByUsername(String username) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username",username);
        User user = userDao.selectOne(wrapper);
        return user;
    }
}

1.7controller登录代码

package com.aaa.controller;

import com.aaa.vo.LoginVo;
import com.aaa.vo.Result;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class LoginController {
    @PostMapping("/login")
    @ResponseBody
    public Result login(LoginVo loginVo){
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(loginVo.getUsername(), loginVo.getPassword());
        try{
            subject.login(token);
            System.out.println("登陆成功");
            return new Result(200,"登陆成功",null);
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("登录失败");
            return new Result(500,"登陆失败",null);
        }

    }
}

result返回结果类

package com.aaa.vo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Result {
    private Integer code;
    private String msg;
    private Object data;
}

loginVo

package com.aaa.vo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class LoginVo {
    private String username;
    private String password;
}

1.8自定义过滤器

package com.aaa.filter;

import com.aaa.vo.Result;
import com.alibaba.fastjson.JSON;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.PrintWriter;

public class LoginFilter extends FormAuthenticationFilter {
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        response.setContentType("application/json;charset=utf-8");
        PrintWriter writer = response.getWriter();
        Result result = new Result(401, "请登录", null);
        String s = JSON.toJSONString(result);
        writer.write(s);
        writer.flush();
        writer.close();
        return false;
    }
}

1.9前端页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
</head>
<body>
<form action="/login" method="post">
    账号:<input type="text" name="username"/><br><br>
    密码:<input type="text" name="password"/><br><br>
    <input type="submit" value="登录"/>
</form>
</body>
</html>

注:

@MapperScan(basePackages = "com.xxx.dao") 包扫描要加入入口函数所在的主类中
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值