加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Java Web系列:Spring Security 基础

发布时间:2020-12-15 01:52:14 所属栏目:大数据 来源:网络整理
导读:Spring Security虽然比JAAS进步很大,但还是先天不足,达不到ASP.NET中的认证和授权的方便快捷。这里演示登录、注销、记住我的常规功能,认证上自定义提供程序避免对数据库的依赖,授权上自定义提供程序消除从缓存加载角色信息造成的角色变更无效副作用。 1.

Spring Security虽然比JAAS进步很大,但还是先天不足,达不到ASP.NET中的认证和授权的方便快捷。这里演示登录、注销、记住我的常规功能,认证上自定义提供程序避免对数据库的依赖,授权上自定义提供程序消除从缓存加载角色信息造成的角色变更无效副作用。

1.基于java config的Spring Security基础配置

(1)使用AbstractSecurityWebApplicationInitializer集成到Spring MVC

SecurityInitializer }

@EnableGlobalMethodSecurity(securedEnabled = ,prePostEnabled = SecurityConfig configure(HttpSecurity http) http.authorizeRequests().antMatchers("/account**","/admin**" http.formLogin().usernameParameter("userName").passwordParameter("password").loginPage("/login" .loginProcessingUrl("/login").successHandler( .logout().logoutUrl("/logout").logoutSuccessUrl("/" http.rememberMe().rememberMeParameter("rememberMe" http.setSharedObject(SecurityContextRepository., HttpSessionSecurityContextRepository repo = SecurityContext context = (context != && context.getAuthentication() != Membership membership = String username = String[] roles = UsernamePasswordAuthenticationToken token = "password" System.out.println("check user role" configure(AuthenticationManagerBuilder auth) auth.authenticationProvider( Authentication authenticate(Authentication authentication) Membership membership = String username = String password = String[] roles = UsernamePasswordAuthenticationToken token = "password" supports(Class authentication.equals(UsernamePasswordAuthenticationToken. auth.userDetailsService( UserDetails loadUserByUsername(String username) Membership membership = UserDetails user = User(username,"password" Collection GrantedAuthority> List list = ArrayList list.add( }

2.使用@PreAuthorize在Controller级别通过角色控制权限

(1)使用@PreAuthorize("isAuthenticated()")注解验证登录

@PreAuthorize("isAuthenticated()" @RequestMapping(value = "/account" "account" }

(2)使用@PreAuthorize("hasAuthority('admin')")注解验证角色

@PreAuthorize("hasAuthority('admin')" @RequestMapping("/admin" "admin" }

3.登录和注销功能

注销直接使用内置功能,登录可以自定义控制器和视图。

@RequestMapping(value = "/login" String login(@RequestParam(value = "error",required = @ModelAttribute("model" (error != result.rejectValue("userName","","Invalid username and password!" "login" }

视图:

Getting Started: Serving Web Content Login Form has errors userName password rememberMe

4.Spring Security核心对象

验证和授权的核心的ASP.NET肯定是HttpModule,Java是Filter,这没什么可说的,到现在两套组合(HttpApplicaiton+HttpModule+HttpHandler)(ServletContext+Filter+Servlet)的核心概念已经熟练了。

(1)安全上下文

ASP.NET中我们可以通过HttpContext.User获取IPrincipal的实例,这是通过HttpModuel(FormsAuthenticationModule)机制实现的。Spring Security中获取SecurityContext也是通过对应的Filter(SecurityContextPersistenceFilter)机制实现的。SecurityContextPersistenceFilter将功能委托给的实例实现,因此我们在上文自定义了SecurityContextRepository实现,刷新其中的角色信息。

(2)身份认证提供程序

AuthenticationProvider对象的authenticate方法验证并返回对象。Authentication对象是Java的Principal接口的子接口。上文自定义的AuthenticationProvider只是简单的将用户名username作为Authentication的实现类UsernamePasswordAuthenticationToken构造函数的参数传递,如果需要也可以传递其他object,调用时通过SecurityContextHolder.getContext().getAuthentication().getPrincipal()获取。

(3)用户信息提供程序

只有在AuthenticationProvider的实现中采用了UserDetailsService用于验证,UserDetailsService才是必须的。UserDetailsService返回一个用对象。在AuthenticationProvider中调用UserDetailsService,将UserDetails对象作为Principal参数传递给Authentication对象,这样我们可以在Controller中通过如下语句获取UserDetails对象。事实上只需要传递用户名作为Principal参数是最实用的,多搞一个自定义UserDetails还不如自定义POJO从Service中通过用户名返回信息来的干净快捷。即使使用UserDetails对象也不一定要使用UserDetailsService,可以直接在AuthenticationProvider中构造并传递UserDetails对象。上面代码的UserDetailsService只是作为演示,实际上不会被调用。

UserDetails userDetails = (UserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();

参考

(1)http://docs.spring.io/autorepo/docs/spring-security/3.2.x/guides/hellomvc.html

(2)http://docs.spring.io/spring-security/site/docs/4.0.4.CI-SNAPSHOT/reference/htmlsingle/

(3)http://docs.spring.io/spring/docs/current/spring-framework-reference/html/view.html

JAAS对核心的数据结构不关注,定义了一堆还不如没有的过程依赖,Spring Security虽然改进了易用性,但从JAAS中继承了不切实际的幻想风格。提供核心数据结构和接口就行了,非要从密码加密到用户信息获取一路跑偏到对缓存和数据库都能产生依赖,Spring基于Object的依赖注入已经不适用了,Spring Security又偏离了核心。内置的不合理,外置的很难用,整合这个词就是整一堆框架合起来才能凑合用。什么时候基于类型的依赖注入框架能取代Spring、基于数据结构的验证框架能取代Spring Security,Java Web开发的生产力估计会提高一些。到现在我还没有找到可用的基于注解的前后端统一验证框架,没有这个东西,对于快速制作演示模型简直是灾难。不管怎么说,SSH这些东西至少要对其基础配置和核心对象有整体上的把握,至少要能快速定位开发中遇到的问题并基于对源代码的了解能应对实际中出现的大部分技术问题才行。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读