spring boot securitymybitis

xiaoxiao2021-02-28  106

.pom文件需要引入

<!--springboot--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>

配置中的URL不要入库,csrf token 默认是true

spring boot 的spring security配置代替spring mvc的spring security xxx.xml配置

@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private WebFilterSecurityInterceptor webFilterSecurityInterceptor; @Bean UserDetailsService customUserService(){ //注册UserDetailsService 的bean return new CustomUserService(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(customUserService()); //user Details Service验证 } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); // 禁用csrf token http.authorizeRequests() .anyRequest().authenticated() //任何请求,登录后可以访问 .and().authorizeRequests().antMatchers("/?logout").permitAll().anyRequest() .hasAnyRole("ANONYMOUS").and() .formLogin() .loginPage("/") .loginPage("/login") .failureUrl("/login?error") .and() .logout().logoutUrl("/?logout") .permitAll(); //注销行为任意访问 http.addFilterBefore(webFilterSecurityInterceptor, FilterSecurityInterceptor.class); }}

拦截器实现,根据需求实现。若之前的数据表和spring security不兼容,可以更具数据表的情况,对所有requestUrl放行,拦截特定的url。这里去掉实现逻辑。

@Service public class WebFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter { @Autowired private FilterInvocationSecurityMetadataSource securityMetadataSource; @Autowired public void setMyAccessDecisionManager(WebAccessDecisionManager webAccessDecisionManager) { super.setAccessDecisionManager(webAccessDecisionManager); } @Override public void init(FilterConfig filterConfig) throws ServletException { } @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 { //fi里面有一个被拦截的url //里面调用MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法获取fi对应的所有权限 //再调用MyAccessDecisionManager的decide方法来校验用户的权限是否足够 InterceptorStatusToken token = super.beforeInvocation(fi); try { //执行下一个拦截器 fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); }catch ( Exception e ){ e.printStackTrace(); } finally { super.afterInvocation(token, null); } } @Override public void destroy() { } @Override public Class<?> getSecureObjectClass() { return FilterInvocation.class; } @Override public SecurityMetadataSource obtainSecurityMetadataSource() { return this.securityMetadataSource; } }加载已有requestUrl @Service public class WebInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource { @Autowired private IPermission permissionService; private HashMap<String, Collection<ConfigAttribute>> map = null; /** * 加载权限表中所有权限 */ public void loadResourceDefine() { map = new HashMap<>(); Collection<ConfigAttribute> array; ConfigAttribute cfg; List<Permission> permissions =null; JSONArray permissionArray=null; try { permissions=permissionService.getMenuList(1); } catch ( Exception e ) { e.printStackTrace(); } for (Permission permission : permissions) { array = new ArrayList<>(); cfg = new SecurityConfig(permission.getName()); //此处只添加了用户的名字,其实还可以添加更多权限的信息,例如请求方法到ConfigAttribute的集合中去。此处添加的信息将会作为MyAccessDecisionManager类的decide的第三个参数。 array.add(cfg); //用权限的getUrl() 作为map的key,用ConfigAttribute的集合作为 value, map.put(permission.getHref(), array); } } //此方法是为了判定用户请求的url 是否在权限表中,如果在权限表中,则返回给 decide 方法,用来判定用户是否有此权限。如果不在权限表中则放行。 @Override public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException { if (map == null) loadResourceDefine(); //object 中包含用户请求的request 信息 HttpServletRequest request = ((FilterInvocation) object).getHttpRequest(); AntPathRequestMatcher matcher; String resUrl; for (Iterator<String> iter = map.keySet().iterator(); iter.hasNext(); ) { resUrl = iter.next(); if (resUrl!=null) { matcher = new AntPathRequestMatcher(resUrl); if (matcher.matches(request)) { return map.get(resUrl); } } } return null; } @Override public Collection<ConfigAttribute> getAllConfigAttributes() { return null; } @Override public boolean supports(Class<?> clazz) { return true; } }

判断是否放行的地方,这里对所有requestUrl都放行,拦截器处控制重写

@Service public class WebAccessDecisionManager implements AccessDecisionManager { // decide 方法是判定是否拥有权限的决策方法, //authentication 是释CustomUserService中循环添加到 GrantedAuthority 对象中的权限信息集合. //object 包含客户端发起的请求的requset信息,可转换为 HttpServletRequest request = ((FilterInvocation) object).getHttpRequest(); //configAttributes 为MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法返回的结果,此方法是为了判定用户请求的url 是否在权限表中,如果在权限表中,则返回给 decide 方法,用来判定用户是否有此权限。如果不在权限表中则放行。 @Override public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException { if (null == configAttributes || configAttributes.size() <= 0) { return; } ConfigAttribute c; String needRole; for (Iterator<ConfigAttribute> iter = configAttributes.iterator(); iter.hasNext(); ) { c = iter.next(); needRole = c.getAttribute(); for (GrantedAuthority ga : authentication.getAuthorities()) {//authentication 为在注释1 中循环添加到 GrantedAuthority 对象中的权限信息集合 if (needRole.trim().equals(ga.getAuthority())) { return; } } } throw new AccessDeniedException("no right"); } @Override public boolean supports(ConfigAttribute attribute) { return true; } @Override public boolean supports(Class<?> clazz) { return true; } } 获取登陆用户权限列表,对重写拦截器是鸡肋。

@Service public class CustomUserService implements UserDetailsService { //自定义UserDetailsService 接口 @Autowired IUser userService; @Autowired IPermission permissionService; public UserDetails loadUserByUsername(String username) { User user = null; try { user = userService.oneByName(username); } catch ( Exception e ) { e.printStackTrace(); } if (user != null) { List<Permission> permissions = null; //**此处需将JSONArray菜单列表转化成List<Permission> try { permissions = permissionService.getMenuList(user.getId()); } catch ( Exception e ) { e.printStackTrace(); } List<GrantedAuthority> grantedAuthorities = new ArrayList<>(); for (Permission permission : permissions) { if (permission != null && permission.getName() != null) { GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(permission.getName()); //1:此处将权限信息添加到 GrantedAuthority 对象中,在后面进行全权限验证时会使用GrantedAuthority 对象。 grantedAuthorities.add(grantedAuthority); } } return new org.springframework.security.core.userdetails.User(user.getName(), user.getPassword(), grantedAuthorities); } else { throw new UsernameNotFoundException("admin: " + username + " do not exist!"); } } }

注:拦截器中执行特定的拦截和403 跳转。

转载请注明原文地址: https://www.6miu.com/read-39361.html

最新回复(0)