概述Spring Security虽然比JAAS进步很大,但还是先天不足,达不到ASP.NET中的认证和授权的方便快捷。这里演示登录、注销、记住我的常规功能,认证上自定义提供程序避免对数据库的依赖,授权上自定义提供程序消除从缓存加载角色信息造成的角色变更无效副作用。1.基于java config的Spring Security
基础配置(1)使用AbstractSecurityWebApplicationInitializer集成到Spring MVC1 public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {2 }(2)使用匿名类在WebSecurityConfigurerAdapter自定义AuthenticationProvider、UserDetailsService、SecurityContextRepository。1 @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)2 @EnableWebSecurity3 public class SecurityConfig extends WebSecurityConfigurerAdapter {45 @Override6 protected void configure(HttpSecurity http) throws Exception {7 http.authorizeRequests().antMatchers("/account**", "/admin**").authenticated();8 http.formLogin().usernameParameter("userName").passwordParameter("password").loginPage("/login")9 .loginProcessingUrl("/login").successHandler(new SavedRequestAwareAuthenticationSuccessHandler()).and()10 .logout().logoutUrl("/logout").logoutSuccessUrl("/");11 http.rememberMe().rememberMeParameter("rememberMe");12 http.csrf().disable();13 http.setSharedObject(SecurityContextRepository.class, new SecurityContextRepository() {1415 private HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();1617 @Override18 public SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder) {19 SecurityContext context = this.repo.loadContext(requestResponseHolder);20 if (context != null && context.getAuthentication() != null) {21 Membership membership = new Membership();22 String username = context.getAuthentication().getPrincipal().toString();23 String[] roles = membership.getRoles(username);24 context.getAuthentication().getAuthorities();25 UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username,26 "password", convertStringArrayToAuthorities(roles));27 context.setAuthentication(token);28 System.out.println("check user role");29 }30 return context;31 }3233 @Override34 public void saveContext(SecurityContext context, HttpServletRequest request, HttpServletResponse response) {35 this.repo.saveContext(context, request, response);36 }3738 @Override39 public boolean containsContext(HttpServletRequest request) {40 return this.repo.containsContext(request);41 }42 });43 }4445 @Autowired46 @Override47 protected void configure(AuthenticationManagerBuilder auth) throws Exception {48 auth.authenticationProvider(new AuthenticationProvider() {4950 @Override51 public Authentication authenticate(Authentication authentication) throws AuthenticationException {52 Membership membership = new Membership();53 String username = authentication.getName();54 String password = authentication.getCredentials().toString();55 if (membership.validateUser(username, password)) {56 String[] roles = membership.getRoles(username);57 UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username,58 "password", convertStringArrayToAuthorities(roles));59 return token;60 }61 return null;62 }6364 @Override65 public boolean supports(Class<?> authentication) {66 return authentication.equals(UsernamePasswordAuthenticationToken.class);67 }6869 });70 auth.userDetailsService(new UserDetailsService() {7172 @Override73 public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {74 Membership membership = new Membership();75 if (membership.hasUser(username)) {76 UserDetails user = new User(username, "password",77 convertStringArrayToAuthorities(membership.getRoles(username)));78 return user;79 }80 return null;81 }82 });83 }8485 public Collection<? extends GrantedAuthority> convertStringArrayToAuthorities(String[] roles) {86 List<SimpleGrantedAuthority> list = new ArrayList<SimpleGrantedAuthority>();87 for (String role : roles) {88 list.add(new SimpleGrantedAuthority(role));89 }90 return list;91 }92 }2.使用@PreAuthorize在Controller级别通过角色控制权限(1)使用@PreAuthorize("isAuthenticated()")注解验证登录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"