进销存系统_SpringSecurity权限框架&登录&用户密码加密&退出
Posted 上善若水
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进销存系统_SpringSecurity权限框架&登录&用户密码加密&退出相关的知识,希望对你有一定的参考价值。
一、引入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();
@Override
public 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();
@Override
public 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 {
@Autowired
private JxcAuthenticationSuccessHandler jxcAuthenticationSuccessHandler;
@Autowired
private JxcAuthenticationFailedHandler jxcAuthenticationFailedHandler;
@Resource
private IUserService userService;
/**
* 放行静态资源
* @param web
* @throws Exception
*/
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(
"/images/**",
"/css/**",
"/js/**",
"/lib/**",
"/error/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// 禁用csrf
http.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();
}
@Bean
protected UserDetailsService userDetailsService() {
return new UserDetailsService() {
@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
// 根据用户名查询用户记录
User userDetails = userService.findUserByUserName(userName);
return userDetails;
}
};
}
/**
* 配置 SpringSecurity 密码加密 Bean对象
* @return
*/
@Bean
public 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;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.authorities;
}
@Override
public String getUsername() {
return userName;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public 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")
@ResponseBody
public 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 {
@Resource
private PasswordEncoder passwordEncoder;
@Override
public 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.进销存系统_系统权限管理-用户&角色管理
项目一众筹网07_01_SpringSecurity框架简介和用法SpringSecurity负责的是 权限验证Spring的注解模式maven引入Spring环境加入layUI环境