Accessing my api using google bearer token - spring

I've enabled google auth by defining the following configuration along with the appropriate application.yml file.
#EnableOAuth2Sso
#Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/**")
.authorizeRequests()
.antMatchers("/", "/login**").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/"));
}
}
I can access my various endpoints through the browser. But the client might not always be a browser.
I have a controller method defined as below
#GetMapping("/user")
public Principal getUser(Principal principal) {
return principal;
}
From the Principal returned I can see the tokenValue which is of type Bearer. How can I use that against my api? Or another token for that matter. I simply want to access my own api using google auth and oauth.
wget -i http://localhost:8080/user -H "Authorization: Bearer $TOKEN"
Redirects me to the login page.
To clarify a bit more I want to authenticate using google auth but be able to access my api using oauth. Weather it's the token returned by google or one generated by spring doesn't matter. Any clues about how I can make that happen?

You can have a look at spring's tutorial focusing on oauth2, and checkout the github project. They have a nice auth-server project where you can find an exemple of what you want to achieve.
Steps to test your scenario are:
Checkout the tutorial project git clone https://github.com/spring-guides/tut-spring-boot-oauth2.git
Run the spring boot project named auth-server
cd auth-server && mvn spring-boot:run
Authenticate through http://localhost:8080
You'll find out that on auth-server side (the api server), an OAuth2Authentication principal will be available with a bearer token made available. You could use this auth-server exemple to design a Controller returning this token if user is authenticated.
Then you'll be able to wget or curl the auth-server with such requests:
curl -X GET "http://localhost:8080/me" -H "Authorization: Bearer 22e70fcf-eb60-483c-9105-xxxx"
In my tests I got following response: {"name":"674008369426415"}
without the bearer, I fortunately got:
curl -X GET "http://localhost:8080/me"
{"error":"unauthorized","error_description":"Full authentication is required to access this resource"}
Missing parts of code
Looking at your code, I think you're missing the SSO Filter part of the spring's tutorial:
http.antMatcher("/**")
// more configuration here
.addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
and
#Bean
public FilterRegistrationBean oauth2ClientFilterRegistration(OAuth2ClientContextFilter filter) {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(filter);
registration.setOrder(-100);
return registration;
}
There must be an interception of client's request somewhere, so this may be something worth looking.

Related

Keycloak Springboot bearer only for specific endpoint and non bearer for another

I am trying to use keycloak springboot adapter. I want to make some endpoints with "/api" work with bearer only to true.
But I also want the endpoint "/login" to not be a bearer only endpoint and redirect the user to the keycloak OIDC login page if he is not authenticated.
How can I achieve that ?
All I have now is just bearer only for every endpoints in my application properties.
Thanks in advance for your answers :)
In web-security conf,
enable anonymous
in http-security ant-matchers, add an entry for your public routes with permitAll()
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.anonymous();
http.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated();
return http.build();
}
PS
Keycloak spring adapters are deprecated
As an alternative, you can use:
spring-addons-webmvc-jwt-resource-server tutorial here
spring-boot-starter-oauth2-resource-server tutorial there (it requires more Java conf)

Handling token response in spring oauth2 client

I am using Spring Cloud Gateway as a API Gateway for our system. We would like to delegate all authentication (oauth) to that component. I was looking at the source code of Spring Oauth2 Client but I don't see any place where I can "plug in" to do what I need.
I would like to catch the moment, when the code exchange is successful and make a redirect with id_token and refresh_token in cookie or query param. We don't store any session as well - whole authentication is meant to stateless.
I am configuring SecurityWebFilterChain (security for WebFlux) like this:
#Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange(Customizer.withDefaults())
.oauth2Login();
http.csrf().disable();
return http.build();
}
I tried to use successHandler
.oauth2Login(c -> c.authenticationSuccessHandler(successHandler));, but in that moment I don't access to refresh_token (have only WebFilterExchange, Authentication in arguments) and I am not even sure how should I perform the redirect form that place.
Is there any way to achieve this?

Spring security 5 - UsernamePasswordAuthenticationFilter and basic authentication

I'm trying to implement simple security for a small API school project and am a bit confused and overwhelmed. I followed
this blog post.
Everything works and I'm able to login and receive a jwt token. However login is currently performed by sending the username and password along with the URL as query parameters. That is of course something I would like to avoid.
I have tried adding httpbasic to the security configuration like this:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.addFilter(new JwtAuthenticationFilter(authenticationManager(), jwtAudience, jwtIssuer, jwtSecret, jwtType))
.authorizeRequests(authorizeRequests ->
authorizeRequests
.antMatchers("/board/**").hasAnyRole("MEMBER", "BOARD")
.antMatchers("/members/**").hasRole("MEMBER")
.anyRequest().authenticated()
)
.httpbasic().and().
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
Login however ceases to work and I constantly get an unauthorized while trying basicAuth with postman.
So my question is: How can I change the behaviour of these code snippets to accept basic authentication and not send user credentials by URL? Do I have to override the AttemptAuthentication method too?

Configure spring security with oauth2/openid for session id but also access token

it is possible to configure spring with oauth2 to accept multiple login possibilities?
Currently I have it working with:
#Override
protected void configure(HttpSecurity http) throws Exception { // #formatter:off
http.authorizeRequests(authorizeRequests -> authorizeRequests
.anyRequest()
.authenticated())
.oauth2Login(AbstractAuthenticationFilterConfigurer::permitAll)
.addFilterAfter(new CustomAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.logout(logout -> logout.logoutSuccessHandler(oidcLogoutSuccessHandler()))
.oauth2ResourceServer().jwt();
} // #formatter:on
If one tries to access an authorize ressource, he gets redirected to a login page of an identity provider, logs in and then get a session id on the client side. The access token and the refreh token are held into memory on the server side.
But now I also want to use an access token to access ressources.
But when I do this, the security application context is just null.
What do I have to do?
I have searching in the doc but could not understand how to achieve this.
I would expect to just add in application.properties:
spring.security.oauth2.resourceserver.jwt.jwk-set-uri
And to add:
.oauth2ResourceServer().jwt() to my HttpSecurity but this does not do the work.
Found the answer, if Bearer is not set as prefix in the Authorization header when sending the token, then it will not be recognized.
Kind of normal since it is the standard...

spring 5 - Oauth2 server get current user

I have build a Spring boot oauth2 server using spring 5. The oauth server works and I can login using basic auth and username/password. I get a bearer token and I can verify the token using the /oauth/check_token url.
In the same Spring boot project I want to add an endpoint that will print out the authenticated user information so that oauth2 clients can get information over the logged in user. I created an endpoint /user and it looks like this:
#GetMapping("/user")
#ResponseBody
public Principal user(Principal user) {
return user;
}
I startup postman so that I can do the api calls and such, call /oauth/token and I receive a token. I then start a new request, set the authentication method to bearer token and fill in the received bearer token. I do a GET call to the url (http://localhost:8080/user) and it turns out the principal is always null. I know because I can debug my application in Spring tool suite and Principal is always empty. I have also tried:
OAuth2Authentication oAuth2Authentication = (OAuth2Authentication)SecurityContextHolder.getContext() .getAuthentication();
That is empty as well. How can I create an endpoint that will print the user info so that clients can set the userInfoUri property.
I have the answer. I'll post it here just in case someone else runs into this problem.
I have a ResourceServerConfigurerAdapter with the following configure in it:
public void configure(HttpSecurity http) throws Exception {
http.anonymous()
.disable()
.requestMatchers()
.antMatchers("/api/user/**").and().authorizeRequests()
.antMatchers("/user").authenticated()
// More rules here
The reason it didn't work because of the first antMatchers("/api/user/**"). I changed it into this:
http.anonymous()
.disable()
.requestMatchers()
.antMatchers("**").and().authorizeRequests()
I believe that the first antMatchers determines the path in which it forces authorizeRequests (Enabling oauth2 security in that path) so if the first path is .antMatchers("/api/user/**") after that is .antMatchers("/user") then it won't match and the /user url won't have the oauth2 security enabled.

Resources