一、Spring Security中的认证 & 授权(前后端分离)
1.1、MyWebSecurityConfigurerAdapter7002
/*** @Author : 一叶浮萍归大海* @Date: 2024/1/11 21:50* @Description: Spring Security配置类*/
@Configuration
public class MyWebSecurityConfigurerAdapter7002 extends WebSecurityConfigurerAdapter {@Resourceprivate MyAuthenticationSuccessHandler7002 successHandler;@Resourceprivate MyAuthenticationFailureHandler7002 failureHandler;@Resourceprivate MyLogoutSuccessHandler logoutSuccessHandler;@Resourceprivate MyAuthenticationEntryPoint authenticationEntryPoint;/*** 密码加密器* @return*/@BeanPasswordEncoder passwordEncoder() {return NoOpPasswordEncoder.getInstance();}/*** 配置基于内存的用户* @param auth* @throws Exception*/@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("admin").password("123456").roles("admin").and().withUser("root").password("123456").roles("root");}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/helloWorld").permitAll().anyRequest().authenticated().and()/*** 登录成功 & 登录失败回调*/.formLogin().loginPage("/login").successHandler(successHandler).failureHandler(failureHandler).and()/*** 注销登录回调*/.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler).permitAll().and().csrf().disable()/*** 未认证回调*/.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint);}}
1.2、MyAuthenticationSuccessHandler7002
/*** @Author : 一叶浮萍归大海* @Date: 2024/1/12 09:55* @Description: 认证(登录)成功处理器*/
@Component
public class MyAuthenticationSuccessHandler7002 implements AuthenticationSuccessHandler {@Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {response.setContentType("application/json;charset=utf-8");PrintWriter out = response.getWriter();R r = R.ok().data(authentication.getPrincipal());out.write(new ObjectMapper().writeValueAsString(r));out.flush();out.close();}
}
1.3、MyAuthenticationFailureHandler7002
/*** @Author : 一叶浮萍归大海* @Date: 2023/1/12 10:05* @Description: 认证(登录)失败处理器*/
@Component
public class MyAuthenticationFailureHandler7002 implements AuthenticationFailureHandler {@Overridepublic void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {response.setContentType("application/json;charset=utf-8");PrintWriter out = response.getWriter();R r = R.error();if (exception instanceof LockedException) {r.data(SpringSecurityConstants.LOCKED_ERROR_MESSAGE);} else if (exception instanceof CredentialsExpiredException) {r.data(SpringSecurityConstants.CREDENTIALS_EXPIRED_ERROR_MESSAGE);} else if (exception instanceof AccountExpiredException) {r.data(SpringSecurityConstants.ACCOUNT_EXPIRED_ERROR_MESSAGE);} else if (exception instanceof DisabledException) {r.data(SpringSecurityConstants.DISABLED_ERROR_MESSAGE);} else if (exception instanceof BadCredentialsException) {r.data(SpringSecurityConstants.BAD_CREDENTIALS_ERROR_MESSAGE);} else if (exception instanceof AuthenticationServiceException) {r.data(SpringSecurityConstants.VERIFY_CODE_ERROR_MESSAGE);} else {r.data(SpringSecurityConstants.LOGIN_ERROR_COMMON_MESSAGE);}out.write(new ObjectMapper().writeValueAsString(r));out.flush();out.close();}
}
1.4、MyLogoutSuccessHandler7002
/*** @Author : 一叶浮萍归大海* @Date: 2024/01/12 11:26* @Description: 注销登录处理器*/
@Component
public class MyLogoutSuccessHandler7002 implements LogoutSuccessHandler {@Overridepublic void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {response.setContentType("application/json;charset=utf-8");PrintWriter out = response.getWriter();R r = R.ok().data(SpringSecurityConstants.LOGOUT_SUCCESS_MESSAGE);out.write(new ObjectMapper().writeValueAsString(r));out.flush();out.close();}}
1.5、MyAuthenticationEntryPoint7002
/*** @Author : 一叶浮萍归大海* @Date: 2024/01/12 11:27* @Description: 未认证处理方案(用户未登录就访问资源)*/
@Component
public class MyAuthenticationEntryPoint7002 implements AuthenticationEntryPoint {@Overridepublic void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {response.setContentType("application/json;charset=utf-8");PrintWriter out = response.getWriter();R r = R.error(ResponseEnum.HTTP_UNAUTHORIZED_ERROR.getCode(),ResponseEnum.HTTP_UNAUTHORIZED_ERROR.getMessage());out.write(new ObjectMapper().writeValueAsString(r));out.flush();out.close();}}
1.6、SpringSecurityConstants7002
/*** @Author 一叶浮萍归大海* @Description Spring Security认证 & 授权常量类* @Date 2024/01/12 10:06*/
public class SpringSecurityConstants {public static final String LOGOUT_SUCCESS_MESSAGE = "注销成功!";public static final String LOCKED_ERROR_MESSAGE = "账户被锁定,请联系管理员!";public static final String CREDENTIALS_EXPIRED_ERROR_MESSAGE = "密码过期,请联系管理员!";public static final String ACCOUNT_EXPIRED_ERROR_MESSAGE = "账户过期,请联系管理员!";public static final String DISABLED_ERROR_MESSAGE = "账户被禁用,请联系管理员!";public static final String BAD_CREDENTIALS_ERROR_MESSAGE = "用户名或者密码错误,请重新输入!";public static final String VERIFY_CODE_ERROR_MESSAGE = "验证码错误!";public static final String LOGIN_ERROR_COMMON_MESSAGE = "登录失败,请联系管理员!";
}
1.7、R
/*** @Author 一叶浮萍归大海* @Description* @Date 2023/01/12 10:06*/
@Data
public class R<T> {private Integer code;private String message;private T data;/*** 构造函数私有化*/private R(){}/*** 返回成功结果* @return*/public static R ok(){R r = new R();r.setCode(ResponseEnum.SUCCESS.getCode());r.setMessage(ResponseEnum.SUCCESS.getMessage());return r;}/*** 返回失败结果* @return*/public static R error(){R r = new R();r.setCode(ResponseEnum.ERROR.getCode());r.setMessage(ResponseEnum.ERROR.getMessage());return r;}public static R error(int code, String msg) {R r = new R();r.setCode(code);r.setMessage(msg);return r;}/*** 设置特定的结果* @param responseEnum* @return*/public static R setResult(ResponseEnum responseEnum){R r = new R();r.setCode(responseEnum.getCode());r.setMessage(responseEnum.getMessage());return r;}public R data(T entity) {this.setData(entity);return this;}/*** 设置特定的响应消息* @param message* @return*/public R message(String message){this.setMessage(message);return this;}/*** 设置特定的响应码* @param code* @return*/public R code(Integer code){this.setCode(code);return this;}
}
1.8、ResponseEnum
/*** @Author 一叶浮萍归大海* @Description* @Date 2023/5/30 15:55*/
@Getter
@ToString
@AllArgsConstructor
public enum ResponseEnum {/*** 响应状态码 & 响应信息映射*/SUCCESS(200, "成功!"),ERROR(201, "失败!"),SERVER_INTERNAL_ERROR(500, "服务器内部错误,请联系管理员!"),PARAMETER_VALIDATE_FAILED_ERROR(10001, "参数校验失败,请联系管理员!"),BUSINESS_ERROR(10002, "业务异常,请联系管理员"),// =================== Spring Cloud Alibaba Sentinel统一异常处理 ===================SENTINEL_FLOW_EXCEPTION(20001,"接口被限流,请联系管理员!"),SENTINEL_DEGRADE_EXCEPTION(20002,"接口被降级,请联系管理员!"),SENTINEL_PARAM_FLOW_EXCEPTION(20003,"热点参数限流,请联系管理员!"),SENTINEL_SYSTEM_BLOCK_EXCEPTION(20004,"触发系统保护规则,请联系管理员!"),SENTINEL_AUTHORITY_EXCEPTION(20005,"授权规则不通过,请联系管理员!"),// =================== Spring Security统一异常处理 ===================HTTP_UNAUTHORIZED_ERROR(401, "尚未登录,请登录!"),HTTP_FORBIDDEN_ERROR(403, "权限不足,请联系管理员!"),;/*** 响应状态码*/private Integer code;/*** 响应信息*/private String message;}