搭建后台管理模块-完成认证操作

master
Administrator 1 year ago
parent 3f9ff8fcc1
commit 6dc95c02ea

@ -0,0 +1,15 @@
package com.mashibing.common.constant;
/**
* @author zjw
* @description
*/
public interface WebMasterConstants {
/**
* key
*/
String KAPTCHA = "kaptcha";
}

@ -25,7 +25,10 @@ public enum ExceptionEnums {
ONE_HOUR_LIMIT(-17,"1小时限流规则生效无法发送短信"),
NO_CHANNEL(-18,"没有选择到合适的通道!"),
SEARCH_INDEX_ERROR(-19,"添加文档信息失败!"),
SEARCH_UPDATE_ERROR(-20,"修改文档信息失败!")
SEARCH_UPDATE_ERROR(-20,"修改文档信息失败!"),
KAPACHA_ERROR(-100,"验证码错误!"),
AUTHEN_ERROR(-101,"用户名或密码错误!")
;
private Integer code;

@ -0,0 +1,34 @@
package com.mashibing.common.util;
import com.mashibing.common.enums.ExceptionEnums;
import com.mashibing.common.vo.ResultVO;
import javax.xml.transform.Result;
/**
* ResultVO
* @author zjw
* @description
*/
public class R {
/**
*
* @return
*/
public static ResultVO ok(){
return new ResultVO(0,"");
}
/**
*
* @param enums
* @return
*/
public static ResultVO error(ExceptionEnums enums){
return new ResultVO(enums.getCode(),enums.getMsg());
}
}

@ -0,0 +1,23 @@
package com.mashibing.common.vo;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
*
* @author zjw
* @description
*/
@Data
@NoArgsConstructor
public class ResultVO {
private Integer code;
private String msg;
public ResultVO(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
}

@ -16,11 +16,13 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- shiro认证授权-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.4.0</version>
</dependency>
<!-- 连接数据库-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
@ -36,10 +38,29 @@
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<!-- 测试依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- 生成验证码-->
<dependency>
<groupId>com.github.axet</groupId>
<artifactId>kaptcha</artifactId>
<version>0.0.9</version>
</dependency>
<!-- 引入公共模块-->
<dependency>
<groupId>com.mashibing</groupId>
<artifactId>beacon-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- SpringMVC的参数校验。-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.5.Final</version>
</dependency>
</dependencies>
<build>

@ -0,0 +1,33 @@
package com.mashibing.webmaster.config;
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
/**
*
* @author zjw
* @description
*/
@Configuration
public class KaptchaConfig {
@Bean
public DefaultKaptcha kaptcha(){
//1、直接构建DefaultKaptcha
DefaultKaptcha kaptcha = new DefaultKaptcha();
//2、设置配置信息
Properties properties = new Properties();
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH,"4");
Config config = new Config(properties);
kaptcha.setConfig(config);
//3、返回对象
return kaptcha;
}
}

@ -44,7 +44,9 @@ public class ShiroConfig {
//2、配置上过滤器链
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
// anon代表放行使用的是AnonymousFilter
filterChainDefinitionMap.put("/sys/user/login","anon");
filterChainDefinitionMap.put("/public/**","anon");
filterChainDefinitionMap.put("/captcha.jpg","anon");
filterChainDefinitionMap.put("/sys/login","anon");
filterChainDefinitionMap.put("/index.html","anon");
filterChainDefinitionMap.put("/login.html","anon");
filterChainDefinitionMap.put("/logout","logout");

@ -0,0 +1,50 @@
package com.mashibing.webmaster.controller;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.mashibing.common.constant.WebMasterConstants;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
/**
* @author zjw
* @description
*/
@Controller
public class KaptchaController {
private final String JPG = "jpg";
@Autowired
private DefaultKaptcha kaptcha;
@GetMapping("/captcha.jpg")
public void captcha(HttpServletResponse resp){
//1、验证码图片不需要做存储和缓存
resp.setHeader("Cache-Control","no-store, no-cahe");
//2、设置响应头信息
resp.setContentType("image/jpg");
//3、生成验证码文字
String text = kaptcha.createText();
// 认证需要验证验证码的准确性基于Shiro将text做存储
SecurityUtils.getSubject().getSession().setAttribute(WebMasterConstants.KAPTCHA,text);
//4、基于文字生成对应的图片
BufferedImage image = kaptcha.createImage(text);
//5、写回验证码图片信息
try {
ServletOutputStream outputStream = resp.getOutputStream();
ImageIO.write(image,JPG,outputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
}

@ -0,0 +1,62 @@
package com.mashibing.webmaster.controller;
import com.alibaba.druid.util.StringUtils;
import com.mashibing.common.constant.WebMasterConstants;
import com.mashibing.common.enums.ExceptionEnums;
import com.mashibing.common.util.R;
import com.mashibing.common.vo.ResultVO;
import com.mashibing.webmaster.dto.UserDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
/**
*
*
* @author zjw
* @description
*/
@RestController
@RequestMapping("/sys")
@Slf4j
public class SmsUserController {
@PostMapping("/login")
public ResultVO login(@RequestBody @Valid UserDTO userDTO, BindingResult bindingResult) {
// * 1、请求参数的非空校验
if (bindingResult.hasErrors()) {
// 参数不合法响应对应的JSON信息
log.info("【认证操作】参数不合法userDTO = {}", userDTO);
return R.error(ExceptionEnums.PARAMETER_ERROR);
}
// * 2、基于验证码校验请求是否合理
String realKaptcha = (String) SecurityUtils.getSubject().getSession().getAttribute(WebMasterConstants.KAPTCHA);
if (!userDTO.getCaptcha().equalsIgnoreCase(realKaptcha)) {
log.info("【认证操作】验证码不正确kapacha = {}realKaptcha = {}", userDTO.getCaptcha(), realKaptcha);
return R.error(ExceptionEnums.KAPACHA_ERROR);
}
// * 3、基于用户名和密码做Shiro的认证操作
UsernamePasswordToken token = new UsernamePasswordToken(userDTO.getUsername(),userDTO.getPassword());
token.setRememberMe(userDTO.getRememberMe());
try {
SecurityUtils.getSubject().login(token);
} catch (AuthenticationException e) {
// * 4、根据Shiro的认证返回响应信息
log.info("【认证操作】用户名或密码错误ex = {}", e.getMessage());
return R.error(ExceptionEnums.AUTHEN_ERROR);
}
// 到这,代表认证成功
return R.ok();
}
}

@ -0,0 +1,24 @@
package com.mashibing.webmaster.dto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* @author zjw
* @description
*/
@Data
public class UserDTO {
@NotBlank
private String username;
@NotBlank
private String password;
@NotBlank
private String captcha;
private Boolean rememberMe = false;
}

@ -50,7 +50,7 @@ public class ShiroRealm extends AuthorizingRealm {
SmsUser smsUser = userService.findByUsername(username);
//3、查询完毕后查看用户是否为null为null就直接返回即可
if(smsUser != null){
if(smsUser == null){
// 用户名错误
return null;
}

Loading…
Cancel
Save