spring boot 中spring security使用数据库保存权限
2017-12-24 10:44
1101 查看
WebSecurityConfig
package com.maven; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.access.AccessDecisionManager; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl; import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import com.maven.security.MyFilterSecurityInterceptor; @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter{ @Autowired private DataSource dataSource; @Autowired @Qualifier("myUserDetailsService") private UserDetailsService userDetailsService; @Autowired @Qualifier("myAccessDecisionManager") private AccessDecisionManager accessDecisionManager; @Autowired @Qualifier("mySecurityMetadataSource") private FilterInvocationSecurityMetadataSource securityMetadataSource; @Autowired private AuthenticationManagerBuilder authenticationManagerBuilder; private AuthenticationManager authenticationManager; @Override protected void configure(HttpSecurity http) throws Exception { http //自定义过滤器,把资源配置存放到数据库中 .addFilterBefore(filter(),FilterSecurityInterceptor.class) .exceptionHandling() .and() .formLogin() .loginPage("/login") .defaultSuccessUrl("/home") .and() .logout() .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) .logoutSuccessUrl("/login?logout") .invalidateHttpSession(true) .deleteCookies("remember-me") .and() .rememberMe() .tokenRepository(tokenRepository()) .tokenValiditySeconds(1209600)//默认2周 .rememberMeCookieName("remember-me") .userDetailsService(userDetailsService) .rememberMeParameter("remember-me"); } private PersistentTokenRepository tokenRepository() { JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl(); tokenRepository.setDataSource(dataSource); return tokenRepository; } // 配置AuthenticationManager @Bean public AuthenticationManager authenticationManagerBean() { authenticationManagerBuilder.authenticationProvider(authenticationProvider()); return authenticationManagerBuilder.getOrBuild(); } // 获取AuthenticationManager,避免多次调用authenticationManagerBean() public AuthenticationManager getAuthenticationManager() { if (this.authenticationManager == null) { return authenticationManagerBean(); } else { return this.authenticationManager; } } // 自定义JpaFilterSecurityInterceptor过滤器 public MyFilterSecurityInterceptor filter() throws Exception { MyFilterSecurityInterceptor filter = new MyFilterSecurityInterceptor(); // 认证管理器,实现用户认证的入口 filter.setAuthenticationManager(getAuthenticationManager()); // 访问决策器,决定某个用户具有的角色,是否有足够的权限去访问某个资源 filter.setAccessDecisionManager(accessDecisionManager); // 资源源数据定义,即定义某一资源可以被哪些角色访问 filter.setSecurityMetadataSource(securityMetadataSource); return filter; } // 配置DaoAuthenticationProvider public DaoAuthenticationProvider authenticationProvider() { DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(); // 设置不隐藏UserNotFoundExceptions authenticationProvider.setHideUserNotFoundExceptions(false); // 设置自定义UserDetailsService authenticationProvider.setUserDetailsService(userDetailsService); // 设置密码加密方式 BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); authenticationProvider.setPasswordEncoder(passwordEncoder); return authenticationProvider; } }
MyAccessDecisionManager
/** * copyright by liukai */ package com.maven.security; import java.util.Collection; import java.util.Iterator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.access.AccessDecisionManager; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; import org.springframework.security.authentication.InsufficientAuthenticationException; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.stereotype.Service; @Service("myAccessDecisionManager") public class MyAccessDecisionManager implements AccessDecisionManager{ private final static Logger logger = LoggerFactory.getLogger(MyAccessDecisionManager.class); /* (non-Javadoc) * @see org.springframework.security.access.AccessDecisionManager#decide(org.springframework.security.core.Authentication, java.lang.Object, java.util.Collection) */ @Override public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException { if (configAttributes == null) { return; //如果访问资源不需要任何权限则直接通过 } //所请求的资源拥有的权限(一个资源对多个权限) Iterator<ConfigAttribute> ite = configAttributes.iterator(); while (ite.hasNext()) { ConfigAttribute ca = ite.next(); String needRole = ((SecurityConfig) ca).getAttribute(); // ga 为用户所被赋予的权限。 needRole 为访问相应的资源应该具有的权限。 for (GrantedAuthority ga : authentication.getAuthorities()) { logger.info("该资源所需要的权限是:"+needRole +",当前用户的权限是:"+ ga.getAuthority()); if (needRole.trim().equals(ga.getAuthority().trim())) { return; } } } logger.info("权限不足,无法访问!"); throw new AccessDeniedException("不允许访问!"); } /* (non-Javadoc) * @see org.springframework.security.access.AccessDecisionManager#supports(org.springframework.security.access.ConfigAttribute) */ @Override public boolean supports(ConfigAttribute attribute) { return true; } /* (non-Javadoc) * @see org.springframework.security.access.AccessDecisionManager#supports(java.lang.Class) */ @Override public boolean supports(Class<?> clazz) { return true; } }
MyFilterSecurityInterceptor
/** * copyright by liukai */ package com.maven.security; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import org.springframework.security.access.SecurityMetadataSource; import org.springframework.security.access.intercept.AbstractSecurityInterceptor; import org.springframework.security.access.intercept.InterceptorStatusToken; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter{ private FilterInvocationSecurityMetadataSource securityMetadataSource; /** * @return the securityMetadataSource */ public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() { return securityMetadataSource; } /** * @param securityMetadataSource the securityMetadataSource to set */ public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource securityMetadataSource) { this.securityMetadataSource = securityMetadataSource; } /* (non-Javadoc) * @see org.springframework.security.access.intercept.AbstractSecurityInterceptor#getSecureObjectClass() */ @Override public Class<?> getSecureObjectClass() { return FilterInvocation.class; } /* (non-Javadoc) * @see org.springframework.security.access.intercept.AbstractSecurityInterceptor#obtainSecurityMetadataSource() */ @Override public SecurityMetadataSource obtainSecurityMetadataSource() { return securityMetadataSource; } /* (non-Javadoc) * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) */ @Override public void init(FilterConfig filterConfig) throws ServletException { } /* (non-Javadoc) * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) */ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { FilterInvocation fi = new FilterInvocation(request, response, chain); invoke(fi); } public void invoke(FilterInvocation fi) throws IOException, ServletException { InterceptorStatusToken token = super.beforeInvocation(fi); try { fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); } finally { super.afterInvocation(token, null); } } /* (non-Javadoc) * @see javax.servlet.Filter#destroy() */ @Override public void destroy() { } }
MySecurityMetadataSource
/** * copyright by liukai */ package com.maven.security; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; import org.springframework.stereotype.Service; import org.springframework.util.AntPathMatcher; import com.maven.auth.service.AuthService; @Service("mySecurityMetadataSource") public class MySecurityMetadataSource implements FilterInvocationSecurityMetadataSource{ private final static Logger logger = LoggerFactory.getLogger(MySecurityMetadataSource.class); private static Map<String, Collection<ConfigAttribute>> resourceMap = null; public MySecurityMetadataSource(AuthService authService) { //查询所有资源路径和角色 List<Map<String,Object>> resourceRoles = authService.findAllResourceAndRole(); //根据URL组装权限Map key为URL,集合为权限集合 resourceMap = new HashMap<String, Collection<ConfigAttribute>>(); for(Map<String,Object> resourceRole :resourceRoles) { ConfigAttribute ca = new SecurityConfig((String) resourceRole.get("CODE")); String url = (String) resourceRole.get("PATH"); if (resourceMap.containsKey(url)) { Collection<ConfigAttribute> value = resourceMap.get(url); value.add(ca); resourceMap.put(url, value); } else { Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>(); atts.add(ca); resourceMap.put(url, atts); } } } /* (non-Javadoc) * @see org.springframework.security.access.SecurityMetadataSource#getAttributes(java.lang.Object) */ @Override public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException { // object 是一个URL,被用户请求的url。 String url = ((FilterInvocation) object).getRequestUrl(); int firstQuestionMarkIndex = url.indexOf("?"); if (firstQuestionMarkIndex != -1) { url = url.substring(0, firstQuestionMarkIndex); } Iterator<String> ite = resourceMap.keySet().iterator(); AntPathMatcher matcher = new AntPathMatcher(); matcher.setTrimTokens(false); while (ite.hasNext()) { String resURL = ite.next(); if (matcher.match(resURL, url)) { logger.info("资源配置URL为"+resURL+"请求的URL为:"+url); return resourceMap.get(resURL); } } return null; } /* (non-Javadoc) * @see org.springframework.security.access.SecurityMetadataSource#getAllConfigAttributes() */ @Override public Collection<ConfigAttribute> getAllConfigAttributes() { // TODO Auto-generated method stub return null; } /* (non-Javadoc) * @see org.springframework.security.access.SecurityMetadataSource#supports(java.lang.Class) */ @Override public boolean supports(Class<?> clazz) { // TODO Auto-generated method stub return true; } }
MyUserDetailsService
package com.maven.security; import java.util.ArrayList; import java.util.List; import javax.transaction.Transactional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import com.maven.auth.dao.UserDao; import com.maven.auth.entity.Role; import com.maven.auth.entity.User; @Transactional @Service("myUserDetailsService") public class MyUserDetailsService implements UserDetailsService{ @Autowired private UserDao userDao; /* (non-Javadoc) * @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String) */ @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = this.userDao.findByUsername(username); if(user==null) { throw new UsernameNotFoundException("用户"+username+"不存在!"); } List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); List<Role> roles = user.getRoles(); for(Role role:roles) { authorities.add(new SimpleGrantedAuthority(role.getCode())); } UserDetails userDetails = new org.springframework.security.core.userdetails.User(user.getUsername(),user.getPassword(),authorities); return userDetails; } }
相关文章推荐
- 在Spring Boot中使用Spring Security实现权限控制
- 在Spring Boot中使用Spring Security实现权限控制
- 在Spring Boot中使用Spring Security实现权限控制
- Spring Boot集成Security使用数据库用户角色权限用户名问题
- Spring Boot集成Security使用数据库用户角色权限ROLE_问题
- 在Spring Boot中使用Spring Security实现权限控制
- SpringBoot中使用Spring Security实现权限控制
- 在Spring Boot中使用Spring Security实现权限控制
- 在Spring Boot中使用Spring Security实现权限控制
- 本文主要介绍使用SpringBoot与shiro实现基于数据库的细粒度动态权限管理系统实例。
- Spring Boot中使用 Spring Security 构建权限系统的示例代码
- 在Spring Boot中使用Spring Security实现权限控制
- Spring Boot中使用Spring Security实现权限控制
- 在Spring Boot中使用Spring Security实现权限控制
- Spring Boot中使用 Spring Security 构建权限系统
- Spring Boot中使用JdbcTemplate访问数据库
- SpringBoot使用JPA操作数据库
- Spring Boot Shiro 权限信息缓存处理,记住我,thymleaf使用shiro标签
- springboot+springmvc+mybatis 使用注解对数据库的增、改和查操作
- Spring Boot-使用Spring Data JPA简化数据库访问