Spring securty<三> 认证案例代码

文章目录

  • Spring securty<三> 认证案例代码
    • 1、简介
    • 2、认证(登录)
    • 3、构建项目
      • 3.1、pom文件
      • 3.2、springboot 主启动类以及演示的controller接口
      • 3.3、swagger-ui的配置类
      • 3.4、统一返回的处理类
      • 3.5、WebSecurity 配置类
      • 3.6、拒绝访问处理器
      • 3.7、未认证的全局处理器
      • 3.8、登录成功的处理器
      • 3.9、认证失败的处理器
      • 3.10、最后一个swagger-ui的登录接口测试类
    • 4、测试验证

本地项目的基础环境

环境 版本
jdk 1.8.0_201
maven 3.6.0
Spring-boot 2.3.3.RELEASE

1、简介

spring security是一个提供身份验证、授权和防止常见攻击的框架,它对命令式和反应式应用程序都有一流的支持,是保护基于Spring的应用程序的事实上的标准。

详细可以参看《spring security官网》

2、认证(登录)

通过之前的两篇文章的介绍,应该也比较清楚了基本的概念了安全框架里的核心的概念了,从这篇开始,主要开始细化讲代码层面上的开发了;在权限框架中,认证这个部分,也算是最难的了,之后的几篇,也是主要讲述认证相关的。

《Spring securty<一> 简介入门案例》

《Spring securty<二> 配置项详解》

3、构建项目

新建项目badger-spring-securty-3

3.1、pom文件

为了方便,在pom文件中,我加入了swagger-ui的相关组件,以及json相关的包

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.3.RELEASE</version><relativePath /></parent><groupId>com.badger</groupId><artifactId>badger-spring-security-3</artifactId><version>0.0.1-SNAPSHOT</version><name>badger-spring-security-3</name><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><java.version>1.8</java.version><maven-jar-plugin.version>3.1.1</maven-jar-plugin.version><swagger.version>2.8.0</swagger.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.78</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- 用于自动生成 API 文档 --><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>${swagger.version}</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>${swagger.version}</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>

3.2、springboot 主启动类以及演示的controller接口

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class SecurityApplication {public static void main(String[] args) throws Exception {SpringApplication.run(SecurityApplication.class, args);}
}

3.3、swagger-ui的配置类

/*** 基于Swagger生成API文档* @author: liqi*/
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {static final String TEST_TOKEN_101 = "";@Beanpublic Docket createRestApi() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select().apis(RequestHandlerSelectors.basePackage("com.badger.spring.boot.security")).paths(PathSelectors.any()).build().globalOperationParameters(parameters());}private List<Parameter> parameters() {ParameterBuilder ticketPar = new ParameterBuilder();ticketPar.name("Authorization");ticketPar.description("验证的token,测试使用");ticketPar.modelRef(new ModelRef("string"));ticketPar.defaultValue(TEST_TOKEN_101);ticketPar.parameterType("header");ticketPar.required(false);return Arrays.asList(ticketPar.build());}private ApiInfo apiInfo() {return new ApiInfoBuilder().title("安全框架").description("内部接口").version("1.0.0-RELEASE").build();}
}

3.4、统一返回的处理类

@Data
public class Result {private Integer code;private String message;private Result(Integer code, String messgae) {this.code = code;this.message = messgae;}public static Result success(String message) {return new Result(200, message);}public static Result result(Integer code, String messgae) {return new Result(code, messgae);}
}

3.5、WebSecurity 配置类

package com.badger.spring.boot.security.config;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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.config.annotation.web.configurers.FormLoginConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {private static final String[] EXCLUDE_URLS = { "/**/*.js", "/**/*.css", "/**/*.jpg", "/**/*.png", "/**/*.gif","/v2/**", "/errors", "/error", "/favicon.ico", "/swagger-ui.html/**", "/swagger-ui/**", "/webjars/**","/swagger-resources/**", "/auth/login" };@Autowiredprivate AuthenticationSuccessHandler successHandler;@Autowiredprivate AuthenticationFailureHandler failureHandler;@AutowiredAccessDeniedHandler deniedHandler;@AutowiredAuthenticationEntryPoint entryPoint;@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("test").password(passwordEncoder().encode("123456")).authorities("admin");}@Overrideprotected void configure(HttpSecurity http) throws Exception {// 全局异常配置http.exceptionHandling().accessDeniedHandler(deniedHandler).authenticationEntryPoint(entryPoint);http.authorizeRequests().antMatchers(EXCLUDE_URLS).permitAll();// 1、表单操作FormLoginConfigurer<HttpSecurity> formLogin = http.formLogin();// 表单请求成功处理器、失败处理器;与loginPage冲突,配置后,loginPage不生效formLogin.successHandler(successHandler).failureHandler(failureHandler);// 表单提交的post请求地址,用户参数名称formLogin.loginProcessingUrl("/auth/login");http.csrf().disable();}
}

1、@EnableWebSecurity 注解,开启Web的Security的注解

2、配置一个默认用户,帐号为test,密码为123456

    @Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("test").password(passwordEncoder().encode("123456")).authorities("admin");}

3、基础帐号密码登录配置

    @Autowiredprivate AuthenticationSuccessHandler successHandler;@Autowiredprivate AuthenticationFailureHandler failureHandler;@Overrideprotected void configure(HttpSecurity http) throws Exception {// 全局异常配置http.exceptionHandling().accessDeniedHandler(deniedHandler).authenticationEntryPoint(entryPoint);http.authorizeRequests().antMatchers(EXCLUDE_URLS).permitAll();// 1、表单操作FormLoginConfigurer<HttpSecurity> formLogin = http.formLogin();// 表单请求成功处理器、失败处理器;与loginPage冲突,配置后,loginPage不生效formLogin.successHandler(successHandler).failureHandler(failureHandler);// 表单提交的post请求地址,用户参数名称formLogin.loginProcessingUrl("/auth/login");http.csrf().disable();}

全局的异常处理器

排除一些css、js、swagger-ui的接口、样式等

这里需要登录成功的处理器,以及登录失败的处理器,下一个小节贴基础代码;

3.6、拒绝访问处理器

/*** 全局异常处理器* @author liqi*/
@Component
public class DeniedHandler implements AccessDeniedHandler {@SuppressWarnings("deprecation")@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response,AccessDeniedException accessDeniedException) throws IOException, ServletException {String error = "请求Url:" + request.getRequestURI() + " 鉴权失败:" + accessDeniedException.getMessage();response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);PrintWriter writer = response.getWriter();writer.print(JSON.toJSONString(Result.result(HttpStatus.UNAUTHORIZED.value(), error)));writer.flush();writer.close();}
}

3.7、未认证的全局处理器

/*** 未认证的全局处理器* 没有认证时,在这里处理结果,不要重定向* @author liqi**/
@Component
public class EntryPoint implements AuthenticationEntryPoint {@SuppressWarnings("deprecation")@Overridepublic void commence(HttpServletRequest request, HttpServletResponse response,AuthenticationException authException) throws IOException, ServletException {String error = "请求Url:" + request.getRequestURI() + " 认证失败:" + authException.getMessage();response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);PrintWriter writer = response.getWriter();writer.print(JSON.toJSONString(Result.result(HttpStatus.UNAUTHORIZED.value(), error)));writer.flush();writer.close();}
}

3.8、登录成功的处理器

/*** 登录成功,事件处理器* @author liqi*/
@Component
@Slf4j
public class SuccessHandler implements AuthenticationSuccessHandler {@SuppressWarnings("deprecation")@Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,Authentication authentication) throws IOException, ServletException {response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);log.info("登录成功:{}", authentication.getPrincipal());PrintWriter writer = response.getWriter();writer.print(JSON.toJSONString(Result.success(authentication.getPrincipal().toString())));writer.flush();writer.close();}
}

3.9、认证失败的处理器

/*** 登录失败处理器* @author liqi*/
@Component
public class FailureHandler implements AuthenticationFailureHandler {private Logger log = LoggerFactory.getLogger(getClass());@SuppressWarnings("deprecation")@Overridepublic void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,AuthenticationException exception) throws IOException, ServletException {log.info("登录失败,{}", exception.getMessage());response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);PrintWriter writer = response.getWriter();writer.print(JSON.toJSONString(Result.result(400, exception.getMessage())));writer.flush();writer.close();}
}

3.10、最后一个swagger-ui的登录接口测试类

@RestController
@Api(tags = { "登录接口" })
public class LoginController {@ApiOperation(value = "账号密码登陆")@ApiImplicitParams({@ApiImplicitParam(name = "username", value = "用户名", dataType = "String", paramType = "query", defaultValue = "test"),@ApiImplicitParam(name = "password", value = "密码", dataType = "String", paramType = "query", defaultValue = "123456") })@PostMapping("/auth/login")public void login(@RequestParam(name = "username", required = true) String username,@RequestParam(name = "password", required = true) String password) {}
}

可以看到,这个登录接口,里面啥的都没有,只是定义了参数,并没有返回,实际业务,也没有走这个接口,而是通过Security的拦截器链,来处理的,定义这个接口,也只是为了,swagger-ui可以扫描到,好调用,如果使用postMain调用,这个接口,可以完全不用写;

设置的默认密码,也跟上述一致,user/123456

4、测试验证

启动主启动类,打开swagger-ui页面

http://localhost:8080/swagger-ui.html#/登录接口

登录正确的帐号密码

{"code": 200,"message": "test"
}

错误的密码

{"code": 400,"message": "Bad credentials"
}

可以看到,测试成功了;

详细的代码,可以查看《码云》

Spring securty<三> 认证案例代码相关推荐

  1. Spring入门-ioc基础案例代码

    目录 一.ioc介绍 二.基础代码实现 1.创建接口实现类 2.传统方式创建 三.spring bean方式创建 1.配置文件 2.编写实现类 一.ioc介绍 略 导入坐标 <dependenc ...

  2. Spring securty<六> 认证--手机号+验证码

    Spring securty<六> 认证–手机号+验证码 文章目录 Spring securty<六> 认证--手机号+验证码 1.简介 2.认证(登录) 3.认证的流程 3. ...

  3. 三色螺旋线 -《跟小海龟学Python》案例代码

    今天分享新书<跟小海龟学Python>的案例代码:三色螺旋线. Python源代码: from turtle import * # 导入海龟绘图库 speed(0) # 快速绘制 # 计算 ...

  4. 使用Spring特性优雅书写业务代码

    作者:阿里巴巴淘系技术 链接:https://www.zhihu.com/question/60761181/answer/1737592739 来源:知乎 著作权归作者所有.商业转载请联系作者获得授 ...

  5. Spring的IoC理解,代码进行详解

    如何理解Spring的IoC IOC底层原理 创建User实体类 创建了UserDao接口 创建了UserDaoImpl实现类 8.4 创建了UserService接口 创建了UserServiceI ...

  6. (转)Spring的三种实例化Bean的方式

    http://blog.csdn.net/yerenyuan_pku/article/details/52832793 Spring提供了三种实例化Bean的方式. 使用类构造器实例化. <be ...

  7. 浅析 Spring Security 的认证过程及相关过滤器

    前言 上一篇文章 浅析 Spring Security 核心组件 中介绍了Spring Security的基本组件,有了前面的基础,这篇文章就来详细分析下Spring Security的认证过程. S ...

  8. Spring第三天,详解Bean的生命周期,学会后让面试官无话可说!

    点击下方链接回顾往期 不要再说不会Spring了!Spring第一天,学会进大厂! Spring第二天,你必须知道容器注册组件的几种方式!学废它吊打面试官! 今天讲解Spring中Bean的生命周期. ...

  9. 怎样处理重命名系列案例代码

    这篇文章主要介绍了批处理重命名系列案例代码 批处理用于文本/文件的操作确实非常简单有力!不用多么复杂的代码,仅一个记事本加上简洁的代码即可搞定大部分文本/文件的操作,下面记录下我用过的一些代码,基本都 ...

  10. spring security 自定义认证登录

    spring security 自定义认证登录 1.概要 1.1.简介 spring security是一种基于 Spring AOP 和 Servlet 过滤器的安全框架,以此来管理权限认证等. 1 ...

最新文章

  1. SVN配置自启动服务碰到[SC] OpenSCManager 失败 5:解决办法
  2. 第十、十一周项目四 - 教师兼干部类
  3. 国考中的电子信息类与计算机类,信息工程属于什么类-电子信息工程在公务员考试中属于计算机类吗 – 手机爱问...
  4. php环境搭建5.6_WIN8.1下搭建PHP5.6环境
  5. Android之多线程----异步消息处理机制之Handler详解
  6. 看懂这5幅图,研发效能分析和改进就容易了
  7. 解决MySQL数据库中文模糊检索问题
  8. C函数形参列表与汇编寄存器的对应关系
  9. jQuery HTML操作
  10. datagrid 重载本地数据_jQuery easyui datagrid重新加载数据
  11. https与http的区别
  12. Office 365系列(6)------Stage Migrate 搬迁方式至O365上来方法及步骤总结
  13. 读《反欺骗的艺术》有感
  14. 统计二叉树的叶子结点个数(C语言数据结构)
  15. ubuntu 16.04 配置网络代理
  16. Java工程师岗位分析报告
  17. 两直线平行交叉相乘_两条直线方程相乘的几何意义 是不是说两相交直线的点的轨迹...
  18. 怎样快速实现两台电脑硬盘文件共享?
  19. Poser v7.0 1DVD(3D 角色动画)
  20. ib中文文学课如何学习重点?

热门文章

  1. 电脑进不了,电脑进不了系统,小编教你怎么解决电脑进不了系统
  2. IT行业可以做什么副业?
  3. 软件测试DAY3-执行用例
  4. Linux-网络管理
  5. 幻想世界正在连接服务器,旅行物语桌面版连接不上怎么办 pc电脑版无法连接服务器怎么办...
  6. echarts柱形图超炫颜色搭配
  7. 使命召唤手游显示服务器停服,使命召唤手游停服了吗 是手游还是端游
  8. 微软宣布446亿美元收购雅虎
  9. 数据结构,持续更新!!!
  10. 线性规划(一):基本概念