一、基於ACCESS方法處理的實現:
我們之前使用的任何放行規則的方法,本質上還是調用access方法執行的
這也意味之我們可以直接使用access方法去方向,只需要注入不同的字符串即可
自定義Access實現:
業務層自定義接口:
package cn.zeal4j.service; import org.springframework.security.core.Authentication; import javax.servlet.http.HttpServletRequest; /** * @author Administrator * @file IntelliJ IDEA Spring-Security-Tutorial * @create 2020 09 28 20:17 */ public interface CustomService { Boolean hasPermission(HttpServletRequest httpServletRequest, Authentication authentication); }
實現類:
package cn.zeal4j.service; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import javax.servlet.http.HttpServletRequest; import java.util.Collection; /** * @author Administrator * @file IntelliJ IDEA Spring-Security-Tutorial * @create 2020 09 28 20:20 */ public class CustomServiceImpl implements CustomService{ @Override public Boolean hasPermission(HttpServletRequest httpServletRequest, Authentication authentication) { // 用戶信息對象 Object principal = authentication.getPrincipal(); if (principal instanceof UserDetails) { UserDetails userDetails = (UserDetails) principal; Collection<? extends GrantedAuthority> authorities = userDetails.getAuthorities(); return authorities.contains(new SimpleGrantedAuthority(httpServletRequest.getRequestURI())); } return false; } }
Access配置:
package cn.zeal4j.configuration; import cn.zeal4j.handler.CustomAccessDeniedHandler; import cn.zeal4j.handler.FarsAuthenticationFailureHandler; import cn.zeal4j.handler.FarsAuthenticationSuccessHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.access.AccessDeniedHandler; /** * @author Administrator * @file IntelliJ IDEA Spring-Security-Tutorial * @create 2020 09 27 21:55 */ @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired private AccessDeniedHandler accessDeniedHandler; @Bean public PasswordEncoder getPasswordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(HttpSecurity httpSecurity) throws Exception { httpSecurity.formLogin(). // 設置登陸行為方式為表單登陸 // 登陸請求參數設置 usernameParameter("username"). passwordParameter("password"). loginPage("/login.html"). // 設置登陸頁面URL路徑 loginProcessingUrl("/login.action"). // 設置表單提交URL路徑 // successForwardUrl("/main.page"). // 設置認證成功跳轉URL路徑 POST請求 successHandler(new FarsAuthenticationSuccessHandler("https://www.acfun.cn/")). // 使用自定義的重定向登陸 // failureForwardUrl("/error.page"); // 設置認證失敗跳轉URL路徑 POST請求 failureHandler(new FarsAuthenticationFailureHandler("/error.html")); // 跨域處理,不需要跳轉了 httpSecurity.authorizeRequests(). regexMatchers(HttpMethod.POST, "正則表達式").permitAll(). // 還可以對符合正則表達式的請求方式進行要求,這個屬性使用來制定請求的方式 antMatchers("/**/*.js", "/**/*.css", "/**/images/*.*").permitAll(). // 靜態資源放行 antMatchers("/login.html").permitAll(). // 登陸頁面允許任意訪問 antMatchers("/error.html").permitAll(). // 失敗跳轉后重定向的頁面也需要被允許訪問 antMatchers("/admin.page").hasAnyAuthority("admin"). /*antMatchers("/vip-01.page").hasAnyAuthority("vip-01").*/ antMatchers("/vip-01.page").hasRole("vip-01"). antMatchers("/ip.page").hasIpAddress("192.168.43.180"). // mvcMatchers("/main.page").servletPath("/xxx").permitAll(). // mvcMatchers資源放行匹配 // antMatchers("/xxx/main.page").permitAll(). // 或者多寫MSP的前綴 anyRequest().authenticated(). // 其他請求均需要被授權訪問 anyRequest().access("@customServiceImpl.hasPermission(httpServletRequest, authentication)"); // 自定義Access配置 // CSRF攻擊攔截關閉 httpSecurity.csrf().disable(); httpSecurity.exceptionHandling().accessDeniedHandler(accessDeniedHandler); } }
這個授權邏輯只允許賦予了對應的接口地址和的才能訪問,像默認訪問的index頁面就會報錯
二、@Secured注解:
package org.springframework.security.access.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface Secured { String[] value(); }
該注解可以標記的位置,方法和類上面
可以聲名的值是一個字符串數組
官方的解釋:
用於聲名角色權限控制,判斷訪問此方法是否具備注解中的角色,參數值必須以ROLE_開頭
具體使用:
二、@PreAuthorize & @PostAuthorize:
@PreAuthorize 用於在方法或者類之前先判斷權限,參數和access方法相同
@PostAuthorize 恰恰相反,在方法和類執行之后判斷
使用這些注解需要在啟動類中打上@EnableGlobalMethodSecurity
內部字符串會被讀取到,和在配置類中設置是差不多的
當然和配置類不同的是,該注解允許方法注入大寫的角色權限前綴,例如ROLE_vip-01