引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- fastjson依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
package com.mydemo.springbootdocker.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 用户对象 sys_user
*
* @author deka
*/
@Data
public class SysUser implements Serializable {
private static final long serialVersionUID = 1L;
private String token;
/**
* 订单类型
*/
private String orderType;
/**
* 用户ID
*/
private Long userId;
/**
* 部门ID
*/
private Long deptId;
/**
* 客户名称
*/
private String customerName;
private String customerUuid;
/**
* 所属区域
*/
private String userRegion;
/**
* 用户账号
*/
private String userName;
/**
* 用户昵称
*/
private String nickName;
/**
* 用户身份
*/
private String userIdentity;
/**
* 用户类别
*/
private String userType;
/**
* 用户邮箱
*/
private String email;
/**
* 手机号码
*/
private String phonenumber;
/**
* 用户性别
*/
private String sex;
/**
* 用户头像
*/
private String avatar;
/**
* 密码
*/
private String password;
/**
* 盐加密
*/
private String salt;
/**
* 帐号状态(0正常 1停用)
*/
private String status;
/**
* 删除标志(0代表存在 2代表删除)
*/
private String delFlag;
/**
* 最后登录IP
*/
private String loginIp;
/**
* 最后登录时间
*/
private Date loginDate;
/**
* 角色组
*/
private Long[] roleIds;
/**
* 岗位组
*/
private Long[] postIds;
/**
* 所属客户UUID
*/
private String[] customerUuids;
/**
* 所属区域
*/
private String[] userRegions;
/**
* 是否工厂人员标志,0:否,1:是
*/
private String isFactoryWorker;
/**
* 是否设备授权用户,0:否,1:是
*/
private String isDeviceAuthUser;
/**
* 部门名称
*/
private String deptName;
/**
* 审批名称
*/
private String examine;
/**
* 核准名称
*/
private String approval;
/**
* 机构层级
*/
private Integer organizationLevel;
@JsonIgnore
private Integer parentOrganizationLevel;
private String organizationId;
}
package com.mydemo.springbootdocker.domain;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.List;
/**
* @Author wyt
* @Date 2024/4/23 上午 10:34
* @Version 1.0
*/
@Data
public class LoginUser implements UserDetails {
public SysUser user;
private List<GrantedAuthority> auth;
public LoginUser(SysUser sysUser,List<GrantedAuthority> auth) {
this.user = sysUser;
this.auth=auth;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return auth;
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUserName();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
package com.mydemo.springbootdocker.security;
import com.mydemo.springbootdocker.domain.LoginUser;
import com.mydemo.springbootdocker.domain.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
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 java.util.List;
/**
* @Author wyt
* @Date 2024/4/23 上午 10:29
* @Version 1.0
*/
@Slf4j
@Configuration
public class UserDetailsServiceImpl implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
log.info("username= {}", username);
/**
* 实际操作,是根据用户输入的用户名,从数据库中获取用户名,密码 权限相关 然后加入到内存中
* 后续操作是 使用数据库中存的加密数据,与用户输入的密码加密比较,看是否一直,如果一致表示认证成功,否则失败
*
* 本示例写死即可
*/
SysUser sysUser = new SysUser();
sysUser.setUserId(Long.valueOf(123));
sysUser.setUserName(username);
sysUser.setNickName("系统管理员");
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String encode = passwordEncoder.encode("123456");
sysUser.setPassword(encode);
//这里的角色信息没有从数据库里查询。实际开发中要从数据库里查询
List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("admin");
// return new User(username,encode,auths);
return createLoginUser(sysUser, auths);
}
public UserDetails createLoginUser(SysUser sysUser, List<GrantedAuthority> auths) {
return new LoginUser(sysUser, auths);
}
}
package com.mydemo.springbootdocker.security;
import com.mydemo.springbootdocker.security.handler.LoginFailureHandler;
import com.mydemo.springbootdocker.security.handler.LoginSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
* @Author wyt
* @Date 2024/4/23 下午 1:22
* @Version 1.0
*/
@Configuration
@EnableWebSecurity
public class SecurityWebConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
// .loginProcessingUrl("/loginDeal")
.usernameParameter("userName") // 提交表单中的用户名
.passwordParameter("password") // 提交表单中的密码字段
// .successHandler(new LoginSuccessHandler()) // 认证成功处理
// .failureHandler(new LoginFailureHandler()) // 认证失败
.permitAll()
.and().authorizeRequests()
.antMatchers("/test/**").permitAll() // 不需要登陆访问
.anyRequest().authenticated()
.and().csrf().disable() // 关闭csrf认证
;
}
}
完成如上工作就可以访问测试了
并且congroller 中/test/… 下面的接口是不需要登陆认证的