Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring security SpringSecurity with Security Context MockMvc OAuth2始终未经授权_Spring Security_Spring Boot_Spring Security Oauth2_Spring Test_Spring Oauth2 - Fatal编程技术网

Spring security SpringSecurity with Security Context MockMvc OAuth2始终未经授权

Spring security SpringSecurity with Security Context MockMvc OAuth2始终未经授权,spring-security,spring-boot,spring-security-oauth2,spring-test,spring-oauth2,Spring Security,Spring Boot,Spring Security Oauth2,Spring Test,Spring Oauth2,我按照以下链接尝试测试OAuth2@PreAuthorise(例如hasAnyRole('ADMIN','test'),但我无法通过任何测试,甚至无法进行身份验证 当我尝试使用管理员(或任何角色)访问端点时它永远不会正确地进行身份验证。如果我遗漏了一些明显的东西,我似乎拥有了示例中的所有内容。我还尝试了另一种替代方法,使用特定于OAuth的身份验证代替WithSecurity Context工厂,但仍然没有成功。如果有任何帮助,我们将不胜感激 和 我正在测试我的控制器 @RestContro

我按照以下链接尝试测试OAuth2@PreAuthorise(例如hasAnyRole('ADMIN','test'),但我无法通过任何测试,甚至无法进行身份验证

当我尝试使用管理员(或任何角色)访问端点时它永远不会正确地进行身份验证。如果我遗漏了一些明显的东西,我似乎拥有了示例中的所有内容。我还尝试了另一种替代方法,使用特定于OAuth的身份验证代替WithSecurity Context工厂,但仍然没有成功。如果有任何帮助,我们将不胜感激

我正在测试我的控制器

@RestController
@RequestMapping("/bookmark/")
public class GroupBookmarkController {

    @Autowired
    BookmarkService bookmarkService;

    /**
    * Get list of all bookmarks
    */
    @RequestMapping(value = "{groupId}", method = RequestMethod.GET)
    @PreAuthorize("hasAnyRole(['ADMIN', 'USER'])")
    public ResponseEntity<List<Bookmark>> listAllGroupBookmarks(@PathVariable("groupId") String groupId) throws BookmarkNotFoundException {
        List<Bookmark> bookmarks = bookmarkService.findAllBookmarksByGroupId(groupId);
        return new ResponseEntity<>(bookmarks, HttpStatus.OK);
    }
    ...
}
我的书签服务应用程序

@SpringBootApplication
@EnableResourceServer
public class BookmarkServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(BookmarkServiceApplication.class, args);
    }
}
我的WithSecurity ContextFactory

public class WithMockCustomUserSecurityContextFactory implements WithSecurityContextFactory<WithMockCustomUser> {
    @Override
    public SecurityContext createSecurityContext(WithMockCustomUser customUser) {
        SecurityContext context = SecurityContextHolder.createEmptyContext();

        List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));

        UserDetails principal = new User(customUser.username(), "password", true, true, true, true, grantedAuthorities);


        Authentication authentication = new UsernamePasswordAuthenticationToken(
                principal, principal.getPassword(), principal.getAuthorities());
        context.setAuthentication(authentication);

        return context;
    }
}
根据@RobWinch的回复
Hi@RobWinch我试过你关于无状态标志的建议,这有助于回答部分问题

您不再需要担心是否在无状态模式下运行

为什么我仍然需要添加无状态false,这是一个bug还是我们使用它的方式略有不同

我需要做的另一件事是将OAuth2Request和OAuth2Authentication添加到WithSecurityContextFactory中,如下所示

public class WithMockCustomUserSecurityContextFactory implements WithSecurityContextFactory<WithMockOAuthUser> {

    @Override
    public SecurityContext createSecurityContext(WithMockOAuthUser withClient) {
        // Get the username
        String username = withClient.username();
        if (username == null) {
            throw new IllegalArgumentException("Username cannot be null");
        }

        // Get the user roles
        List<GrantedAuthority> authorities = new ArrayList<>();
        for (String role : withClient.roles()) {
            if (role.startsWith("ROLE_")) {
                throw new IllegalArgumentException("roles cannot start with ROLE_ Got " + role);
            }
            authorities.add(new SimpleGrantedAuthority("ROLE_" + role));
        }

        // Get the client id
        String clientId = withClient.clientId();
        // get the oauth scopes
        String[] scopes = withClient.scope();
        Set<String> scopeCollection = Sets.newSet(scopes);

        // Create the UsernamePasswordAuthenticationToken
        User principal = new User(username, withClient.password(), true, true, true, true, authorities);
        Authentication authentication = new UsernamePasswordAuthenticationToken(principal, principal.getPassword(),
                principal.getAuthorities());


        // Create the authorization request and OAuth2Authentication object
        OAuth2Request authRequest = new OAuth2Request(null, clientId, null, true, scopeCollection, null, null, null,
                null);
        OAuth2Authentication oAuth = new OAuth2Authentication(authRequest, authentication);

        // Add the OAuth2Authentication object to the security context
        SecurityContext context = SecurityContextHolder.createEmptyContext();
        context.setAuthentication(oAuth);
        return context;
    }

}
带有MockCustomUserSecurityContextFactory的公共类使用Security ContextFactory实现{
@凌驾
public SecurityContext createSecurityContext(带MockOAuthuser和客户端){
//获取用户名
字符串username=withClient.username();
如果(用户名==null){
抛出新的IllegalArgumentException(“用户名不能为null”);
}
//获取用户角色
列表权限=新建ArrayList();
for(字符串角色:withClient.roles()){
if(role.startsWith(“role_”)){
抛出新的IllegalArgumentException(“角色不能以ROLE_uGot”+ROLE开头);
}
添加(新的SimpleGrantedAuthority(“角色+角色”);
}
//获取客户端id
字符串clientId=withClient.clientId();
//获取oauth范围
字符串[]scopes=withClient.scope();
Set scopeCollection=Set.newSet(scopes);
//创建UsernamePasswordAuthenticationToken
用户主体=新用户(用户名,withClient.password(),true,true,true,authorities);
Authentication Authentication=新用户名PasswordAuthenticationToken(主体,主体.getPassword(),
principal.getAuthorities());
//创建授权请求和OAuth2Authentication对象
OAuth2Request authRequest=新的OAuth2Request(null,clientId,null,true,scopeCollection,null,null,null,
无效);
OAuth2Authentication oAuth=新的OAuth2Authentication(authRequest,authentication);
//将OAuth2Authentication对象添加到安全上下文中
SecurityContext上下文=SecurityContextHolder.createEmptyContext();
setAuthentication(oAuth);
返回上下文;
}
}

问题在于,如果SecurityContext被标记为无状态,则会清除它。要解决此问题,请将其配置为允许在外部填充状态(即无状态=false)。

要添加更多信息,如何将无状态设置为false:

在ResourceServerConfigurerAdapter中,执行以下操作:

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.stateless(false);
    }

这对我很有用。

WithMockOAuthUser的代码在哪里?它与Security ContextFactory有关?@RobWinch抱歉,这是一个打字错误,实际上WithMockCustomUser是一个打字错误,让我胡思乱想,同样的问题也存在。我有另一个界面,它创建了OAuth身份验证,而不是用户名密码身份验证什么您的安全配置看起来像吗?具体来说,web和方法安全配置看起来像什么?@RobWinch我实际上没有一个默认配置运行,这是一个微服务,在带有配置的auth服务的网关后面进行通信。这些测试是在与AuthService隔离的情况下运行的我仍然有一个配置?@revilo如果我可以问的话,你是否可以与你的测试环境共享一个存储库?我正在尝试测试spring-security-oauth2,除了401之外,我什么都得不到。你的文章是帮助我理解得最多的一篇文章。使用spring-security和spring-security-oauth2的项目测试还不存在。它是太好了。提前感谢Hi@RobWinch我用无状态标志尝试了你的建议,这有助于部分答案。但是在你对这个问题的回答[Spring OAuth and Boot Integration Test]()中你提到“你不再需要担心是否在无状态模式下运行”为什么它是必需的我需要这个,这是一个错误还是我们使用它有点不同。我已经更新了答案,因为我已经用完了这里的字符Spring Security OAuth处理无状态的不同于Spring Security,因此该语句不适用于OAuth(不幸的是).在上面的示例中,您到底是如何将其设置为false的?@RobWinch亲爱的rob,我们已经尝试了好几天来测试spring-security-oauth2,我们也遇到了401个错误。spring-security-oauth2没有任何示例,我们需要一个。有没有办法获得示例或其他信息?
public class WithMockCustomUserSecurityContextFactory implements WithSecurityContextFactory<WithMockOAuthUser> {

    @Override
    public SecurityContext createSecurityContext(WithMockOAuthUser withClient) {
        // Get the username
        String username = withClient.username();
        if (username == null) {
            throw new IllegalArgumentException("Username cannot be null");
        }

        // Get the user roles
        List<GrantedAuthority> authorities = new ArrayList<>();
        for (String role : withClient.roles()) {
            if (role.startsWith("ROLE_")) {
                throw new IllegalArgumentException("roles cannot start with ROLE_ Got " + role);
            }
            authorities.add(new SimpleGrantedAuthority("ROLE_" + role));
        }

        // Get the client id
        String clientId = withClient.clientId();
        // get the oauth scopes
        String[] scopes = withClient.scope();
        Set<String> scopeCollection = Sets.newSet(scopes);

        // Create the UsernamePasswordAuthenticationToken
        User principal = new User(username, withClient.password(), true, true, true, true, authorities);
        Authentication authentication = new UsernamePasswordAuthenticationToken(principal, principal.getPassword(),
                principal.getAuthorities());


        // Create the authorization request and OAuth2Authentication object
        OAuth2Request authRequest = new OAuth2Request(null, clientId, null, true, scopeCollection, null, null, null,
                null);
        OAuth2Authentication oAuth = new OAuth2Authentication(authRequest, authentication);

        // Add the OAuth2Authentication object to the security context
        SecurityContext context = SecurityContextHolder.createEmptyContext();
        context.setAuthentication(oAuth);
        return context;
    }

}
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.stateless(false);
    }