mirror of
				https://github.com/dromara/RuoYi-Vue-Plus.git
				synced 2025-11-04 16:23:42 +08:00 
			
		
		
		
	新增Anonymous匿名访问不鉴权注解
This commit is contained in:
		@@ -0,0 +1,19 @@
 | 
			
		||||
package com.ruoyi.common.annotation;
 | 
			
		||||
 | 
			
		||||
import java.lang.annotation.Documented;
 | 
			
		||||
import java.lang.annotation.ElementType;
 | 
			
		||||
import java.lang.annotation.Retention;
 | 
			
		||||
import java.lang.annotation.RetentionPolicy;
 | 
			
		||||
import java.lang.annotation.Target;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 匿名访问不鉴权注解
 | 
			
		||||
 * 
 | 
			
		||||
 * @author ruoyi
 | 
			
		||||
 */
 | 
			
		||||
@Target({ ElementType.METHOD, ElementType.TYPE })
 | 
			
		||||
@Retention(RetentionPolicy.RUNTIME)
 | 
			
		||||
@Documented
 | 
			
		||||
public @interface Anonymous
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
@@ -8,12 +8,14 @@ import org.springframework.security.config.annotation.authentication.builders.Au
 | 
			
		||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
 | 
			
		||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 | 
			
		||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
 | 
			
		||||
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
 | 
			
		||||
import org.springframework.security.config.http.SessionCreationPolicy;
 | 
			
		||||
import org.springframework.security.core.userdetails.UserDetailsService;
 | 
			
		||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 | 
			
		||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
 | 
			
		||||
import org.springframework.security.web.authentication.logout.LogoutFilter;
 | 
			
		||||
import org.springframework.web.filter.CorsFilter;
 | 
			
		||||
import com.ruoyi.framework.config.properties.PermitAllUrlProperties;
 | 
			
		||||
import com.ruoyi.framework.security.filter.JwtAuthenticationTokenFilter;
 | 
			
		||||
import com.ruoyi.framework.security.handle.AuthenticationEntryPointImpl;
 | 
			
		||||
import com.ruoyi.framework.security.handle.LogoutSuccessHandlerImpl;
 | 
			
		||||
@@ -55,7 +57,13 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
 | 
			
		||||
     */
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private CorsFilter corsFilter;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 允许匿名访问的地址
 | 
			
		||||
     */
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private PermitAllUrlProperties permitAllUrl;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 解决 无法直接注入 AuthenticationManager
 | 
			
		||||
     *
 | 
			
		||||
@@ -87,6 +95,10 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void configure(HttpSecurity httpSecurity) throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        // 注解标记允许匿名访问的url
 | 
			
		||||
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = httpSecurity.authorizeRequests();
 | 
			
		||||
        permitAllUrl.getUrls().forEach(url -> registry.antMatchers(url).permitAll());
 | 
			
		||||
 | 
			
		||||
        httpSecurity
 | 
			
		||||
                // CSRF禁用,因为不使用session
 | 
			
		||||
                .csrf().disable()
 | 
			
		||||
@@ -98,24 +110,14 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
 | 
			
		||||
                .authorizeRequests()
 | 
			
		||||
                // 对于登录login 注册register 验证码captchaImage 允许匿名访问
 | 
			
		||||
                .antMatchers("/login", "/register", "/captchaImage").anonymous()
 | 
			
		||||
                .antMatchers(
 | 
			
		||||
                        HttpMethod.GET,
 | 
			
		||||
                        "/",
 | 
			
		||||
                        "/*.html",
 | 
			
		||||
                        "/**/*.html",
 | 
			
		||||
                        "/**/*.css",
 | 
			
		||||
                        "/**/*.js",
 | 
			
		||||
                        "/profile/**"
 | 
			
		||||
                ).permitAll()
 | 
			
		||||
                .antMatchers("/swagger-ui.html").anonymous()
 | 
			
		||||
                .antMatchers("/swagger-resources/**").anonymous()
 | 
			
		||||
                .antMatchers("/webjars/**").anonymous()
 | 
			
		||||
                .antMatchers("/*/api-docs").anonymous()
 | 
			
		||||
                .antMatchers("/druid/**").anonymous()
 | 
			
		||||
                // 静态资源,可匿名访问
 | 
			
		||||
                .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
 | 
			
		||||
                .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
 | 
			
		||||
                // 除上面外的所有请求全部需要鉴权认证
 | 
			
		||||
                .anyRequest().authenticated()
 | 
			
		||||
                .and()
 | 
			
		||||
                .headers().frameOptions().disable();
 | 
			
		||||
        // 添加Logout filter
 | 
			
		||||
        httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler);
 | 
			
		||||
        // 添加JWT filter
 | 
			
		||||
        httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,72 @@
 | 
			
		||||
package com.ruoyi.framework.config.properties;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
import java.util.regex.Pattern;
 | 
			
		||||
import org.apache.commons.lang3.RegExUtils;
 | 
			
		||||
import org.springframework.beans.BeansException;
 | 
			
		||||
import org.springframework.beans.factory.InitializingBean;
 | 
			
		||||
import org.springframework.context.ApplicationContext;
 | 
			
		||||
import org.springframework.context.ApplicationContextAware;
 | 
			
		||||
import org.springframework.context.annotation.Configuration;
 | 
			
		||||
import org.springframework.core.annotation.AnnotationUtils;
 | 
			
		||||
import org.springframework.web.method.HandlerMethod;
 | 
			
		||||
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
 | 
			
		||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
 | 
			
		||||
import com.ruoyi.common.annotation.Anonymous;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 设置Anonymous注解允许匿名访问的url
 | 
			
		||||
 * 
 | 
			
		||||
 * @author ruoyi
 | 
			
		||||
 */
 | 
			
		||||
@Configuration
 | 
			
		||||
public class PermitAllUrlProperties implements InitializingBean, ApplicationContextAware
 | 
			
		||||
{
 | 
			
		||||
    private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}");
 | 
			
		||||
 | 
			
		||||
    private ApplicationContext applicationContext;
 | 
			
		||||
 | 
			
		||||
    private List<String> urls = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
    public String ASTERISK = "*";
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void afterPropertiesSet()
 | 
			
		||||
    {
 | 
			
		||||
        RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
 | 
			
		||||
        Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();
 | 
			
		||||
 | 
			
		||||
        map.keySet().forEach(info -> {
 | 
			
		||||
            HandlerMethod handlerMethod = map.get(info);
 | 
			
		||||
 | 
			
		||||
            // 获取方法上边的注解 替代path variable 为 *
 | 
			
		||||
            Anonymous method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Anonymous.class);
 | 
			
		||||
            Optional.ofNullable(method).ifPresent(anonymous -> info.getPatternsCondition().getPatterns()
 | 
			
		||||
                    .forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK))));
 | 
			
		||||
 | 
			
		||||
            // 获取类上边的注解, 替代path variable 为 *
 | 
			
		||||
            Anonymous controller = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), Anonymous.class);
 | 
			
		||||
            Optional.ofNullable(controller).ifPresent(anonymous -> info.getPatternsCondition().getPatterns()
 | 
			
		||||
                    .forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK))));
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void setApplicationContext(ApplicationContext context) throws BeansException
 | 
			
		||||
    {
 | 
			
		||||
        this.applicationContext = context;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<String> getUrls()
 | 
			
		||||
    {
 | 
			
		||||
        return urls;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setUrls(List<String> urls)
 | 
			
		||||
    {
 | 
			
		||||
        this.urls = urls;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user