简体   繁体   English

Spring Boot2 Oauth2隐式流 - http:// localhost:8080 / oauth / authorize获取访问被拒绝

[英]Spring Boot2 Oauth2 Implicit Flow - http://localhost:8080/oauth/authorize getting Access Denied

I have created a Spring Boot 2 Application, integrated SpringFox Swagger 2.8.0 with Implicit Oauth2 Grant for Authentication and Authorization. 我创建了一个Spring Boot 2应用程序,集成了SpringFox Swagger 2.8.0和Implicit Oauth2 Grant,用于身份验证和授权。

The Code is working fine but when I click Authorize button it redirects to the 该代码工作正常,但当我单击授权按钮时,它重定向到

http://localhost:8080/oauth/authorize?response_type=token&client_id=test-app-client-id&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fwebjars%2Fspringfox-swagger-ui%2Foauth2-redirect.html&scope=read&state=U3VuIE9jdCAxNCAyMDE4IDIwOjQyOjUwIEdNVCswNTMwIChJbmRpYSBTdGFuZGFyZCBUaW1lKQ%3D%3D HTTP://本地主机:8080 /的OAuth /授权RESPONSE_TYPE =令牌的client_id =测试应用程式内用户-id&REDIRECT_URI = HTTP%3A%2F%2Flocalhost%3A8080%2Fwebjars%2Fspringfox-招摇的UI%2Foauth2-将redirect.html&范围=读&状态= U3VuIE9jdCAxNCAyMDE4IDIwOjQyOjUwIEdNVCswNTMwIChJbmRpYSBTdGFuZGFyZCBUaW1lKQ%3D%3D

but shows Access Denied like as shown below. 但是显示Access Denied,如下所示。

My complete project is available in GitHub 我的完整项目在GitHub可用

MainApplication.java MainApplication.java

@EnableSwagger2
@SpringBootApplication
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@RestController
public class MainApplication /*extends WebMvcConfigurerAdapter*/
{

    public static void main(String[] args)
    {
        SpringApplication.run(MainApplication.class, args);
    }

    @RequestMapping("/user")
    public Principal user(Principal user) {
        return user;
    }

    @Bean
    SecurityConfiguration security() {
      return SecurityConfigurationBuilder.builder()//<19>
          .clientId("test-app-client-id")
          .build();
    }

    @Bean
    SecurityScheme oauth() {
          List<GrantType> grantTypes = new ArrayList<>();
          ImplicitGrant implicitGrant = new ImplicitGrant(new LoginEndpoint("http://localhost:8080/oauth/authorize"),"access_code");
          grantTypes.add(implicitGrant);
          List<AuthorizationScope> scopes = new ArrayList<>();
          scopes.add(new AuthorizationScope("read","Read access on the API"));
        return new OAuthBuilder()
                .name("SECURITY_SCHEME_OAUTH2")
                .grantTypes(grantTypes)
                .scopes(scopes)
                .build();
    }

    @Bean
    public Docket docket()
    {
        return new Docket(DocumentationType.SWAGGER_2)
            .select()
            .apis(RequestHandlerSelectors.basePackage(getClass().getPackage().getName()))
            .paths(PathSelectors.any())
            .build()
            .securitySchemes(Collections.singletonList(oauth()))
            .apiInfo(generateApiInfo());
    }


    private ApiInfo generateApiInfo()
    {
        return new ApiInfo("Sample Service", "This service is to check Sample Service.", "Version 1.0",
            "Sample Service", "123@test.com", "Apache 2.0", "http://www.apache.org/licenses/LICENSE-2.0");
    }
}

在此输入图像描述

Update 1 更新1

I have added the security and the passwordencoder configure suggested from @AlexanderPetrov . 我添加了@AlexanderPetrov建议的安全性和passwordencoder配置。 Things are working fine, when I add @EnableResourceServer my login screen is showing Full authentication is required to access this resource like as shown below 事情@EnableResourceServer ,当我添加@EnableResourceServer我的登录屏幕显示需要完全身份验证才能访问此资源 ,如下所示

在此输入图像描述

Can anyone please help me on this 任何人都可以帮我这个

You need to do the following changes in your code 您需要在代码中进行以下更改

  1. Form login configuration is necessary for implicit flow. 隐式流需要表单登录配置。
  2. Also if we use implicit flow token will be generated through authorization url instead of token url. 此外,如果我们使用隐式流令牌将通过授权URL而不是令牌url生成。 So you need to change "/oauth/token" to "oauth/authorize". 所以你需要将“/ oauth / token”改为“oauth / authorize”。 configure method below 配置方法如下

     @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().antMatchers("/oauth/authorize").authenticated() .and() .authorizeRequests().anyRequest().permitAll() .and() .formLogin().permitAll() .and() .csrf().disable(); } 
  3. Add password encoder in SecurityConfig class and invoke it to encode user password in globalUserDetails method. SecurityConfig类中添加密码编码器并调用它以在globalUserDetails方法中编码用户密码。 Encoder is necessary because you use in memory passwords. 编码器是必要的,因为你在内存密码中使用。 So without password encoder application fails with an error: 所以没有密码编码器应用程序失败并出现错

     Encoded password does not look like BCrypt 

Code fragment below 代码片段如下

@Autowired
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
    PasswordEncoder passwordEncoder = passwordEncoder();
    auth.inMemoryAuthentication().passwordEncoder(passwordEncoder()).
            withUser("bill").password(passwordEncoder.encode("abc123")).roles("ADMIN").and()
            .withUser("$2a$10$TT7USzDvMxMZvf0HUVh9p.er1GGnjNQzlcGivj8CivnaZf9edaz6C")
            .password("$2a$10$TT7USzDvMxMZvf0HUVh9p.er1GGnjNQzlcGivj8CivnaZf9edaz6C").roles("USER");
}

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

Hope it helps. 希望能帮助到你。 I've created branch for your project but couldn't push it because of 403. So all necessary code is here in my answer. 我已经为你的项目创建了分支但由于403而无法推送它。所以所有必要的代码都在我的答案中。

When you enable a resource server, you need to configure the check_token URL, so that it can reach the OAuth2 authorization server and validate the given access_token. 启用资源服务器时,需要配置check_token URL,以便它可以访问OAuth2授权服务器并验证给定的access_token。

You could do something like: 你可以这样做:

@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class OAuth2ResourceServerConfig extends GlobalMethodSecurityConfiguration {

    @Value("${oauth.url.internal}")    // e.g. http://localhost:8082/oauth
    private String oauthUrl;

    @Value("${oauth.client}")
    private String oauthClient;

    @Value("${oauth.secret}")
    private String oauthSecret;

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

    @Primary
    @Bean
    public RemoteTokenServices tokenService() {
        RemoteTokenServices tokenService = new RemoteTokenServices();
        tokenService.setCheckTokenEndpointUrl(oauthUrl + "/check_token");
        tokenService.setClientId(oauthClient);
        tokenService.setClientSecret(oauthSecret);
        return tokenService;
    }
}

Besides this, you may want to ignore Swagger-specific endpoints: 除此之外,您可能希望忽略特定于Swagger的端点:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/v2/api-docs", "/configuration/ui", "/swagger-resources", "/configuration/security", "/swagger-ui.html", "/webjars/**");
    }
}

Just in case, this is the class I implemented for Swagger w/ OAuth2 authorization: 为了以防万一,这是我为Swagger w / OAuth2授权实现的类:

@EnableSwagger2
@Configuration
public class SwaggerConfig implements WebMvcConfigurer {

    private static final String BASE_PACKAGE = "com.somepackage.api";

    @Value("${oauth.url}")    // Make sure this is an external URL, i.e. accessible from Swagger UI
    private String oauthUrl;

    @Value("${swagger.scopes}")
    private String swaggerScopes;

    @Value("${swagger.urls}")
    private String swaggerUrls;    // Your v2/api-docs URL accessible from the UI

    @Bean
    public Docket api(){
        return new Docket(DocumentationType.SWAGGER_2)
            .select()
            .apis(RequestHandlerSelectors.basePackage(BASE_PACKAGE))
            .apis(RequestHandlerSelectors.any())
            .paths(PathSelectors.any())
            .build()
            .securitySchemes(Collections.singletonList(securitySchema()))
            .securityContexts(Collections.singletonList(securityContext()));
    }

    private OAuth securitySchema() {
        List<AuthorizationScope> authorizationScopeList = new ArrayList<>();
        authorizationScopeList.add(new AuthorizationScope(swaggerScopes, ""));

        List<GrantType> grantTypes = new ArrayList<>();
        GrantType creGrant = new ResourceOwnerPasswordCredentialsGrant(oauthUrl + "/token");
        grantTypes.add(creGrant);

        return new OAuth("oauth2schema", authorizationScopeList, grantTypes);
    }

    private SecurityContext securityContext() {
        return SecurityContext.builder().securityReferences(defaultAuth()).forPaths(PathSelectors.ant(swaggerUrls)).build();
    }

    private List<SecurityReference> defaultAuth() {
        final AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = new AuthorizationScope(swaggerScopes, "");
        return Collections.singletonList(new SecurityReference("oauth2schema", authorizationScopes));
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");

        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
}

Versions: 版本:

  • springSecurityVersion = '2.0.5.RELEASE' springSecurityVersion ='2.0.5.RELEASE'
  • swaggerVersion = '2.8.0' swaggerVersion ='2.8.0'
  • springBootVersion = '2.0.5.RELEASE' springBootVersion ='2.0.5.RELEASE'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Oauth2客户端凭证流+ Spring Boot2引发对于id“ null”错误,没有映射PasswordPasscoder&gt; - Oauth2 Client Credentials Flow + Spring Boot2 throwing There is no PasswordEncoder mapped > for the for the id “null” error Spring Oauth2隐式流 - Spring Oauth2 implicit flow 获取401访问http:// localhost:8080 / oauth / token - getting 401 to access http://localhost:8080/oauth/token Spring OAuth2隐式流重定向URL - Spring OAuth2 implicit flow redirect url Spring Boot 2.0.4 + OAuth2 + JWT-无法获取访问令牌,返回405或仅被映射到localhost:8080 / - Spring Boot 2.0.4 + OAuth2 + JWT - Cannot get Access Token, returns 405 or just gets mapped into localhost:8080/ Spring Boot和OAuth2:获取ResourceAccessException:“ http:// localhost:5555 / oauth / token”的POST请求出现I / O错误:拒绝连接:connect - Spring Boot & OAuth2: Getting ResourceAccessException: I/O error on POST request for “http://localhost:5555/oauth/token”: Connection refused: connect Spring OAuth2 授权:拒绝访问 - Spring OAuth2 Authorization: Access Denied HTTP标头中的Spring OAuth2访问令牌 - Spring OAuth2 Access Token in HTTP Header 确认 oauth2 批准流程后,Princial 是 null 在服务 /oauth/authorize (http post in approveOrDeny) - Princial is null in service /oauth/authorize (http post in approveOrDeny) after confirm oauth2 approval flow OAuth2客户端凭据通过Spring Boot Keycloak集成进行流动 - OAuth2 client credentials flow via Spring Boot Keycloak integration
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM