Olá pessoal
Estou iniciando os estudos com SpringSecurity e criei uma aplicação onde o login é feito via OAuth2.0. Estou implementando o login baseado na documentação do SpringSecurity dessa página:
https://docs.spring.io/spring-security/reference/servlet/oauth2/client/authorization-grants.html
E os requisitos estou buscando dessa página:
https://developer.atlassian.com/cloud/jira/platform/oauth-2-3lo-apps/#faq5
Estou sendo redirecionado para a pagina de Login da Atlassian, estou passando pela tela de permissões que minha conta vai ceder ao meu app, mas após essas etapas não sou direcionado para minha URL que está no controller.
Fiz a implementação da seguinte forma:
@Configuration
@EnableWebSecurity
public class ProjectSecurityConfig {
@Bean
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity httpSecurity) throws Exception{
httpSecurity
// .sessionManagement(sMConfig -> sMConfig.sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
// .invalidSessionUrl("/sessionInvalid"))
.csrf(csrfConfig -> csrfConfig.disable())
.authorizeHttpRequests(request -> request.requestMatchers("/hello").authenticated()
.anyRequest().permitAll())
.formLogin(Customizer.withDefaults())
// .oauth2Login(Customizer.withDefaults());
.oauth2Login(oauth2 -> oauth2.authorizationEndpoint(auth -> auth.authorizationRequestResolver(
authorizationRequestResolver(this.clientRegistrationRepository())
)));
return httpSecurity.build();
}
@Bean
public ClientRegistrationRepository clientRegistrationRepository() {
return new InMemoryClientRegistrationRepository(this.jiraRegistration());
}
private ClientRegistration jiraRegistration() {
return ClientRegistration.withRegistrationId("atlassian")
.issuerUri("https://api.atlassian.com")
.clientId("****")
.scope("read:jira-work")
.redirectUri("http://localhost:8080/hello")
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.clientSecret("****")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_JWT)
.authorizationUri("https://auth.atlassian.com/authorize")
.tokenUri("https://auth.atlassian.com/oauth/token")
// .userInfoUri("https://api.atlassian.com/me")
.clientName("*****")
.build();
}
private OAuth2AuthorizationRequestResolver authorizationRequestResolver(
ClientRegistrationRepository clientRegistrationRepository) {
DefaultOAuth2AuthorizationRequestResolver authorizationRequestResolver =
new DefaultOAuth2AuthorizationRequestResolver(
clientRegistrationRepository, "/oauth2/authorization");
authorizationRequestResolver.setAuthorizationRequestCustomizer(
authorizationRequestCustomizer());
return authorizationRequestResolver;
}
private Consumer<OAuth2AuthorizationRequest.Builder> authorizationRequestCustomizer() {
return customizer -> customizer
.additionalParameters(params -> {
params.put("prompt", "consent");
params.put("audience", "api.atlassian.com");
});
}
}
No site da atlassian são obrigatorios os params “prompt” e “audience”. Estou enviando na URL
que ficou da seguinte forma:
(https://auth.atlassian.com/authorize?response_type=code&client_id=****&scope=read:jira-work&state=Tzt3GtMAdCLVposbxBDHP5VAD2jJ-ohm4EUmKZHMMQM%3D&redirect_uri=http://localhost:8080/hello&prompt=consent&audience=api.atlassian.com)
estou recebendo a minha request com o code retornado pelo Login no atlassian
/hello?state=Tzt3GtMAdCLVposbxBDHP5VAD2jJ-ohm4EUmKZHMMQM%3D&code=bearerTokenAqui
Agora vamos aos problemas que eu acredito estar causando isso… Mas antes alguns detalhes…
Dentro de public abstract class AbstractAuthenticationToken >
@Override
public boolean isAuthenticated() {
return this.authenticated;
}
está true recebendo um objeto do tipo AnonymousAuthenticationToken. Em
public class AuthorizationFilter >
private Authentication getAuthentication() {
Authentication authentication = this.securityContextHolderStrategy.getContext().getAuthentication();
if (authentication == null) {
throw new AuthenticationCredentialsNotFoundException(
"An Authentication object was not found in the SecurityContext");
}
return authentication;
}
recebo o mesmo AnonymousAuthenticationToken e retorna normalmente.
Ainda em AuthorizationFilter >
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
if (this.observeOncePerRequest && isApplied(request)) {
chain.doFilter(request, response);
return;
}
if (skipDispatch(request)) {
chain.doFilter(request, response);
return;
}
String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName();
request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);
try {
AuthorizationDecision decision = this.authorizationManager.check(this::getAuthentication, request);
this.eventPublisher.publishAuthorizationEvent(this::getAuthentication, request, decision);
if (decision != null && !decision.isGranted()) {
throw new AccessDeniedException("Access Denied");
}
chain.doFilter(request, response);
}
finally {
request.removeAttribute(alreadyFilteredAttributeName);
}
}
O objeto
AuthorizationDecision decision = this.authorizationManager.check(this::getAuthentication, request);
tem o valor de granted = false.
Então recebo um
throw new AccessDeniedException("Access Denied");
e sou redirecionado para o Login…
Já procurei bastante na internet possíveis soluções para esse caso porém o que encontrei as pessoas tem esse mesmo problema ao implementar um Oauth server e não um client login simples…
Alguem pode me ajudar?
Estou a disposição para calls caso o assunto seja muito extenso ou complexo para a discussão aqui no forum, basta me dizer qual preferencia de app de chamada.
To perdendo os cabelo galera e o café já acabou aqui em casa kkkkk
Obrigado a todos!!