当前位置: 首页 > 知识库问答 >
问题:

Spring security具有相同资源的Oauth2或HTTP基本身份验证

岑明辉
2023-03-14

我正在尝试实现一个API,该API具有受Oauth2或HTTP基本身份验证保护的资源。

当我加载WebSecurityConfigurerAdapter(它首先对资源应用HTTP基本身份验证)时,不接受Oauth2令牌身份验证。反之亦然。

配置示例:这将对所有/user/**资源应用HTTP基本身份验证

@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private LoginApi loginApi;

    @Autowired
    public void setLoginApi(LoginApi loginApi) {
        this.loginApi = loginApi;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(new PortalUserAuthenticationProvider(loginApi));
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/users/**").authenticated()
                .and()
            .httpBasic();
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
            .requestMatchers().antMatchers("/users/**")
        .and()
            .authorizeRequests()
                .antMatchers("/users/**").access("#oauth2.clientHasRole('ROLE_CLIENT') and #oauth2.hasScope('read')");
    }
}

共有1个答案

严誉
2023-03-14

我设法得到这个工作的基础上,提示迈克尔雷斯勒的答案,但有一些调整。

我的目标是在相同的资源endpoint上同时允许基本身份验证和Oauth,例如/leafcase/123。由于filterChains的排序(可以在FilterChainProxy.filterChains中进行检查),我被困了相当一段时间;默认顺序如下:

  • OAuth身份验证服务器(如果在同一项目中启用)的筛选器链。默认顺序0(请参阅AuthorizationServerSecurityConfiguration)
  • OAuth资源服务器的筛选器链。默认顺序3(请参见ResourceServerConfiguration)。它有一个请求匹配器逻辑,可以匹配Oauth身份验证endpoint以外的任何东西(例如,/Oauth/token、/Oauth/authorize等。请参阅ResourceServerConfiguration$NotoAuthRequestMatcher.matches())。
  • 对应于config(HttpSecurity http)的filterChains-默认顺序100,请参见WebSecurityConfigurerAdapter。

由于资源服务器的filterChains比WebSecurityConfigurerAdapter配置的filterchain的级别更高,并且前者几乎匹配每个资源endpoint,因此Oauth资源服务器逻辑总是介入到对资源endpoint的任何请求中(即使请求使用授权:基本头)。您将得到的错误是:

{
    "error": "unauthorized",
    "error_description": "Full authentication is required to access this resource"
}

我做了2个改变来获得这个工作:

首先,将WebSecurityConfigurerAdapter排序为高于资源服务器(排序2高于排序3)。

@Configuration
@Order(2)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

其次,让configure(HttpSecurity)使用一个只匹配“authorization:basic”的customer RequestMatcher。

@Override
protected void configure(HttpSecurity http) throws Exception {

    http
        .anonymous().disable()
        .requestMatcher(new BasicRequestMatcher())
        .authorizeRequests()
            .anyRequest().authenticated()
            .and()
        .httpBasic()
             .authenticationEntryPoint(oAuth2AuthenticationEntryPoint())
            .and()
        // ... other stuff
 }
 ...
 private static class BasicRequestMatcher implements RequestMatcher {
    @Override
    public boolean matches(HttpServletRequest request) {
        String auth = request.getHeader("Authorization");
        return (auth != null && auth.startsWith("Basic"));
    }
 }

因此,在资源服务器的filterChain有机会匹配一个基本的身份验证资源请求之前,它会匹配并处理它。它也只处理authorizaiton:basic资源请求,因此任何带有authorizaiton:barer的请求都将落空,然后由资源服务器的filterChain处理(即OAuth的过滤器启动)。此外,它的级别低于AuthenticationServer(在同一项目上启用AuthenticationServer的情况下),因此它不会阻止AuthenticationOnServer的filterchain处理对/oauth/token等的请求。

 类似资料:
  • 问题内容: 我必须 使用 HTTP Basic身份验证从http服务器下载和解析XML文件。现在,我这样做: 但是以这种方式,我无法从具有http身份验证的服务器获取xml(或者我只是根本不知道该文档)文档。 如果您能向我展示实现我的目标的最好,最简单的方法,我将不胜感激。 问题答案: 您可以使用。例如: 这将设置默认值,并将在 所有 请求中使用。显然,当您不需要所有请求的凭据或多个不同的凭据(可

  • 我正在尝试使用OAuth2实现开发一个带有Spring Security性的rest api。但是如何删除基本身份验证呢。我只想向body发送用户名和密码,并在postman上获取令牌。 要删除基本身份验证,并从邮递员的get token中发送body标记中的用户名密码吗 我遇到了一些问题{"错误":"未经授权","error_description":"没有客户端身份验证。尝试添加适当的身份验证

  • 我尝试了angular.js,并从一个restful api的web-ui开始(使用超文本传输协议基本授权)。这真的很好,除了授权工作。 到目前为止,我使用的是设置密码,但大多数情况下浏览器会打开http basic auth的默认登录表单。另一个奇怪的行为是angular请求不包含授权头(选项和GET请求都不包含)。我还尝试使用header配置在每个请求上设置此header,但这也不起作用。 有

  • 有没有办法对/oauth/tokenendpoint禁用HTTP基本身份验证?我希望在JSON主体或请求头中发送client_id和client_secret。 我想工作的卷曲例子: 或

  • 我所期望的是:当用户从表单登录时,它可以调用restful服务,而无需经过基本身份验证(因为它已经经过身份验证)。我的想法是,角色为'role_user'的用户也应该调用restful服务。但是,当我从表单登录后,我也被提示进行基本身份验证,试图从浏览器调用restful服务。 有没有得到我所期望的?

  • 问题内容: 我想写书,所使用的一个一个的NodeJS REST的API服务器Joyent的,并且一切正常,除了我无法验证普通用户的身份验证。如果我跳到终端并执行,则无法在NodeJS http服务器上获取值username:password。如果我的NodeJS http服务器类似于 ,是否应该在来自回调的 req 对象中某处获取值username:password ?如何获得这些值而不必使用Co