Spring security 获取用户登录信息: Spring Security框架的核心共享组件 1.SecurityContextHolder: 最基础的对象就是SecurityContextHolder。 我们把当前应用程序的当前安全环境的细节存储到它里边了。 默认情况下,SecurityContextHolder使用ThreadLocal存储这些信息,这意味着,安全环境在同一个线程执行的方法一直是有效的。 我们把安全主体和系统交互的信息都保存在SecurityContextHolder中了,查看该类的源代码:我们发现在这个类中有一个静态属性: SecurityContextHolderStrategy strategy,在SecurityContextHolder初始化的时候,为它指定了实例对象。 strategy.setContext(SecurityContext context); 2.SecurityContext: Security上下文,是一个接口 void setAuthentication(Authentication authentication); 3.Authentication 也是一个接口。我们把安全主体和系统交互的信息都保存在SecurityContextHolder中了。 Spring Security使用一个Authentication对应来表现这些信息。 虽然你通常不需要自己创建一个Authentication对象, 直接通过SecurityContextHolder获取上下文对象,然后通过上下文对象(SecurityContext)获取即可 4.UserDetails UserDetails是一个Spring Security的核心接口。 它代表一个主体(包含于用户相关的信息)。 在Authentication接口中有一个方法 Object getPrincipal(); 这个方法返回的是一个安全主题,大多数情况下, 这个对象可以强制转换成UserDetails对象,获取到UerDetails对象之后,就可以通过这个对象的getUserName()方法获取当前用户名。 下面的代码演示了在任何地方,如何获取当前的用户名: SecurityContext ctx = SecurityContextHolder.getContext(); Authentication auth = ctx.getAuthentication(); Object Principal = auth.getPrincipal(); String username = ""; if(Principal instanceof UserDetails){ username = (UserDetails)Principal.getUsername(); }else{ username = Principal.toString(); } 进阶:理解安全过滤器链 1.Spring Security的web架构是完全基于标准的servlet过滤器的。它没有在内部使用servlet或任何其他基于servlet的框架(比如spring mvc),所以它没有与任何特定的web技术强行关联。 它只管处理HttpServletRequest 和HttpServletResponse,不关心请求时来自浏览器,web服务客户端,还是一个AJAX应用。 2.Spring Security 一启动就会包含一批负责各种安全管理的过滤器,这些过滤器组成过滤器链。 3.这里配置了一个过滤器,名字是DelegatingFilterProx,这个类在spring-web-3.0.0RELEASE.jar包中 它实际上是一个代理类,这个过滤器里没有实现过滤器的任何逻辑。 DelegatingFilterProxy做的事情是代理Filter的方法,从spring容器【application context】里获得bean。 这让bean可以获得spring web application context的生命周期支持,使配置较为轻便。 bean必须实现javax.servlet.Filter接口,它必须和filter-name里定义的名称是一样的。查看DelegatingFilterProxy的javadoc获得更多信息。 4.刚才说到Spring Security需要一些过滤器,这些过滤器如果在web.xml中配置的话,配置起来就很繁琐了,这些过滤器还必须按照顺序来配置. 所以为了方便,就只在web.xml文件中配置了一个代理过滤器,它就相当于是一个入口,web容器启动的时候,由它到spring容器中启动spring Security需要的过滤器链。 5.既然如此,我们就需要在spirng容器中配置过滤器了。我们知道,代理类需要有个代理目标,web.xml文件中的DelegatingFilterProxy 所代理的目标类是什么呢?这个类就是: org.springframework.security.web.FilterChainProxy ,在spring容器中声明这个类,然后将要启动的过滤器链配置进去就完成了配置任务,下面是在applicationContext.xml文件中的配置: Spring Security框架提供的过滤器已经很完善了,一般没有必要自己来定义,除非是特殊需求。 1.HttpSessionContextIntegrationFilter 第一个起作用的过滤器,首先判断用户的session中是否已经存在一个SecurityContext了,如果存在,就把SecurityContext拿出来,放到SecurityContextHolder中,拱Spring Security其他部分使用。如果不存在,就创建一个SecurityContext出来,还是放到SecurityContextHolder中,拱其它部分使用。 在所有过滤器执行完毕后,清空SecurityContextHolde。 2.LogoutFilter 只处理注销请求,默认为/j_spring_security_logout . 在用户发送注销请求的时候,销毁用户session,清空SecurityContextHolder,然后重定向到注销成功页面。 3.AuthenticationProcessingFilter 处理 form 登陆的过滤器,与form 登陆有关的所有操作都是在此进行的。默认情况下只处理/j_spring_security_check 请求,这个请求应该是用户使用form登陆后的提交地址 此过滤器执行的基本操作时,通过用户名和密码判断用户是否有效,如果登录成功就跳转到成功页面(可能是登陆之前访问的受保护页面,也可能是默认的成功页面),如果登录失败,就跳转到失败页面 4.DefaultLoginPageGeneratingFilter 此过滤器用来生成一个默认的登录页面,默认的访问地址为/spring_security_login,这个默认的登录页面虽然支持用户输入用户名,密码,也支持rememberMe 功能,但是因为太难看了,只能是在演示时做个样子,不可能直接用在实际项目中 5.BasicProcessingFilter 此过滤器用于进行 basic 验证,功能与AuthenticationProcessingFilter 类似,只是验证的方式不同 6.SecurityContextHolderAwareRequestFilter 此过滤器用来包装客户的请求。目的是在原始请求的基础上,为后续程序提供一些额外的数据。比如getRemoteUser()时直接返回当前登陆的用户名之类的。 7.RememberMeProcessingFilter---------------------------------------------- 此过滤器实现 RememberMe 功能,当用户cookie 中存在rememberMe 的标记,此过滤器会根据标记自动实现用户登陆,并创建SecurityContext,授予对应的权限。 8.AnonymousProcessingFilter 为了保证操作统一性,当用户没有登陆时,默认为用户分配匿名用户的权限。有关匿名登录功能的详细信息 9.ExceptionTranslationFilte 此过滤器的作用是处理中 FilterSecurityInterceptor 抛出的异常,然后将请求重定向到对应页面,或返回对应的响应错误代码。 10.SessionFixationProtectionFilter 防御会话伪造攻击。 11.FilterSecurityInterceptor 用户的权限控制都包含在这个过滤器中。 功能一: 如果用户尚未登陆,则抛出AuthenticationCredentialsNotFoundException“尚未认证异常”。 功能二: 如果用户已登录,但是没有访问当前资源的权限,则抛出AccessDeniedException“拒绝访问异常”。 功能三: 如果用户已登录,也具有访问当前资源的权限,则放行。 管理会话 应用中常常有这样的情形:一个用户正确的登录了系统,并没有使用系统提供的”退出”功能,而是直接关掉浏览器,或者长时间不适用体统,Tomcat默认情况下会保存session 30分钟,30分钟后,会话就会过期。 我们可以配置Spring Security 检测失效的session ID,并把用户转发到对应的URL上,我们可以通过配置 session-management元素 同步会话控制:(单点登录) 多个用户不能使用同一个账号同时登陆系统。为了实现这个功能,我们首先要在web.xml文件中添加一个监听器,这个监听器会在session 创建和销毁的时候通知Spring Security。 <listener><listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class></listener> <!--会话管理配置,登录失效--> <security:session-management invalid-session-url="/sessionTimeOut.html"> <!--配置单点登录,注意web.xml也要相应的配置监听器--> <security:concurrency-control max-sessions="1" error-if-maximum-exceeded="true"></security:concurrency-control> </security:session-management> Spring Security的简单原理 核心: 1.AuthenticationProcessingFilter登陆验证拦截器 2.AbstractSecurityInterceptor资源管理拦截器 流程: 1.用户登陆,会被AuthenticationProcessingFilter拦截,调用AuthenticationManager的实现,而且AuthenticationManager会调用ProviderManager来获取用户验证信息(不同的Provider调用的服务不同,因为这些信息可以是在数据库上,可以是在LDAP服务器上,可以是xml配置文件上等),如果验证通过后会将用户的权限信息封装一个User放到spring的全局缓存SecurityContextHolder中,以备后面访问资源时使用。 2.访问资源(即授权管理),访问url时,会通过AbstractSecurityInterceptor拦截器拦截,其中会调用FilterInvocationSecurityMetadataSource的方法来获取被拦截url所需的全部权限,在调用授权管理器AccessDecisionManager,这个授权管理器会通过spring的全局缓存SecurityContextHolder获取用户的权限信息,还会获取被拦截的url和被拦截url所需的全部权限,然后根据所配的策略(有:一票决定,一票否定,少数服从多数等),如果权限足够,则返回,权限不够则报错并调用权限不足页面。 实现:
Spring security 相关名词解释
最新推荐文章于 2021-05-20 16:04:33 发布