内容简介:寻根究底 Spring Security - 概述与快速启动
Spring Security
为基于 Java-EE
的企业级应用提供了综合的安全管理功能。当前有很多方案来解决服务器级别的安全访问机制,但是当部署环境一改变,就有需要花费大量的时间来解决应用的安全问题。 Spring Security
很好地提供了 WAR&EAR
级别的应用安全问题。
应用的安全主要包含两个核心概念 authentication
和 authorization
,即认证和授权。通过认证识别身份,通过授权获取能够访问的资源的权限。
在应用级别 Spring Security
支持各种级别的授权模型,常见的类型包括:
- HTTP BASIC authentication headers
- HTTP Digest authentication headers
- HTTP X.509 client certificate exchange
- Form-based authentication
- Jasig Central Authentication Service (otherwise known as CAS, which is a popular open source single sign-on system)
- LDAP (a very common approach to cross-platform authentication needs, especially in large environments)
- OpenID authentication
除上面描述之外,还支持其他众多方案,具体参见 Spring Security Document 。
Spring Security
主要解决以下三个方面的安全问题:
- 授权Web 请求
- 授权防范的调用
- 授权访问个人的领域对象
模块划分
Core
spring-security-core.jar
包含核心的认证和访问控制类和接口,远程支持,以及供应用使用的基本的 spring-security
的接口。支持独立的应用程序,远程的客户端,方法层的安全和基于JDBC的用户存储。包含以下核心目录:
- org.springframework.security.core
- org.springframework.security.access
- org.springframework.security.authentication
- org.springframework.security.provisioning
Remoting
提供了与 spring remoting
的集成。核心包为 org.springframework.security.remoting
。
Web
包含过滤器(filters)和Web 安全相关的基础代码。当采用 spring security web authentication services
和 URL-based
访问控制时需要使用。主要的包为 org.springframework.security.web
。
Config
包含 spring security namespace
的解析代码和 Java Configuration Code
的相关接口。当使用XML和 Java 注解的方式配置应用时需要用到。主要的包为 org.springframework.security.config
。
LDAP
LDAP authentication and provisioning code。核心的包为 org.springframework.security.ldap
。
ACL
专业的领域对象ACL 实现。用来为领域对象的访问提供安全机制。核心包为 org.springframework.security.acls
。
CAS
CAS 客户端的集成工具。当需要集成几个基于CAS的单点登录系统时需要使用。核心包为 org.springframework.security.cas
。
OpenID
spring-security.openid.jar
提供对OpenID 的支持。核心包为 org.springframework.security.openid
。需要 OpenID4Java
。
启动Spring Security
Spring Web 基于注解的启动机制
Java-EE
规范为了实现不通过 web.xml
启动Java-EE 项目定义了基于SPI(Service Provider Interface)机制的 javax.servlet.ServletContainerInitializer
接口。通过 SPI 机制
Java-EE
容器启动后,会在 classpath
中寻找上述接口的实现类,并回调该接口提供的方法。
Spring Web
就是采用上述机制来实现Web 相关内容的初始化工作的。 org.springframework.web.SpringServletContainerInitializer
既为 Spring Web
中实现 javax.servlet.Servletcontainerinitializer
接口的类,具体代码如下:
@HandlesTypes(WebApplicationInitializer.class) public classSpringServletContainerInitializerimplementsServletContainerInitializer{ @Override publicvoidonStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException { List<WebApplicationInitializer> initializers = new LinkedList<WebApplicationInitializer>(); if (webAppInitializerClasses != null) { for (Class<?> waiClass : webAppInitializerClasses) { // Be defensive: Some servlet containers provide us with invalid classes, // no matter what @HandlesTypes says... if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) && WebApplicationInitializer.class.isAssignableFrom(waiClass)) { try { initializers.add((WebApplicationInitializer) waiClass.newInstance()); } catch (Throwable ex) { throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex); } } } } if (initializers.isEmpty()) { servletContext.log("No Spring WebApplicationInitializer types detected on classpath"); return; } servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath"); AnnotationAwareOrderComparator.sort(initializers); for (WebApplicationInitializer initializer : initializers) { initializer.onStartup(servletContext); } } }
从上述代码上,我们可以看到Spring 在启动后调用了 org.springframework.web.WebApplicationInitializer
的实现类的 onStartup()
方法。
启动Spring Security
启动spring Security 需要注册 springSecurityFilterChain
,同时 Spring Security
提供了 WebSecurityConfigurerAdapter
来对Spring Security 进行配置。
非Spring MVC 应用
在非基于注解的Spring 应用中不能采用Sevlet 容器的SPI机制来进行启动,因此需要将 WebSecurityConfig.class
传递给 AbstractSecurityWebApplicationInitializer
的构造函数,来启动 Spring Security
。
@EnableWebSecurity @EnableGlobalMethodSecurity @EnableGlobalAuthentication public classWebSecurityConfigextendsWebSecurityConfigurerAdapter{ // do our self http config, we user WebSecurityConfigurerAdapter @Autowired publicvoidconfigureGlobal(AuthenticationManagerBuilder auth)throwsException{ auth.inMemoryAuthentication() .withUser("user").password("password").roles("USER"); } @Override protectedvoidconfigure(HttpSecurity http)throwsException{ http .authorizeRequests() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll(); } }
public classSecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer { publicSecurityWebApplicationInitializer(){ super(WebSecurityConfig.class); } }
通过以上配置可以得到以下功能:
- 所有URL 的访问都需要认证
- 基于用户名密码的的认证
- 允许用户logout
- X-XSS
- CSRF Fixation
- Session Fixation
-
集成了Servlet API:
- HttpServletRequest#getRemoteUser()
- HttpServletRequest.html#getUserPrincipal()
- HttpServletRequest.html#isUserInRole(java.lang.String)
- HttpServletRequest.html#login(java.lang.String, java.lang.String)
- HttpServletRequest.html#logout()
- ……
Spring MVC应用的启动
基于Spring MVC 的应用由SPI 机制启动,因此需要由 Spring MVC
来加载 Spring Security
的配置。因此,注册 springsecurityfilterchain
仅仅需要实现 AbstractSecurityWebApplicationInitializer
即可。
public classSecurityWebApplicationInitializerextendsAbstractSecurityWebApplicationInitializer{ // register springSecurityFilterChain // with out exist spring mvc, we use AbstractSecurityWebApplicationInitializer }
Spring MVC 的启动Init 类:
public classWebInitializerextendsAbstractAnnotationConfigDispatcherServletInitializer{ @Override protected Class<?>[] getRootConfigClasses() { return new Class<?>[]{RootConfig.class, WebSecurityConfig.class}; } @Override protected Class<?>[] getServletConfigClasses() { return new Class<?>[]{WebConfig.class}; } @Override protected String[] getServletMappings() { return new String[]{"/"}; } }
Spring MVC 基于 JSP
模板的配置:
@Configuration @EnableWebMvc @ComponentScan("org.zzy.spring.aop.web") public classWebConfigextendsWebMvcConfigurerAdapter{ @Bean publicViewResolverviewResolver(){ InternalResourceViewResolver resourceViewResolver = new InternalResourceViewResolver(); resourceViewResolver.setPrefix("/WEB-INF/views/"); resourceViewResolver.setSuffix(".jsp"); resourceViewResolver.setViewClass(JstlView.class); resourceViewResolver.setExposeContextBeansAsAttributes(true); return resourceViewResolver; } @Bean publicMessageSourcemessageSource(){ /*ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasename("messages/messages");*/ ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); messageSource.setBasename("classpath:messages/messages"); messageSource.setCacheSeconds(10); return messageSource; } @Override publicvoidconfigureDefaultServletHandling(DefaultServletHandlerConfigurer configurer){ configurer.enable(); } }
总结
Spring Security
为应用级别的安全访问提供了许多开箱即用的功能。同时,用户也能基于自己的业务需求根据 Spring Security
暴露的接口进行个性化的开发。相关内容会在后续的n文章中进行介绍。本文对 Spring MVC
的启动机制进行了详细地址介绍,在此基础上也介绍了 Spring Security
的启动方式,相信读者会有很大收获。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 寻根究底 Spring Security - 概述与快速启动
- 服务端指南 服务端概述 | 微服务架构概述
- influxdb 源码分析-概述
- zookeeper入门系列:概述
- 云原生架构概述
- 1.Spring 框架概述
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Linux 系统编程(第二版)
Robert Love / 东南大学出版社 / 2014-1-1 / 78
如何编写那些直接依赖于Linux内核和核心系统库提供的服务的软件?通过《Linux系统编程(第2版)(影印版)》,Linux内核参与者RobertLove(洛夫)为你提供了Linux系统编程方面的教程,Linux系统调用的参考手册,以及对于如何编写更聪明和更快的代码的来自内部人士的建议。Love清晰地指出了POSIX标准函数和Linux特别提供服务之间的差异。通过关于多线程的新章节,这本修订和扩展......一起来看看 《Linux 系统编程(第二版)》 这本书的介绍吧!