进销存系统

编程入门 行业动态 更新时间:2024-10-09 09:15:40

<a href=https://www.elefans.com/category/jswz/34/1717723.html style=进销存系统"/>

进销存系统

代码地址:.git

一、引入SpringSecurity权限框架

为了快速方便实现进销存系统权限管理功能,系统引入SpringSecurity框架对应用权限进行统一控制。

1.1、使用SpringSecurity完成用户登录认证

1.1.1、jxc-admin pom.xml引入SpringSecurity坐标

        <!--spring security 组件--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>

1.1.2、JxcAuthenticationSuccessHandler.java

package com.xbmu.admin.config.security;import com.fasterxml.jackson.databind.ObjectMapper;
import com.xbmu.admin.model.RespBean;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** 认证成功处理器** @author bitaotao* @since 2021-09-12*/
@Component
public class JxcAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {private static ObjectMapper objectMapper = new ObjectMapper();@Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {response.setContentType("application/json;charset=UTF-8");response.getWriter().write(objectMapper.writeValueAsString(RespBean.success("登录成功")));}
}

1.1.3、JxcAuthenticationFailedHandler.java

package com.xbmu.admin.config.security;import com.fasterxml.jackson.databind.ObjectMapper;
import com.xbmu.admin.model.RespBean;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/**** 认证失败处理器* @author bitaotao* @since 2021-09-12*/
@Component
public class JxcAuthenticationFailedHandler extends SimpleUrlAuthenticationFailureHandler {private static ObjectMapper objectMapper = new ObjectMapper();@Overridepublic void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {response.setContentType("application/json;charset=UTF-8");response.getWriter().write(objectMapper.writeValueAsString(RespBean.error("用户名或密码错误")));}
}

1.1.4、SpringSecurity配置类 SecurityConfig.java

package com.xbmu.admin.config.security;import com.xbmu.admin.pojo.User;
import com.xbmu.admin.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;import javax.annotation.Resource;/*** SpringSecurity配置类* @author bitaotao* @since 2021-09-12*/
@SpringBootConfiguration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate JxcAuthenticationSuccessHandler jxcAuthenticationSuccessHandler;@Autowiredprivate JxcAuthenticationFailedHandler jxcAuthenticationFailedHandler;@Resourceprivate IUserService userService;/*** 放行静态资源* @param web* @throws Exception*/@Overridepublic void configure(WebSecurity web) throws Exception {web.ignoring().antMatchers("/images/**","/css/**","/js/**","/lib/**","/error/**");}@Overrideprotected void configure(HttpSecurity http) throws Exception {// 禁用csrfhttp.csrf().disable()// 允许frame 页面嵌套.headers().frameOptions().disable().and().formLogin().usernameParameter("userName").passwordParameter("passWord").loginPage("/index").loginProcessingUrl("/login").successHandler(jxcAuthenticationSuccessHandler).failureHandler(jxcAuthenticationFailedHandler).and().authorizeRequests().antMatchers("/index","/login").permitAll().anyRequest().authenticated();}@Beanprotected UserDetailsService userDetailsService() {return new UserDetailsService() {@Overridepublic UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {// 根据用户名查询用户记录User userDetails = userService.findUserByUserName(userName);return userDetails;}};}/*** 配置 SpringSecurity 密码加密 Bean对象* @return*/@Beanpublic PasswordEncoder encoder(){return new BCryptPasswordEncoder();}/*** 配置认证Service接口与密码加密实现类* @param auth* @throws Exception*/protected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService()).passwordEncoder(encoder());}
}

1.1.5、User.java

package com.xbmu.admin.pojo;import com.baomidou.mybatisplus.annotation.TableField;
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.Collection;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;/*** <p>* 用户表* </p>** @author bitaotao* @since 2021-09-11*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("t_user")
@ApiModel(value="User对象", description="用户表")
public class User implements Serializable, UserDetails {private static final long serialVersionUID = 1L;@ApiModelProperty(value = "主键id")@TableId(value = "id", type = IdType.AUTO)private Integer id;@ApiModelProperty(value = "备注名")private String bz;@ApiModelProperty(value = "密码")private String password;@ApiModelProperty(value = "真实姓名")private String trueName;@ApiModelProperty(value = "用户名")private String userName;@ApiModelProperty(value = "备注")private String remarks;@ApiModelProperty(value = "是否删除")private Integer isDel;@TableField(exist = false)Collection<? extends GrantedAuthority> authorities;@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {return this.authorities;}@Overridepublic String getUsername() {return userName;}@Overridepublic boolean isAccountNonExpired() {return true;}@Overridepublic boolean isAccountNonLocked() {return true;}@Overridepublic boolean isCredentialsNonExpired() {return true;}@Overridepublic boolean isEnabled() {return true;}
}

1.1.6、UserController.java

删除UserController类中的login方法,引入了SpringSecurity框架,采用了SpringSecurity框架中的login方法。

1.1.7、UserServiceImpl.java

将该类中 user.getUserName()代码 修改为 user.getUsername()。因为user类实现了org.springframework.security.core.userdetails.UserDetails接口,所有就采用UserDetails接口中的方法。

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package org.springframework.security.core.userdetails;import java.io.Serializable;
import java.util.Collection;
import org.springframework.security.core.GrantedAuthority;public interface UserDetails extends Serializable {Collection<? extends GrantedAuthority> getAuthorities();String getPassword();String getUsername();boolean isAccountNonExpired();boolean isAccountNonLocked();boolean isCredentialsNonExpired();boolean isEnabled();
}

1.1.8、测试

登录后,没有进入首页,而是又回到了登录页面。这是因为之前写的非法访问控制起了作用。

解决方法:删除非法访问控制代码(拦截器)。

<a href="javascript:;">${(Session.SPRING_SECURITY_CONTEXT.authentication.principal.username)!''}</a>


1.2、用户密码加密

1.2.1、密码修改对明文密码加密处理

使用SpringSecurity框架实现用户登录时,主要通过PasswordEncoder接口实现用户密码加密处理,核心实现类BCryptPasswordEncoder常用方法:

方法名描述
String encode(CharSequence rawPassword)字符串序列加密
boolean matches(CharSequence rawPassword, String encodedPassword)密码匹配,参数1为明文密码,参数2为加密密码,匹配成功返回true,反之false

1.2.2、删除自定义的login方法

删除UserServiceImpl.java、IUserService.java类中的login方法

1.2.3、UserController.java

修改UserController类中updateUserPassword方法

   /*** 用户密码更新* @param principal principal对象* @param oldPassword 旧密码* @param newPassword 新密码* @param confirmPassword 确认密码* @return*/@RequestMapping("updateUserPassword")@ResponseBodypublic RespBean updateUserPassword(Principal principal, String oldPassword, String newPassword, String confirmPassword){userService.updateUserPassword(principal.getName(),oldPassword,newPassword,confirmPassword);return RespBean.success("用户密码更新成功!");}

1.2.4、UserServiceImpl.java

package com.xbmu.admin.service.impl;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xbmu.admin.pojo.User;
import com.xbmu.admin.mapper.UserMapper;
import com.xbmu.admin.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xbmu.admin.util.AssertUtil;
import com.xbmu.admin.util.StringUtil;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;import javax.annotation.Resource;/*** <p>* 用户表 服务实现类* </p>** @author bitaotao* @since 2021-09-11*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {@Resourceprivate PasswordEncoder passwordEncoder;@Overridepublic User findUserByUserName(String userName) {return this.baseMapper.selectOne(new QueryWrapper<User>().eq("is_del",0).eq("user_name",userName));}@Override@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)public void updateUserInfo(User user) {/*** 用户名:非空、唯一*/AssertUtil.isTrue(StringUtil.isEmpty(user.getUsername()),"用户名不能为空!");User tempUser = this.findUserByUserName(user.getUsername());AssertUtil.isTrue(null != tempUser && !(tempUser.getId().equals(user.getId())),"用户名已存在!");AssertUtil.isTrue(!(this.updateById(user)),"用户信息更新失败!");}@Override@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)public void updateUserPassword(String userName, String oldPassword, String newPassword, String confirmPassword) {/*** 用户名非空 必须存在* 原始密码 新密码 确认密码 均不能为空* 原始密码必须正确* 新密码 与 确认密码必须一致  并且不能与原始密码相同*/User user = this.findUserByUserName(userName);AssertUtil.isTrue(null==user,"用户不存在或未登录!");AssertUtil.isTrue(StringUtil.isEmpty(oldPassword),"请输入原始密码!");AssertUtil.isTrue(StringUtil.isEmpty(newPassword),"请输入新密码!");AssertUtil.isTrue(StringUtil.isEmpty(confirmPassword),"请输入确认密码!");AssertUtil.isTrue(!(passwordEncoder.matches(oldPassword,user.getPassword())),"原始密码输入错误!");AssertUtil.isTrue(!(newPassword.equals(confirmPassword)),"新密码输入不一致!");AssertUtil.isTrue(newPassword.equals(oldPassword),"新密码与原始密码不能一致!");user.setPassword(passwordEncoder.encode(newPassword));AssertUtil.isTrue(!this.updateById(user),"用户密码更新失败!");}
}

1.3、系统退出代码优化

1.3.1、JxcLogoutSuccessHandler.java

package com.xbmu.admin.config.security;import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** 退出成功处理器** @author bitaotao* @since 2021-09-12*/
@Component
public class JxcLogoutSuccessHandler implements LogoutSuccessHandler {@Overridepublic void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {response.sendRedirect(request.getContextPath()+"/index");}
}

1.3.2、SecurityConfig.java

引入了SpringSecurity框架,采用了SpringSecurity框架中的signout方法。

package com.xbmu.admin.config.security;import com.xbmu.admin.pojo.User;
import com.xbmu.admin.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;import javax.annotation.Resource;/*** SpringSecurity配置类* @author bitaotao* @since 2021-09-12*/
@SpringBootConfiguration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate JxcAuthenticationSuccessHandler jxcAuthenticationSuccessHandler;@Autowiredprivate JxcAuthenticationFailedHandler jxcAuthenticationFailedHandler;@Resourceprivate IUserService userService;@Resourceprivate JxcLogoutSuccessHandler jxcLogoutSuccessHandler;/*** 放行静态资源* @param web* @throws Exception*/@Overridepublic void configure(WebSecurity web) throws Exception {web.ignoring().antMatchers("/images/**","/css/**","/js/**","/lib/**","/error/**");}@Overrideprotected void configure(HttpSecurity http) throws Exception {// 禁用csrfhttp.csrf().disable()// 允许frame 页面嵌套.headers().frameOptions().disable().and().formLogin().usernameParameter("userName").passwordParameter("passWord").loginPage("/index").loginProcessingUrl("/login").successHandler(jxcAuthenticationSuccessHandler).failureHandler(jxcAuthenticationFailedHandler).and().logout().logoutUrl("/signout").deleteCookies("JSESSIONID").logoutSuccessHandler(jxcLogoutSuccessHandler).and().authorizeRequests().antMatchers("/index","/login").permitAll().anyRequest().authenticated();}@Beanprotected UserDetailsService userDetailsService() {return new UserDetailsService() {@Overridepublic UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {// 根据用户名查询用户记录User userDetails = userService.findUserByUserName(userName);return userDetails;}};}/*** 配置 SpringSecurity 密码加密 Bean对象* @return*/@Beanpublic PasswordEncoder encoder(){return new BCryptPasswordEncoder();}/*** 配置认证Service接口与密码加密实现类* @param auth* @throws Exception*/protected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService()).passwordEncoder(encoder());}
}

1.3.3、测试


退出后,会删除cookies信息。

更多推荐

进销存系统

本文发布于:2024-02-06 13:51:25,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1749670.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:进销存系统

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!