- pom.xml中加入springsecurity依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
- 用户对象实体
@Data
public class ProjectUser implements Serializable, UserDetails {
private static final long serialVersionUID = 4702398324039042010L;
// todo 用户的其他属性
private String username;
/**
* 系统级别的用户角色枚举,可以修改成1,2,3存储在db,节省空间
*/
public enum UserRoleEnum {
/**
* 管理员
*/
ROLE_ADMIN("ROLE_ADMIN", "管理员"),
/**
* 普通用户
*/
ROLE_NORMAL("ROLE_NORMAL", "普通用户");
private String key;
private String value;
private UserRoleEnum(String key, String value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public String getValue() {
return value;
}
}
}
- 无密码编码,如果需要密码编码直接在里面编写
public class NoPasswordEncoder implements PasswordEncoder {
@Override
public String encode(CharSequence rawPassword) {
return "";
}
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
return true;
}
}
- 用户服务,公司的邮箱,直接登录;如果是toc,需要用户注册,登录分开写
@Service
@Slf4j
public class UserService implements UserDetailsService {
@Autowired
private AuthenticationManager authenticationManager;
/**
* 通过用户名加载用户
*
* @param username
* @return
*/
@Override
public UserDetails loadUserByUsername(String username) {
ProjectUser user = null;//根据自己逻辑获取用户
if (user == null) {
throw new UsernameNotFoundException("用户不存在");
}
return user;
}
/**
* 登陆
*
* @param username
* @return
*/
public ProjectUser login(String username, String password) {
// todo 校验这个用户,并登陆并授权
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
UsernamePasswordAuthenticationToken upToken = new UsernamePasswordAuthenticationToken(username, encoder.encode(password));
//使用SpringSecurity拦截登陆请求 设置认证,为了其他接口访问进行用户验证
Authentication authentication = authenticationManager.authenticate(upToken);
SecurityContextHolder.getContext().setAuthentication(authentication);
// todo 返回登陆的用户信息
}
}
- springsecurity的配置
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) //post请求之前进行验证
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserService userService;
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(new NoPasswordEncoder());
}
/**
* 如果是前后分离部署的,这个里面不用写静态资源
* 如果是前后端放在一起的,需要把静态资源忽略验证
*
* @param web
* @throws Exception
*/
@Override
public void configure(WebSecurity web) throws Exception {
web
.debug(false)
.ignoring()
.antMatchers("/**/*.html","/webjars/**")
.antMatchers("/**/favicon.ico")
.antMatchers("/fonts/**")
.antMatchers("/css/**")
.antMatchers("/img/**")
.antMatchers("/lib/**")
.antMatchers("/scripts/**")
.antMatchers("/static-css/**")
.antMatchers("/static-icons/**")
.antMatchers("/static-img/**")
.antMatchers("/static-mock/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable() //禁用csrf
.authorizeRequests().antMatchers(HttpMethod.GET,"/swagger-resources/configuration/ui",
"/swagger-resources/configuration/security",
"/v2/api-docs",
"/swagger-resources").permitAll()
//给api开的所有接口不走springsecurity
.antMatchers(HttpMethod.POST, "/authentication/login",
"/authentication/logout","/authentication/techplatLogin","/api/token","/api/sql/create","/api/sql/update").permitAll()
.antMatchers("/error","/healthCheck").permitAll()
.antMatchers(HttpMethod.GET,"/api/sql/yarnClusterList","/api/sql/flinksqlEngineList","/api/sql/detail","/api/sql/start"
,"/api/sql/getStartTimeLine","/api/sql/stop","/api/sql/delete").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(new AuthenticationEntryPoint() {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
response.setCharacterEncoding("utf-8");
response.setContentType("text/javascript;charset=utf-8");
response.getWriter().print(JSONObject.toJSONString(new ResultDTO(401, "未登录")));
}
})
.accessDeniedHandler(new AccessDeniedHandler() {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException, ServletException {
response.setCharacterEncoding("utf-8");
response.setContentType("text/javascript;charset=utf-8");
response.getWriter().print(JSONObject.toJSONString(new ResultDTO(403, "无权限")));
}
})
.and()
.logout()
.logoutUrl("/authentication/logout")
.invalidateHttpSession(true)
.deleteCookies("project-test-sid", "project-sid")
.logoutSuccessHandler(new LogoutSuccessHandler() {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
response.setStatus(200);
response.setCharacterEncoding("utf-8");
response.setContentType("text/javascript;charset=utf-8");
response.getWriter().print(JSONObject.toJSONString(ResultDTO.success("注销成功")));
}
})
.permitAll();
}
}
- springsecurity的工具类,包含获取当前登录的用户
public class WebSecurityUtil {
private WebSecurityUtil() {
throw new IllegalStateException("Utility class");
}
/**
* 获取当前登录的用户
*
* @return
*/
public static ProjectUser getUser() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return (ProjectUser) authentication.getPrincipal();
}
}