security antMatchers(HttpMethod method, String... antPatterns)实现特定注解无需登录认证功能

场景

项目中某些接口不需要认证, 通过注解实现相对于其他的security配置会更灵活。

解决方案

  1. 按照HTTP方法的维度 获取到uri集合
  2. 使用antMatchers(HttpMethod method, String… antPatterns) 完成搜集的uri配置

antMatchers(HttpMethod method, String… antPatterns) 是 Spring Security 中用于配置 特定 HTTP 方法和 URL 模式的安全规则。

HttpMethod method 表示要匹配的 HTTP 方法(例如 GET、POST、PUT 等)。
String… antPatterns 表示要匹配的 URL 模式,可以指定多个模式。 可以设置成ur数组

下面是个例子

http
            .authorizeRequests()
                .antMatchers(HttpMethod.GET, "/public/**").permitAll()  // 允许GET请求访问/public/**路径
                .antMatchers(HttpMethod.POST, "/admin/**").hasRole("ADMIN")  // 需要ADMIN角色才能POST访问/admin/**路径
                .anyRequest().authenticated()  // 其他请求需要进行身份验证

代码实现

  1. 获取PermitAll注解修饰的uri
    /**
     * 获取被PermitAll注解修饰的url地址
     * */
    private Multimap<RequestMethod, String> getUrlsFormPermitAllAnnotation() {
        Multimap<RequestMethod, String> methodMap = HashMultimap.create();

        RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping) applicationContext.getBean("requestMappingHandlerMapping");
        for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : requestMappingHandlerMapping.getHandlerMethods().entrySet()) {
            HandlerMethod method = entry.getValue();
            if (!method.hasMethodAnnotation(PermitAll.class)) {
                continue;
            }
            if (entry.getKey().getPatternsCondition() == null) {
                continue;
            }

            Set<String> url = entry.getKey().getPatternsCondition().getPatterns();

            for (RequestMethod requestMethod : entry.getKey().getMethodsCondition().getMethods()) {
                methodMap.putAll(requestMethod, url);
            }
        }
        log.info("PermitAll注解修饰的urls {}", methodMap);

        return methodMap;
    }
  1. 将uri设置成无需认证
        Multimap<RequestMethod, String> permitAllUrlMap = getUrlsFormPermitAllAnnotation();
        // 设置具体请求的权限
        httpSecurity.authorizeRequests()
                .antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js").permitAll() // 静态资源无需认证
                .antMatchers("/websocket/message").permitAll() // websocket无需认证
                .antMatchers(HttpMethod.GET, permitAllUrlMap.get(RequestMethod.GET).toArray(new String[0])).permitAll()
                .antMatchers(HttpMethod.POST, permitAllUrlMap.get(RequestMethod.POST).toArray(new String[0])).permitAll()
                .antMatchers(HttpMethod.PUT, permitAllUrlMap.get(RequestMethod.PUT).toArray(new String[0])).permitAll()
                .antMatchers(HttpMethod.DELETE, permitAllUrlMap.get(RequestMethod.DELETE).toArray(new String[0])).permitAll()
                .and().authorizeRequests().anyRequest().authenticated(); // 其他请求必须认证

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我来给你讲一下使用注解装配实现登录注册功能的步骤。 1. 首先,在你的项目中添加 Spring Security 和 Spring MVC 的依赖。 2. 在 Spring Security 的配置类中使用注解开启安全验证,并配置登录页面、认证成功后跳转的页面等。 ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { // 忽略静态资源的验证 @Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers("/js/**", "/css/**", "/images/**"); } // 配置登录页面、认证成功后跳转的页面等 @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/login", "/register").anonymous() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .defaultSuccessUrl("/home") .permitAll() .and() .logout() .logoutUrl("/logout") .logoutSuccessUrl("/login") .invalidateHttpSession(true) .deleteCookies("JSESSIONID"); } // 配置用户认证方式 @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user").password("123456").roles("USER") .and() .withUser("admin").password("admin").roles("ADMIN"); } } ``` 3. 在 Spring MVC 的配置类中使用注解开启组件扫描,并配置视图解析器、拦截器等。 ```java @Configuration @EnableWebMvc @ComponentScan(basePackages = "com.example.demo") public class MvcConfig implements WebMvcConfigurer { // 配置视图解析器 @Override public void configureViewResolvers(ViewResolverRegistry registry) { registry.jsp("/WEB-INF/views/", ".jsp"); } // 配置拦截器 @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor()) .addPathPatterns("/**") .excludePathPatterns("/login", "/register", "/logout"); } } ``` 4. 在控制器中使用注解处理登录、注册请求。 ```java @Controller public class UserController { @GetMapping("/login") public String login() { return "login"; } @PostMapping("/login") public String doLogin(String username, String password) { // 处理登录请求 return "redirect:/home"; } @GetMapping("/register") public String register() { return "register"; } @PostMapping("/register") public String doRegister(String username, String password) { // 处理注册请求 return "redirect:/login"; } @GetMapping("/home") public String home() { return "home"; } } ``` 5. 最后,在登录页面和注册页面中使用 Thymeleaf 模板引擎的表单绑定和注解校验。 ```html <form th:action="@{/login}" method="post"> <div> <label>用户名:</label> <input type="text" name="username" th:field="*{username}" required /> </div> <div> <label>密码:</label> <input type="password" name="password" th:field="*{password}" required /> </div> <button type="submit">登录</button> </form> <form th:action="@{/register}" method="post"> <div> <label>用户名:</label> <input type="text" name="username" th:field="*{username}" required /> </div> <div> <label>密码:</label> <input type="password" name="password" th:field="*{password}" required /> </div> <button type="submit">注册</button> </form> ``` 这样就可以使用注解装配实现登录注册功能了。当用户访问需要登录才能访问的页面时,会跳转到登录页面进行认证认证成功后会跳转回原来的页面。如果用户没有登录或者没有权限访问某个页面,会跳转到错误页面。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值