springboot集成security
来源:互联网 发布:调查问卷软件 编辑:程序博客网 时间:2024/05/17 13:09
接着上一篇( springboot 集成mybatis)继续搞,接下来集成security
首先还是添加pom依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>建表(如果TB_USER已经建了,则不需要再建)
CREATE TABLE `TB_USER` (`ID` varchar(32) NOT NULL ,`USER_NAME` varchar(32) NOT NULL ,`PASSWORD` varchar(32) NOT NULL ,`ENABLE` varchar(2) NOT NULL DEFAULT '1' ,`PHONE` varchar(11) NULL ,`EMAIL` varchar(32) NULL ,`EXTEND_FIELD` text NULL ,`CREATE_TIME` datetime NOT NULL DEFAULT now() ,`UPDATE_TIME` datetime NOT NULL DEFAULT now() ,PRIMARY KEY (`ID`));CREATE TABLE `TB_RESOURCE` ( `ID` varchar(32) NOT NULL, `FATHER_ID` varchar(32) NOT NULL, `CODE` varchar(32) NOT NULL, `TITLE` varchar(32) DEFAULT NULL, `URL` varchar(32) DEFAULT NULL, `ICON` varchar(32) DEFAULT NULL, `STATUS` varchar(2) DEFAULT NULL, `LEVEL` int(11) DEFAULT NULL, `CREATE_TIME` datetime DEFAULT now(), `UPDATE_TIME` datetime DEFAULT now(), PRIMARY KEY (`ID`));CREATE TABLE `TB_ROLE` ( `ID` varchar(32) NOT NULL, `NAME` varchar(32) NOT NULL, `DESCRIPTION` varchar(32) NOT NULL, `STATUS` varchar(2) DEFAULT NULL, `CREATE_TIME` datetime DEFAULT now(), `UPDATE_TIME` datetime DEFAULT now(), PRIMARY KEY (`ID`));CREATE TABLE `TB_ROLE_RESOURCE` ( `ID` varchar(32) NOT NULL, `ROLE_ID` varchar(32) NOT NULL, `RESOURCE_ID` varchar(32) NOT NULL, `STATUS` varchar(2) DEFAULT NULL, `CREATE_TIME` datetime DEFAULT now(), `UPDATE_TIME` datetime DEFAULT now(), PRIMARY KEY (`ID`));CREATE TABLE `TB_USER_ROLE` ( `ID` varchar(32) NOT NULL, `ROLE_ID` varchar(32) NOT NULL, `USER_ID` varchar(32) NOT NULL, `STATUS` varchar(2) DEFAULT NULL, `CREATE_TIME` datetime DEFAULT now(), `UPDATE_TIME` datetime DEFAULT now(), PRIMARY KEY (`ID`));
接下来是java安全验证相关的一些代码编辑
1.自定义SabUserDetailsService实现UserDetailsService接口,重写loadUserByUsername方法,可以从数据库读取
/** * override query user by user name */ @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { if (StringUtils.isEmpty(username)) { logger.error("username is empty"); throw new UsernameNotFoundException("username is empty"); } // query from cache // UserDetails user = userCache.get(username); springboot.demo.dmo.User user = userMapper.findByUserName(username); if (null == user) { logger.warn("get user is null, userName:{}", username); // return empty user return new User(username, "", new HashSet<GrantedAuthority>()); } Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>(); if (!CollectionUtils.isEmpty(user.getRoleList())) { for (Role role : user.getRoleList()) { GrantedAuthority auth = new SimpleGrantedAuthority(role.getName()); authorities.add(auth); } } // return user bean return new User(user.getUserName(), user.getPassword(), authorities); }
2.自定义SabSourceService实现FilterInvocationSecurityMetadataSource接口,启动是加载db数据到内存
@Componentpublic class SabSourceService implements FilterInvocationSecurityMetadataSource { @Autowired private ResourceMapper resourceMapper; private static Map<String, Collection<ConfigAttribute>> resourceMap = new ConcurrentHashMap<String, Collection<ConfigAttribute>>(); /* * 一定要加上@PostConstruct注解 在Web服务器启动时,提取系统中的所有权限。 */ @PostConstruct private void loadResourceDefine() { this.loadResource(); } public void loadResource(){ /* * 应当是资源为key, 权限为value。 资源通常为url, 权限就是那些以ROLE_为前缀的角色。 一个资源可以由多个权限来访问。 */ List<Resource> resList = resourceMapper.loadAll(); if (!CollectionUtils.isEmpty(resList)) { for (Resource resource : resList) { List<ConfigAttribute> attList = new ArrayList<ConfigAttribute>(); if (!CollectionUtils.isEmpty(resource.getRoleList())) { for (Role role : resource.getRoleList()) { ConfigAttribute ca = new SecurityConfig(role.getName()); attList.add(ca); } } resourceMap.put(resource.getUrl(), attList); } } } @Override public Collection<ConfigAttribute> getAllConfigAttributes() { return new ArrayList<ConfigAttribute>(); } @Override public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException { FilterInvocation filterInvocation = (FilterInvocation) object; if (resourceMap == null) { loadResourceDefine(); } Iterator<String> ite = resourceMap.keySet().iterator(); while (ite.hasNext()) { String resURL = ite.next(); RequestMatcher requestMatcher = new AntPathRequestMatcher(resURL); if (requestMatcher.matches(filterInvocation.getHttpRequest())) { return resourceMap.get(resURL); } } return null; } @Override public boolean supports(Class<?> clazz) { return true; }}
3.自定义SabAccessDecisionManager实现AccessDecisionManager接口,重写decide方法,自定义权限规则
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(); for (GrantedAuthority ga : authentication.getAuthorities()) { if (needRole.trim().equals(ga.getAuthority().trim())) { return; } } } throw new AccessDeniedException("权限不足"); }
4.自定义拦截器SabSecurityInterceptor集成FilterSecurityInterceptor
@Componentpublic class SabSecurityInterceptor extends FilterSecurityInterceptor{@Resource(name = "sabSourceService") private SabSourceService sourceService; @Resource(name = "authenticationManager") private AuthenticationManager authenticationManager; @Resource(name = "sabAccessDecisionManager") private SabAccessDecisionManager accessDecisionManager; @PostConstruct public void init() { super.setAuthenticationManager(authenticationManager); super.setAccessDecisionManager(accessDecisionManager); } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { FilterInvocation fi = new FilterInvocation(request, response, chain); if (SecurityContextHolder.getContext().getAuthentication() == null || null == fi || fi.getRequestUrl().contains(".js") || fi.getRequestUrl().contains(".css")) { chain.doFilter(request, response); } else { 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); } } @Override public Class<?> getSecureObjectClass() { return FilterInvocation.class; } @Override public SecurityMetadataSource obtainSecurityMetadataSource() { return sourceService; } @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } @Override public void destroy() { // TODO Auto-generated method stub }}
5.自定义SecurityConfig继承WebSecurityConfigurerAdapter,重写configure方法,这里面的权限校验的规则配置
@Configuration@EnableWebSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter {@Resource(name = "sabUserDetailsService")UserDetailsService userDetailsService;@Resource(name = "sabSecurityInterceptor")FilterSecurityInterceptor securityInterceptor;@Autowiredpublic void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService);}/** * base config */@Overrideprotected void configure(HttpSecurity http) throws Exception {http.headers().frameOptions().disable();http.addFilterBefore(securityInterceptor, FilterSecurityInterceptor.class)// 在正确的位置添加我们自定义的过滤器.authorizeRequests().antMatchers("/reloadResource").permitAll() // 刷新资源权限.antMatchers("/**.*").authenticated()// .后缀认证.and().formLogin().loginPage("/login").loginProcessingUrl("/login").usernameParameter("username").passwordParameter("password").defaultSuccessUrl("/loginSuccess").failureUrl("/loginFail").and().logout().logoutSuccessUrl("/login").logoutUrl("/logout")// login.and().exceptionHandling().accessDeniedPage("/403")//.and().csrf().disable() // disable csrf.rememberMe().tokenRepository(new InMemoryTokenRepositoryImpl()).tokenValiditySeconds(86400);// remember// me}/** * fliter ignoring ,such as static */@Overridepublic void configure(WebSecurity web) throws Exception {web.ignoring().antMatchers("/resources/**");}}
@RequestMapping("login")public ModelAndView login() {return new ModelAndView("login");}@RequestMapping("logout")public String logout(HttpServletRequest request) {try {request.logout();} catch (ServletException e) {e.printStackTrace();}return "redirect:/login";}
至此已经基本完成,访问应用,发现跳转login页面,输入维护在库里面的用户名、密码即可登录,ddl,dml可以参考下面源码
git clone https://github.com/cm-jornada/demo.gitgit checkout security
阅读全文
0 0
- 集成springboot-starter-security
- springboot集成security
- springboot集成spring security初探
- Springboot集成Security设置defaultSuccessUrl()不起作用问题
- springboot spring-security 集成微信登录
- SpringBoot集成Security(实现自定义表单,自定义验证)
- springboot集成spring security初探2--从数据库读取用户权限
- Springboot security
- springboot security CSRF问题
- SpringBoot - Spring Security学习
- springboot+mybatis实现security
- springboot+mybatis+spring security
- springboot+security框架整合
- SpringBoot~Spring Security入门
- springboot整合spring-security
- Spring security集成CAS
- SpringBoot配置属性之Security
- springboot+security 的BCryptPasswordEncoder 使用
- 网络基础 — OSI七层协议模型、TCP/IP四层模型
- POJ1066---Treasure Hunt (计算几何基础:线段相交)
- [未完待续][NOI2017模拟]大新闻
- Count Color POJ 2777
- MRP运行(MD01-MD03) MRP控制参数
- springboot集成security
- C#动态生成XML
- use tpm2-abrmd on RHEL7.3
- struts2文件上传Demo
- List object in Python
- LC的课后辅导 QDU
- ACM日记_17.5.01——矩阵快速幂整理(例题i:Fibonacci POJ
- Spring中Bean的简单属性注入
- 中文分词的python实现-基于HMM算法