SpringBoot整合Spring Security实现登录、注册、密码加密 您所在的位置:网站首页 色达怎么坐车去稻城 SpringBoot整合Spring Security实现登录、注册、密码加密

SpringBoot整合Spring Security实现登录、注册、密码加密

2023-10-10 19:33| 来源: 网络整理| 查看: 265

一、创建数据库表 CREATE TABLE `sys_user` ( `user_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `nickname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `avatar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `sex` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `phone` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `email_verified` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `true_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `id_card` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `birthday` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `introduction` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `organization_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `state` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `deleted` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `create_time` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `update_time` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

注意的是,password之后使用BCryptPasswordEncoder加密,因此password字符长度必须大于60

二、UserEnrity层 package com.epwcloud.common.system.entity; import com.baomidou.mybatisplus.annotation.*; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import org.springframework.security.core.userdetails.UserDetails; import java.util.Date; import java.util.List; /** * Created by 谭月浩on 2021-11-21 16:10 */ @ApiModel(description = "用户") @TableName("sys_user") public class User implements UserDetails { @ApiModelProperty("用户id") @TableId(value = "user_id", type = IdType.AUTO) private Integer userId; @ApiModelProperty("账号") private String username; @ApiModelProperty("密码") private String password; @ApiModelProperty("昵称") private String nickname; @ApiModelProperty("头像") private String avatar; @ApiModelProperty("性别") private Integer sex; @ApiModelProperty("手机号") private String phone; @ApiModelProperty("邮箱") private String email; @ApiModelProperty("邮箱是否验证,0否,1是") private Integer emailVerified; @ApiModelProperty("真实姓名") private String trueName; @ApiModelProperty("身份证号") private String idCard; @ApiModelProperty("出生日期") private Date birthday; @ApiModelProperty("个人简介") private String introduction; @ApiModelProperty("机构id") private Integer organizationId; @ApiModelProperty("状态,0正常,1冻结") private Integer state; @ApiModelProperty("是否删除,0否,1是") @TableLogic private Integer deleted; @ApiModelProperty("注册时间") private Date createTime; @ApiModelProperty("修改时间") private Date updateTime; @ApiModelProperty("性别名称") @TableField(exist = false) private String sexName; @ApiModelProperty("机构名称") @TableField(exist = false) private String organizationName; @ApiModelProperty("角色id") @TableField(exist = false) private List roleIds; @ApiModelProperty("角色列表") @TableField(exist = false) private List roles; @ApiModelProperty("权限列表") @TableField(exist = false) private List authorities; public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } public String getAvatar() { return avatar; } public void setAvatar(String avatar) { this.avatar = avatar; } public Integer getSex() { return sex; } public void setSex(Integer sex) { this.sex = sex; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Integer getEmailVerified() { return emailVerified; } public void setEmailVerified(Integer emailVerified) { this.emailVerified = emailVerified; } public String getTrueName() { return trueName; } public void setTrueName(String trueName) { this.trueName = trueName; } public String getIdCard() { return idCard; } public void setIdCard(String idCard) { this.idCard = idCard; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getIntroduction() { return introduction; } public void setIntroduction(String introduction) { this.introduction = introduction; } public Integer getOrganizationId() { return organizationId; } public void setOrganizationId(Integer organizationId) { this.organizationId = organizationId; } public Integer getState() { return state; } public void setState(Integer state) { this.state = state; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } public Date getUpdateTime() { return updateTime; } public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } public Integer getDeleted() { return deleted; } public void setDeleted(Integer deleted) { this.deleted = deleted; } public List getAuthorities() { return authorities; } public void setAuthorities(List authorities) { this.authorities = authorities; } public List getRoles() { return roles; } public void setRoles(List roles) { this.roles = roles; } public List getRoleIds() { return roleIds; } public void setRoleIds(List roleIds) { this.roleIds = roleIds; } public String getOrganizationName() { return organizationName; } public void setOrganizationName(String organizationName) { this.organizationName = organizationName; } public String getSexName() { return sexName; } public void setSexName(String sexName) { this.sexName = sexName; } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return state == 0; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } @Override public String toString() { return "User{" + ", userId=" + userId + ", username=" + username + ", password=" + password + ", nickname=" + nickname + ", avatar=" + avatar + ", sex=" + sex + ", phone=" + phone + ", email=" + email + ", emailVerified=" + emailVerified + ", trueName=" + trueName + ", idCard=" + idCard + ", birthday=" + birthday + ", introduction=" + introduction + ", organizationId=" + organizationId + ", state=" + state + ", createTime=" + createTime + ", updateTime=" + updateTime + ", deleted=" + deleted + ", organizationName=" + organizationName + "}"; } } 三、Controller层 public class UserController extends BaseController { @Autowired private UserService userService; @Autowired private MenuService menuService; @ApiOperation("用户登录") @ApiImplicitParams({ @ApiImplicitParam(name = "username", value = "账号", required = true, dataType = "string", paramType = "query"), @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "string", paramType = "query"), }) @PostMapping("/login") public void login(String username, String password) { // 登录操作由JwtLoginFilter完成 } @PreAuthorize("hasAuthority('sys:user:save')") @OperLog(value = "用户管理", desc = "添加", param = false, result = true) @ApiOperation("添加用户") @PostMapping() public JsonResult add(@RequestBody User user) { user.setState(0); user.setPassword(userService.encodePsw(user.getPassword())); if (userService.saveUser(user)) { return JsonResult.ok("添加成功"); } return JsonResult.error("添加失败"); } } 四、JwtLoginFilter、server、serverImpl层 package com.epwcloud.common.core.security; import com.alibaba.fastjson.JSON; import com.epwcloud.common.core.Constants; import com.epwcloud.common.core.web.JsonResult; import com.epwcloud.common.system.entity.LoginRecord; import com.epwcloud.common.system.service.LoginRecordService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.LockedException; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /** * 登录过滤器 * Created by 谭月浩 on 2021-11-21 12:57 */ public class JwtLoginFilter extends UsernamePasswordAuthenticationFilter { @Autowired private LoginRecordService loginRecordService; public JwtLoginFilter(AuthenticationManager authenticationManager) { super.setAuthenticationManager(authenticationManager); super.setFilterProcessesUrl("/api/login"); } /** * 登录成功签发token返回json数据 */ @Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException { UserDetails user = (UserDetails) authResult.getPrincipal(); String access_token = JwtUtil.buildToken(user.getUsername(), Constants.TOKEN_EXPIRE_TIME, Constants.TOKEN_KEY); // 记录登录日志 loginRecordService.saveAsync(user.getUsername(), LoginRecord.TYPE_LOGIN, null, request); // 返回json数据 response.setContentType("application/json;charset=UTF-8"); PrintWriter out = response.getWriter(); out.write(JSON.toJSONString(JsonResult.ok("登录成功").put("access_token", access_token) .put("token_type", JwtUtil.TOKEN_TYPE))); out.flush(); } /** * 登录失败处理 */ @Override protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException { String username = request.getParameter("username"); response.setContentType("application/json;charset=UTF-8"); PrintWriter out = response.getWriter(); JsonResult result; if (e instanceof UsernameNotFoundException) { result = JsonResult.error("账号不存在"); loginRecordService.saveAsync(username, LoginRecord.TYPE_ERROR, "账号不存在", request); } else if (e instanceof BadCredentialsException) { result = JsonResult.error("账号或密码错误"); loginRecordService.saveAsync(username, LoginRecord.TYPE_ERROR, "账号或密码错误", request); } else if (e instanceof LockedException) { result = JsonResult.error("账号被锁定"); loginRecordService.saveAsync(username, LoginRecord.TYPE_ERROR, "账号被锁定", request); } else { result = JsonResult.error(e.getMessage()); } out.write(JSON.toJSONString(result)); out.flush(); } } /** * 添加用户(包含角色) */ boolean saveUser(User user); /** * md5加密用户密码 */ String encodePsw(String psw); @Transactional @Override public boolean saveUser(User user) { if (user.getUsername() != null && baseMapper.selectCount(new QueryWrapper() .eq("username", user.getUsername())) > 0) { throw new BusinessException("账号已存在"); } if (user.getPhone() != null && baseMapper.selectCount(new QueryWrapper() .eq("phone", user.getPhone())) > 0) { throw new BusinessException("手机号已存在"); } if (user.getEmail() != null && baseMapper.selectCount(new QueryWrapper() .eq("email", user.getEmail())) > 0) { throw new BusinessException("邮箱已存在"); } boolean result = baseMapper.insert(user) > 0; if (result) { addUserRoles(user.getUserId(), user.getRoleIds(), false); } return result; } /** * 密码加密 */ @Override public String encodePsw(String psw) { if (psw == null) return null; return new BCryptPasswordEncoder().encode(psw); } 五、Mapper层、MapperXML层

此处用的是MybatisPlus,mabber继承了BaseMabber,所以基础的CURD不需要再写mabber

六、放行接口

登录页面JwtLoginFilter配置已经自动放行了,需要在SecurityConfig中放行/api/sys/user

@Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() .antMatchers(HttpMethod.GET, "/favicon.ico", "/api/file/**", "/", "/assets/**", "/**.html") .permitAll() .antMatchers("/api/login","/api/sys/user", "/error", "/druid/**", "/webjars/**", "/swagger-ui.html", "/swagger-resources/**", "/v3/api-docs","/doc.html").permitAll() .anyRequest().authenticated() .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and().headers().frameOptions().disable() .and().cors().and().csrf().disable(); http.exceptionHandling().accessDeniedHandler(jwtExceptionHandler()).authenticationEntryPoint(jwtExceptionHandler()); http.logout().logoutUrl("/logout").logoutSuccessHandler(jwtLogoutSuccessHandler()); http.addFilterBefore(jwtLoginFilter(), UsernamePasswordAuthenticationFilter.class); http.addFilterBefore(jwtRequestFilter(), UsernamePasswordAuthenticationFilter.class); }



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有