首页 \ 问答 \ 401 Spring授权中的未授权访问被拒绝Oauth2(401 Unauthorized Access Denied in Spring boot Oauth2)

401 Spring授权中的未授权访问被拒绝Oauth2(401 Unauthorized Access Denied in Spring boot Oauth2)

当从我的角度应用程序击中oauth/token API时,我得到401 Unauthorized Access Denied错误。 我无法弄清楚缺少的东西。 请帮忙。

以下是我的代码

SecurityConfiguration.java

@Order(2)
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsService customUserDetailsService;



    @Autowired
    private CustomLogoutSuccessHandler customLogoutSuccessHandler;

    private static String REALM = "MY_TEST_REALM";

    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserDetailsService);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
        .addFilterBefore(new WebSecurityConfig(), ChannelProcessingFilter.class)
        .exceptionHandling()
        .and()
        .logout()
        .logoutUrl("/oauth/logout")
        .logoutSuccessHandler(customLogoutSuccessHandler)
        .and()
        .csrf()
        .disable()
        .authorizeRequests()
        .antMatchers("/uaa/**, /uaa/oauth/token, /uaa/oauth/authorize").hasRole("ADMIN").anyRequest().authenticated();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
    }
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

}

OAuthConfiguration.java

@Configuration
@EnableAuthorizationServer
public class OAuthConfiguration extends AuthorizationServerConfigurerAdapter {

private final transient Logger logger = LoggerFactory.getLogger(OAuthConfiguration.class);

@Autowired
private DataSource dataSource;

@Autowired
private CustomAuthenticationEntryPoint customAuthenticationEntryPoint;

@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;

@Bean
public TokenStore tokenStore() {
    return new JdbcTokenStore(dataSource);
}

@Bean
protected AuthorizationCodeServices authorizationCodeServices() {
    return new JdbcAuthorizationCodeServices(dataSource);
}

@Bean
public BCryptPasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

@Autowired
UserDetailsService customUserDetailsService;

@Bean
@Primary
public DefaultTokenServices tokenServices() {
    final DefaultTokenServices tokenServices = new DefaultTokenServices();
    tokenServices.setSupportRefreshToken(true);
    tokenServices.setTokenStore(tokenStore());
    return tokenServices;
}

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    endpoints.tokenStore(tokenStore()).authenticationManager(authenticationManager);
    endpoints.userDetailsService(customUserDetailsService);
}

@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
    oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()")
    .authenticationEntryPoint(customAuthenticationEntryPoint);
    oauthServer.addTokenEndpointAuthenticationFilter(
            new BasicAuthenticationFilter(authenticationManager, customAuthenticationEntryPoint));

}

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    clients
    .jdbc(dataSource).passwordEncoder(passwordEncoder())
    .withClient("clientId")
            .authorizedGrantTypes("password", "refresh_token", "authorization_code", "client_credentials",
                    "implicit")
            .authorities("ROLE_ADMIN").scopes("read", "write", "trust").secret("123456")
            .accessTokenValiditySeconds(1800).refreshTokenValiditySeconds(3000);
}
}

WebSecurityConfig.java

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class WebSecurityConfig implements Filter{

     @Override
      public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With, Origin, Accept, x-auth-token");

        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
          response.setStatus(HttpServletResponse.SC_OK);
        } else {
          chain.doFilter(req, res);
        }
      }

      @Override
      public void init(FilterConfig filterConfig) {
      }

      @Override
      public void destroy() {
      }
}

ResourceServerConfig.java

@Configuration
@EnableResourceServer

public class ResourceServerConfig extends GlobalMethodSecurityConfiguration {

    @Override
       protected MethodSecurityExpressionHandler createExpressionHandler() {
           return new OAuth2MethodSecurityExpressionHandler();
       }
}

application.properties

security.oauth2.client.clientId: clientId
security.oauth2.client.clientSecret: 123456
security.oauth2.client.authorized-grant-types: password,refresh_token,authorization_code,client_credentials
security.oauth2.client.scope: read,write,trust
security.oauth2.client.accessTokenUri=http://localhost:8080/uaa/oauth/token
security.oauth2.client.userAuthorizationUri=http://localhost:8080/uaa/oauth/authorize
security.oauth2.client.authenticationScheme=query
security.oauth2.client.clientAuthenticationScheme=form
security.oauth2.resource.filter-order = 3
spring.oauth2.resource.userInfoUri: http://localhost:8080/uaa/user

When hitting oauth/token API from my angular app, I get 401 Unauthorized Access Denied error. I am not able to figure out what's missing. Please help.

Below is my code

SecurityConfiguration.java

@Order(2)
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsService customUserDetailsService;



    @Autowired
    private CustomLogoutSuccessHandler customLogoutSuccessHandler;

    private static String REALM = "MY_TEST_REALM";

    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserDetailsService);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
        .addFilterBefore(new WebSecurityConfig(), ChannelProcessingFilter.class)
        .exceptionHandling()
        .and()
        .logout()
        .logoutUrl("/oauth/logout")
        .logoutSuccessHandler(customLogoutSuccessHandler)
        .and()
        .csrf()
        .disable()
        .authorizeRequests()
        .antMatchers("/uaa/**, /uaa/oauth/token, /uaa/oauth/authorize").hasRole("ADMIN").anyRequest().authenticated();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
    }
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

}

OAuthConfiguration.java

@Configuration
@EnableAuthorizationServer
public class OAuthConfiguration extends AuthorizationServerConfigurerAdapter {

private final transient Logger logger = LoggerFactory.getLogger(OAuthConfiguration.class);

@Autowired
private DataSource dataSource;

@Autowired
private CustomAuthenticationEntryPoint customAuthenticationEntryPoint;

@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;

@Bean
public TokenStore tokenStore() {
    return new JdbcTokenStore(dataSource);
}

@Bean
protected AuthorizationCodeServices authorizationCodeServices() {
    return new JdbcAuthorizationCodeServices(dataSource);
}

@Bean
public BCryptPasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

@Autowired
UserDetailsService customUserDetailsService;

@Bean
@Primary
public DefaultTokenServices tokenServices() {
    final DefaultTokenServices tokenServices = new DefaultTokenServices();
    tokenServices.setSupportRefreshToken(true);
    tokenServices.setTokenStore(tokenStore());
    return tokenServices;
}

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    endpoints.tokenStore(tokenStore()).authenticationManager(authenticationManager);
    endpoints.userDetailsService(customUserDetailsService);
}

@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
    oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()")
    .authenticationEntryPoint(customAuthenticationEntryPoint);
    oauthServer.addTokenEndpointAuthenticationFilter(
            new BasicAuthenticationFilter(authenticationManager, customAuthenticationEntryPoint));

}

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    clients
    .jdbc(dataSource).passwordEncoder(passwordEncoder())
    .withClient("clientId")
            .authorizedGrantTypes("password", "refresh_token", "authorization_code", "client_credentials",
                    "implicit")
            .authorities("ROLE_ADMIN").scopes("read", "write", "trust").secret("123456")
            .accessTokenValiditySeconds(1800).refreshTokenValiditySeconds(3000);
}
}

WebSecurityConfig.java

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class WebSecurityConfig implements Filter{

     @Override
      public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With, Origin, Accept, x-auth-token");

        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
          response.setStatus(HttpServletResponse.SC_OK);
        } else {
          chain.doFilter(req, res);
        }
      }

      @Override
      public void init(FilterConfig filterConfig) {
      }

      @Override
      public void destroy() {
      }
}

ResourceServerConfig.java

@Configuration
@EnableResourceServer

public class ResourceServerConfig extends GlobalMethodSecurityConfiguration {

    @Override
       protected MethodSecurityExpressionHandler createExpressionHandler() {
           return new OAuth2MethodSecurityExpressionHandler();
       }
}

application.properties

security.oauth2.client.clientId: clientId
security.oauth2.client.clientSecret: 123456
security.oauth2.client.authorized-grant-types: password,refresh_token,authorization_code,client_credentials
security.oauth2.client.scope: read,write,trust
security.oauth2.client.accessTokenUri=http://localhost:8080/uaa/oauth/token
security.oauth2.client.userAuthorizationUri=http://localhost:8080/uaa/oauth/authorize
security.oauth2.client.authenticationScheme=query
security.oauth2.client.clientAuthenticationScheme=form
security.oauth2.resource.filter-order = 3
spring.oauth2.resource.userInfoUri: http://localhost:8080/uaa/user

原文:https://stackoverflow.com/questions/43241655
更新时间:2024-01-31 15:01

最满意答案

这是一个非常开放的问题,取决于很多因素。

一般来说,如果您使用的语言具有良好的文档生成工具(javadoc,doxygen,MS的C#内容),则应该将文档写在方法的上方,并让工具生成页面。 其优点是,您可以将文本保存在代码中,这意味着它可以在逻辑上正确的位置组织,并且在对方法的行为进行更改时可以轻松进行编辑。

如果您没有很好的文档工具支持或无法访问源代码,维基百科不是一个坏主意,但它们是上述的第二选择。

注意:我在这里只谈论代码文档。 其他工件显然不能与代码一起存储 - 维基是放置这些文档的好地方。 或者,如果您使用某个CMS,您可以简单地将它们作为text / pdf /任何可通过存储库编辑的文件提交给某些docs/文件夹。 它的优点是,如果移动存储库,它们会保留在存储库中,而维基不会(必然)存在。


That's a very open ended question, and depends on many factors.

Generally speaking, if you use a language that has good documentation generation tools (javadoc, doxygen, MS's C# stuff), you should write your documentation above your methods and have your tools generate the pages. The advantage is that you keep the source of your text alongside your code which means it is orgnanized in the logically correct place and easily editable when you make a change to the behaviour of the method.

If you don't have good doc tool support or don't have access to source code, wiki's aren't a bad idea, but they're a second choice to the above.

Note: I'm talking only about code documentation here. Other artifacts obviously cannot be stored alongside code-- a wiki is a great place to put those documents. Alternatively if you use some CMS you can simply commit them in some docs/ folder as text/pdf/whatever files to be editable via the repository. The advantage there is that they stay with the repository if it is moved whereas a wiki does not (necessarily).

相关问答

更多
  • software
  • 你可以尝试一个维基,我是MediaWiki的用户,当他们在一个大学的主题上,并且足够好。 如果您不想安装,可以简单地使用github ,它将为您提供软件存储库以及您正在寻找的其他内容。 You can try a wiki, i've been a user of MediaWiki when they had it on a subject in the univerisity, and is good enough. If you don't want an installation, you coul ...
  • “知道它添加的额外命令” - dpkg -L python-software-properties仅显示/ usr / bin /中的add-apt-repository ,因此它是此包添加的唯一命令。 有关文档,请参阅man add-apt-repository 。 "know of the extra commands it adds" - dpkg -L python-software-properties shows only the add-apt-repository in /usr/bin/, ...
  • 这是一个非常开放的问题,取决于很多因素。 一般来说,如果您使用的语言具有良好的文档生成工具(javadoc,doxygen,MS的C#内容),则应该将文档写在方法的上方,并让工具生成页面。 其优点是,您可以将文本源保存在代码中,这意味着它可以在逻辑上正确的位置组织,并且在对方法的行为进行更改时可以轻松进行编辑。 如果您没有很好的文档工具支持或无法访问源代码,维基百科不是一个坏主意,但它们是上述的第二选择。 注意:我在这里只谈论代码文档。 其他工件显然不能与代码一起存储 - 维基是放置这些文档的好地方。 或者 ...
  • 应该测试什么? 那么,就网站而言,“你能进入页面吗?” 包括一个URL作为起点,并让管理员点击某个点。 管理员不需要完成整个QA周期,只需确认您的部署意图是否真正实现了部署。 其他想法另外,我们(我的团队在我上一份工作中)进行了QA测试。 作为质量保证人员,他对细节没有亲密感,在部署到质量保证部门时,我们能够获得有关错误发生的反馈。 另一件有用的事情是在部署之前与管理员坐在一起。 仔细阅读说明并确保他们以同样的方式了解他们。 模板? 只需制作包含DEV,QA和PROD等数据字段的部分即可。 当你写出说明时, ...
  • 类和它们之间的属性/方法的细节之间的关系与系统将要做的事情无关,与系统如何完成它的工作有关。 出于这个原因,我将UML类图放在设计规范中。 此外,我通常不会在整个类图中加入设计规范,但也会将其中某些部分(如果有的话)专注于特定主题(整个系统的子任务)。 我主要使用类图(当然是序列图)来设计应用程序,让我的头脑清楚地看到解决方案,但不是为了记录它:类图可能(并且将来)经常从我的第一次改变,主要是由于重构。 The relation between the classes and the detail of t ...
  • 我面临同样的问题; 我的方法已经从不喜欢SharePoint而不是将文档发布到SharePoint门户,不喜欢SharePoint和发布文档。 如果您的环境被广泛使用,那么很可能没有人会看到您在其他地方创建的内容。 这取决于您的受众,谁正在使用您的门户以及谁有权访问它。 。 。 如果您创建一个非常棒的目录结构:清晰,一致,并且反映出从低级别到高级别的详细信息,那么您可以向“管理”或其他同事提供基于所需级别的文档访问权限; 与他们想要为其任务提取的信息相关。 如果需要,您还可以从SharePoint高级链接到 ...
  • 由于不同的站点具有不同的数据库首选项,因此您可能希望使用ActiveRecord或PDO或ODBC等层来抽象出最终用户想要使用的特定数据库。 这将允许人们部署到PostgreSQL或MySQL或他们喜欢的任何东西。 单进程服务器系统的一个很好的选择可能是SQLite3 。 它不适用于所有系统,但如果您的系统最多可以扩展到几十个用户,它可能会正常工作。 (为了使SQLite3规模扩大到数百或数千,您需要投入服务器的工作量可能会争取规划数据库服务器环境。) Since different sites have ...
  • 你可能会得到一些类似于大学使用的抄袭软件。 它应该找到文本中的所有相似之处,但是我不确定它们是否检测到布局/字体大小。 We opted to do a hybrid solution. I found out that XTest works with some old file formats and pdf, but not rtf or even txt files. So I created a utility that will run our old iText code or our new ...
  • Confluence wiki允许您导入Word文档。 我被告知这是一个非常好的维基,有很多功能。 Confluence wiki lets you import Word documents. I've been told it's a really good wiki with a lot of features.

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)