SpringSecurity 安全框架
入门案例
创建基于maven环境的springboot2项目。并引入相关的依赖。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-test</artifactId><scope>test</scope></dependency>
新建controller包并创建测试用的controller类TestController
packagecom.example.demo.controller;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RestController;/**
* @Author ChenRuXu
* @Date 2023/2/17 19:50
* @Version 1.0
*/@RestController@RequestMapping("/test")publicclassTestController{@GetMapping("/hello")publicStringadd(){return"hello security";}}
访问页面时出现了默认的安全认证窗口,密码在控制台处进行显示。默认的用户名为user
基本原理
springsecurity本质上是一个过滤器链
FilterSecurityInterceptor过滤器
位于最低端的过滤器是一个方法级的权限过滤器。
publicclassFilterSecurityInterceptorextendsAbstractSecurityInterceptorimplementsFilter{privatestaticfinalStringFILTER_APPLIED="__spring_security_filterSecurityInterceptor_filterApplied";privateFilterInvocationSecurityMetadataSource securityMetadataSource;privateboolean observeOncePerRequest =true;
该类实现了Filter接口是一个过滤器类
publicinterfaceFilter{defaultvoidinit(FilterConfig filterConfig)throwsServletException{}voiddoFilter(ServletRequest var1,ServletResponse var2,FilterChain var3)throwsIOException,ServletException;defaultvoiddestroy(){}
过滤器接口实现了三个方法包括了,init初始化过滤器执行的方法,doFilter过滤时执行的方法,和销毁时执行的方法。
ExceptionTranslationFilter过滤器
是个异常处理的过滤器用来处理在认证授权的过程中抛出的异常信息。
publicclassExceptionTranslationFilterextendsGenericFilterBeanimplementsMessageSourceAware{privatevoiddoFilter(HttpServletRequest request,HttpServletResponse response,FilterChain chain)throwsIOException,ServletException{try{
chain.doFilter(request, response);}catch(IOException var7){throw var7;}catch(Exception var8){Throwable[] causeChain =this.throwableAnalyzer.determineCauseChain(var8);RuntimeException securityException =(AuthenticationException)this.throwableAnalyzer.getFirstThrowableOfType(AuthenticationException.class, causeChain);if(securityException ==null){
securityException =(AccessDeniedException)this.throwableAnalyzer.getFirstThrowableOfType(AccessDeniedException.class, causeChain);}if(securityException ==null){this.rethrow(var8);}if(response.isCommitted()){thrownewServletException("Unable to handle the Spring Security Exception because the response is already committed.", var8);}this.handleSpringSecurityException(request, response, chain,(RuntimeException)securityException);}}
处理各种异常的信息。
UsernamePasswordAuthenticationFilter过滤器
UsernamePasswordAuthenticationFilter过滤器:对/login的POST请求做拦截,校验表单中用户名密码。
核心的业务逻辑
publicAuthenticationattemptAuthentication(HttpServletRequest request,HttpServletResponse response)throwsAuthenticationException{if(this.postOnly &&!request.getMethod().equals("POST")){thrownewAuthenticationServiceException("Authentication method not supported: "+ request.getMethod());}else{String username =this.obtainUsername(request);
username = username !=null? username.trim():"";String password =this.obtainPassword(request);
password = password !=null? password :"";UsernamePasswordAuthenticationToken authRequest =UsernamePasswordAuthenticationToken.unauthenticated(username, password);this.setDetails(request, authRequest);returnthis.getAuthenticationManager().authenticate(authRequest);}}
过滤器链的加载过程
使用springsecurity配置过滤器
需要配置的过滤器为:DelegatingFilterProxy
publicclassDelegatingFilterProxyextendsGenericFilterBean{publicvoiddoFilter(ServletRequest request,ServletResponse response,FilterChain filterChain)throwsServletException,IOException{Filter delegateToUse =this.delegate;if(delegateToUse ==null){synchronized(this.delegateMonitor){
delegateToUse =this.delegate;if(delegateToUse ==null){WebApplicationContext wac =this.findWebApplicationContext();if(wac ==null){thrownewIllegalStateException("No WebApplicationContext found: no ContextLoaderListener or DispatcherServlet registered?");}
delegateToUse =this.initDelegate(wac);}this.delegate = delegateToUse;}}}
使用this.initDelegate(wac)进行初始化加载需要需要用到的信息
版权归原作者 程序小旭 所有, 如有侵权,请联系我们删除。