[英]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");
}
}
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 您需要在代码中进行以下更改
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(); }
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: 版本:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.