GVKun编程网logo

无法在Spring Security中使用@Secured Method Security批注(spring 无法注入)

14

对于想了解无法在SpringSecurity中使用@SecuredMethodSecurity批注的读者,本文将是一篇不可错过的文章,我们将详细介绍spring无法注入,并且为您提供关于@PreAut

对于想了解无法在Spring Security中使用@Secured Method Security批注的读者,本文将是一篇不可错过的文章,我们将详细介绍spring 无法注入,并且为您提供关于@PreAuthorize批注在Spring Security中不起作用、org.springframework.boot.autoconfigure.security.SecurityAuthorizeMode的实例源码、spring boot 整合spring security中spring security版本升级的遇到的坑、Spring security 5.0:spring security savedrequest 为空的有价值信息。

本文目录一览:

无法在Spring Security中使用@Secured Method Security批注(spring 无法注入)

无法在Spring Security中使用@Secured Method Security批注(spring 无法注入)

我做了很多研究,对我来说一切看起来都不错……但是我无法使它正常工作!有人知道吗?

不管我做什么,相关的映射对任何人都保持公开状态(无论匿名或登录,无论他们扮演什么角色)。

理想情况下,我希望所有请求都公开,但@Secured()注释的请求除外-显然,只有具有特定角色的用户才能访问这些映射。

那可能吗?

仅供参考,我目前构建了一种方法“ hasRole(String
role)”,该方法检查登录用户的角色,如果该方法返回false,则抛出NotAuthorizedException(定制)。

用户详细信息

  @Override  public Collection<? extends GrantedAuthority> getAuthorities() {      List<GrantedAuthority> grantedAuthorities = null;      System.out.print("Account role... ");      System.out.println(account.getRole());      if (account.getRole().equals("USER")) {          GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_USER");          grantedAuthorities = Arrays.asList(grantedAuthority);      }      if (account.getRole().equals("ADMIN")) {          GrantedAuthority grantedAuthorityUser = new SimpleGrantedAuthority("ROLE_USER");          GrantedAuthority grantedAuthorityAdmin = new SimpleGrantedAuthority("ROLE_ADMIN");          grantedAuthorities = Arrays.asList(grantedAuthorityUser, grantedAuthorityAdmin);      }      return grantedAuthorities;  }

安全配置

@Configuration@EnableWebSecurity@EnableGlobalMethodSecurity(securedEnabled = true)public class SecurityConfig extends WebSecurityConfigurerAdapter {    @Autowired    private AuthFailure authFailure;    @Autowired    private AuthSuccess authSuccess;    @Autowired    private EntryPointUnauthorizedHandler unauthorizedHandler;    @Autowired    private UserDetailsServiceImpl userDetailsService;    /*@Autowired    public void configAuthBuilder(AuthenticationManagerBuilder builder) throws Exception {        builder.userDetailsService(userDetailsService);    }*/    @Override    public AuthenticationManager authenticationManagerBean() throws Exception {        return super.authenticationManagerBean();    }    @Autowired    @Override    public void configure(AuthenticationManagerBuilder builder) throws Exception {        builder.userDetailsService(userDetailsService);    }  private CsrfTokenRepository csrfTokenRepository() {    HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();    repository.setHeaderName("X-XSRF-TOKEN");    return repository;  }    @Override    public void configure(HttpSecurity http) throws Exception {      http.csrf().csrfTokenRepository(csrfTokenRepository())        .and().exceptionHandling().authenticationEntryPoint(unauthorizedHandler)        .and().formLogin().loginPage("/login").successHandler(authSuccess).failureHandler(authFailure)        //.and().authorizeRequests().antMatchers("/rest/**").authenticated()        //.and().authorizeRequests().antMatchers("/**").permitAll()        .and().addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class);;    }

AccountController

  @Secured("ROLE_USER")  @RequestMapping(method = RequestMethod.GET)  public List<Account> getAllAccounts(@RequestParam(value = "mail", required = false) String mail) {

谢谢!

答案1

小编典典

您可以通过Spring HttpSecurity使用Controller范围的Security。尝试将其添加到您的configure方法中:

.antMatchers("rest/accounts*").hasRole("ADMIN")

如果您希望任何要求公开(真的吗?):

.anyRequest().permitAll()

当您从任何地方访问它时,还可以在UserDetailsS​​ervice中保护示例的Methodinvocation:

@Secured("ROLE_USER")public getAllAccounts(...){...}

只有这样,您才需要使用以下方法注释SecurityConfig:

@EnableGlobalMethodSecurity(securedEnabled = true)

实际上,我们建议您在服务层使用方法安全性来控制对应用程序的访问,并且不要完全依赖于在Web应用程序级别定义的安全性约束的使用。URL会发生变化,很难考虑到应用程序可能支持的所有可能的URL以及如何处理请求。您应该尝试限制自己使用一些简单易懂的简单蚂蚁路径。始终尝试使用“默认拒绝”方法,在此方法中,您最后定义了一个全包通配符(/或),并拒绝访问。在服务层定义的安全性更健壮,更难绕开,因此您应始终利用Spring
Security的方法安全性选项。

参见:http :
//docs.spring.io/autorepo/docs/spring-security/4.0.0.CI-
SNAPSHOT/reference/htmlsingle/#request-
matching

@PreAuthorize批注在Spring Security中不起作用

@PreAuthorize批注在Spring Security中不起作用

我发现了许多类似的问题,但都没有解决我的问题。我的问题是ROLE_USER可以访问的功能ROLE_ADMIN

我的spring-security.xml代码如下。

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:s="http://www.springframework.org/schema/security"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                    http://www.springframework.org/schema/security
                    http://www.springframework.org/schema/security/spring-security-3.0.xsd">

<s:http auto-config="true" use-expressions="true">
    <s:intercept-url pattern="/index.jsp" access="permitAll" />
    <s:intercept-url pattern="/welcome*" access="hasRole('ROLE_USER')" />
    <s:intercept-url pattern="/helloadmin*" access="hasRole('ROLE_ADMIN')" />

    <s:form-login login-page="/login" default-target-url="/welcome"
        authentication-failure-url="/loginfailed" />
    <s:logout logout-success-url="/logout" />
</s:http>

<s:authentication-manager>
  <s:authentication-provider>
    <s:user-service>
        <s:user name="asif" password="123456" authorities="ROLE_USER,ROLE_ADMIN" />
        <s:user name="raheel" password="123456" authorities="ROLE_USER" />          
    </s:user-service>
  </s:authentication-provider>
</s:authentication-manager>

当我添加<s:global-method-security pre-post-annotations="enabled"/>
我的代码时显示找不到资源错误,并且当我删除我的代码时成功执行但ROLE_USER可以访问ROLE_ADMIN函数

我的控制器功能是。

@PreAuthorize("hasRole('ROLE_ADMIN')")
@RequestMapping(value="/delete",method = RequestMethod.GET)
public String DeleteAll(ModelMap model,Principal principal ) {

    org.springframework.security.core.userdetails.User activeUser = (org.springframework.security.core.userdetails.User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    System.out.println("Active user is "+activeUser.getUsername()+"Authorities are "+activeUser.getAuthorities());
    return "deleteUsers";

}

org.springframework.boot.autoconfigure.security.SecurityAuthorizeMode的实例源码

org.springframework.boot.autoconfigure.security.SecurityAuthorizeMode的实例源码

项目:https-github.com-g0t4-jenkins2-course-spring-boot    文件:H2ConsoleAutoConfiguration.java   
@Override
public void configure(HttpSecurity http) throws Exception {
    String path = this.console.getPath();
    String antPattern = (path.endsWith("/") ? path + "**" : path + "/**");
    HttpSecurity h2Console = http.antMatcher(antPattern);
    h2Console.csrf().disable();
    h2Console.httpBasic();
    h2Console.headers().frameOptions().sameOrigin();
    String[] roles = this.security.getUser().getRole().toArray(new String[0]);
    SecurityAuthorizeMode mode = this.security.getBasic().getAuthorizeMode();
    if (mode == null || mode == SecurityAuthorizeMode.ROLE) {
        http.authorizeRequests().anyRequest().hasAnyRole(roles);
    }
    else if (mode == SecurityAuthorizeMode.AUTHENTICATED) {
        http.authorizeRequests().anyRequest().authenticated();
    }
}
项目:spring-boot-concourse    文件:H2ConsoleAutoConfiguration.java   
@Override
public void configure(HttpSecurity http) throws Exception {
    String path = this.console.getPath();
    String antPattern = (path.endsWith("/") ? path + "**" : path + "/**");
    HttpSecurity h2Console = http.antMatcher(antPattern);
    h2Console.csrf().disable();
    h2Console.httpBasic();
    h2Console.headers().frameOptions().sameOrigin();
    String[] roles = this.security.getUser().getRole().toArray(new String[0]);
    SecurityAuthorizeMode mode = this.security.getBasic().getAuthorizeMode();
    if (mode == null || mode == SecurityAuthorizeMode.ROLE) {
        http.authorizeRequests().anyRequest().hasAnyRole(roles);
    }
    else if (mode == SecurityAuthorizeMode.AUTHENTICATED) {
        http.authorizeRequests().anyRequest().authenticated();
    }
}
项目:contestparser    文件:H2ConsoleAutoConfiguration.java   
@Override
public void configure(HttpSecurity http) throws Exception {
    String path = this.console.getPath();
    String antPattern = (path.endsWith("/") ? path + "**" : path + "/**");
    HttpSecurity h2Console = http.antMatcher(antPattern);
    h2Console.csrf().disable();
    h2Console.httpBasic();
    h2Console.headers().frameOptions().sameOrigin();
    String[] roles = this.security.getUser().getRole().toArray(new String[0]);
    SecurityAuthorizeMode mode = this.security.getBasic().getAuthorizeMode();
    if (mode == null || mode == SecurityAuthorizeMode.ROLE) {
        http.authorizeRequests().anyRequest().hasAnyRole(roles);
    }
    else if (mode == SecurityAuthorizeMode.AUTHENTICATED) {
        http.authorizeRequests().anyRequest().authenticated();
    }
}
项目:cas-security-spring-boot-starter    文件:CasSecurityAutoConfiguration.java   
@Override
public void configure(HttpSecurity http) throws Exception {
    String logoutSuccessUrl = buildUrl(casSecurityProperties.getServer().getBaseUrl(),casSecurityProperties.getServer().getPaths().getlogout());
    http.logout().permitAll().logoutSuccessUrl(logoutSuccessUrl);

    SecurityAuthorizeMode mode = casSecurityProperties.getAuthorizeMode();
    if (mode == SecurityAuthorizeMode.ROLE) {
        List<String> roles = securityProperties.getUser().getRole();
        http.authorizeRequests().anyRequest().hasAnyRole(roles.toArray(new String[roles.size()]));
    } else if (mode == SecurityAuthorizeMode.AUTHENTICATED) {
        http.authorizeRequests().anyRequest().authenticated();
    }
}

spring boot 整合spring security中spring security版本升级的遇到的坑

spring boot 整合spring security中spring security版本升级的遇到的坑

在spring security3.x的版本中

hasAnyRole这个方法不会对我们需要认证的身份前面加个前缀ROLE_,在3.x版本hasRole的源码如下

 

public final boolean hasAnyRole(String... roles) {
        Set<String> roleSet = getAuthoritySet();

        for (String role : roles) {
            if (roleSet.contains(role)) {
                return true;
            }
        }

        return false;
    }

而4.x版本下的会根据我的具体情况看看是不是要加前缀,代码如下

public final boolean hasAnyRole(String... roles) {
        return hasAnyAuthorityName(defaultRolePrefix, roles);
    }

    private boolean hasAnyAuthorityName(String prefix, String... roles) {
        Set<String> roleSet = getAuthoritySet();

        for (String role : roles) {
            String defaultedRole = getRoleWithDefaultPrefix(prefix, role);
            if (roleSet.contains(defaultedRole)) {
                return true;
            }
        }

        return false;
    }
private static String getRoleWithDefaultPrefix(String defaultRolePrefix, String role) {
        if (role == null) {
            return role;
        }
        if (defaultRolePrefix == null || defaultRolePrefix.length() == 0) {
            return role;
        }
        if (role.startsWith(defaultRolePrefix)) {
            return role;
        }
        return defaultRolePrefix + role;
    }

这里的这个坑要小心,如果加了Role_前缀,那么你登录时的角色的前面也需要加Role_才行,不然会认证失败,然后就是403页面了。(ps:hasRole这个方法也有这个版本问题,具体也是和hasAnyRole差不多。)

Spring security 5.0:spring security savedrequest 为空

Spring security 5.0:spring security savedrequest 为空

如何解决Spring security 5.0:spring security savedrequest 为空?

我有一个 spring boot 客户端应用程序,我在其中使用 spring-boot-starter-oauth2-client 和 spring-boot-starter-security。同一个应用程序在一个环境中运行良好,但是在另一个环境中部署后,我可以看到 spring security 保存的请求为空,这就是它不断重定向到登录页面的原因。

启用 spring 安全调试日志后,我可以看到身份验证成功并检索到用户详细信息。但是,它继续重定向到“/”,因为spring security 保存的请求为空。

我不知道问题出在哪里,为什么它能够在一种环境中而不是在另一种环境中保存请求。我应该从哪里开始寻找?任何帮助将不胜感激。

应用程序未重定向的调试日志

{"timestamp":"2021-05-12T17:24:40.918+10:00","app":"my-protected-application","logLevel":"INFO","thread":"http-nio-8080-exec-1","eventSource":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","message":"Initializing Spring dispatcherServlet ''dispatcherServlet''"}
{"timestamp":"2021-05-12T17:24:41.104+10:00","traceId":"2efe5d4e6d04f787","spanId":"2efe5d4e6d04f787","logLevel":"DEBUG","eventSource":"org.springframework.security.web.util.matcher.AntPathRequestMatcher","message":"Checking match of request : ''/actuator/health/readiness''; against ''/actuator/info''"}
{"timestamp":"2021-05-12T17:24:41.112+10:00","message":"Checking match of request : ''/actuator/health/readiness''; against ''/actuator/health/readiness''"}
{"timestamp":"2021-05-12T17:24:41.112+10:00","eventSource":"org.springframework.security.web.FilterChainProxy","message":"/actuator/health/readiness has an empty filter list"}
{"timestamp":"2021-05-12T17:24:55.666+10:00","traceId":"9681ad4d267d4beb","spanId":"9681ad4d267d4beb","thread":"http-nio-8080-exec-2","message":"Checking match of request : ''/oauth2/authorization/my-protected-application''; against ''/actuator/info''"}
{"timestamp":"2021-05-12T17:24:55.666+10:00","message":"Checking match of request : ''/oauth2/authorization/my-protected-application''; against ''/actuator/health/readiness''"}
{"timestamp":"2021-05-12T17:24:55.666+10:00","message":"Checking match of request : ''/oauth2/authorization/my-protected-application''; against ''/actuator/health/liveness''"}
{"timestamp":"2021-05-12T17:24:55.668+10:00","message":"/oauth2/authorization/my-protected-application at position 1 of 14 in additional filter chain; firing Filter: ''WebAsyncManagerIntegrationFilter''"}
{"timestamp":"2021-05-12T17:24:55.670+10:00","message":"/oauth2/authorization/my-protected-application at position 2 of 14 in additional filter chain; firing Filter: ''SecurityContextPersistenceFilter''"}
{"timestamp":"2021-05-12T17:24:55.670+10:00","eventSource":"org.springframework.security.web.context.HttpSessionSecurityContextRepository","message":"No HttpSession currently exists"}
{"timestamp":"2021-05-12T17:24:55.670+10:00","message":"No SecurityContext was available from the HttpSession: null. A new one will be created."}
{"timestamp":"2021-05-12T17:24:55.673+10:00","message":"/oauth2/authorization/my-protected-application at position 3 of 14 in additional filter chain; firing Filter: ''HeaderWriterFilter''"}
{"timestamp":"2021-05-12T17:24:55.674+10:00","message":"/oauth2/authorization/my-protected-application at position 4 of 14 in additional filter chain; firing Filter: ''logoutFilter''"}
{"timestamp":"2021-05-12T17:24:55.674+10:00","eventSource":"org.springframework.security.web.util.matcher.OrRequestMatcher","message":"Trying to match using Ant [pattern=''/logout'',GET]"}
{"timestamp":"2021-05-12T17:24:55.675+10:00","message":"Checking match of request : ''/oauth2/authorization/my-protected-application''; against ''/logout''"}
{"timestamp":"2021-05-12T17:24:55.675+10:00",POST]"}
{"timestamp":"2021-05-12T17:24:55.675+10:00","message":"Request ''GET /oauth2/authorization/my-protected-application'' doesn''t match ''POST /logout''"}
{"timestamp":"2021-05-12T17:24:55.675+10:00",PUT]"}
{"timestamp":"2021-05-12T17:24:55.675+10:00","message":"Request ''GET /oauth2/authorization/my-protected-application'' doesn''t match ''PUT /logout''"}
{"timestamp":"2021-05-12T17:24:55.675+10:00",DELETE]"}
{"timestamp":"2021-05-12T17:24:55.675+10:00","message":"Request ''GET /oauth2/authorization/my-protected-application'' doesn''t match ''DELETE /logout''"}
{"timestamp":"2021-05-12T17:24:55.675+10:00","message":"No matches found"}
{"timestamp":"2021-05-12T17:24:55.676+10:00","message":"/oauth2/authorization/my-protected-application at position 5 of 14 in additional filter chain; firing Filter: ''OAuth2AuthorizationRequestRedirectFilter''"}
{"timestamp":"2021-05-12T17:24:55.676+10:00","message":"Checking match of request : ''/oauth2/authorization/my-protected-application''; against ''/oauth2/authorization/{registrationId}''"}
{"timestamp":"2021-05-12T17:24:55.676+10:00","message":"Checking match of request : ''/oauth2/authorization/my-protected-application''; against ''/oauth2/authorization/{registrationId}''"}

解决方法

您是直接调用登录 URL 而不是尝试通过登录页面登录吗?

用户请求的请求数据存储在 requestCache 中。 此处存储的请求数据为 savedRequestSpring security 在用户身份验证后重定向 requestCachesavedRequest 对象。

SavedRequest 必须为空,因为如果不使用登录页面直接使用 URL,则前一个请求中没有请求数据。

您可以尝试从登录页面登录或使用 Referrer 标头获取页面 URL。

我们今天的关于无法在Spring Security中使用@Secured Method Security批注spring 无法注入的分享就到这里,谢谢您的阅读,如果想了解更多关于@PreAuthorize批注在Spring Security中不起作用、org.springframework.boot.autoconfigure.security.SecurityAuthorizeMode的实例源码、spring boot 整合spring security中spring security版本升级的遇到的坑、Spring security 5.0:spring security savedrequest 为空的相关信息,可以在本站进行搜索。

本文标签: