i want to use Keycloak as a authentication provider.
i do not want to use keycloak dependencies directly into my app. instead i want to use spring-security and webflux to access keycloak.
is there a way to implement basic authentication using spring security and keycloak. i know SecurityWebFilterChain class and #EnableWebFluxSecurity but how to integrate it with keycloak?
#Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http.authorizeExchange(exchanges -> exchanges.anyExchange().authenticated()).oauth2Login();
http.csrf().disable();
http.httpBasic();
return http.build();
}
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
Related
This question already has answers here:
Use Keycloak Spring Adapter with Spring Boot 3
(3 answers)
Closed last month.
I'm having issue about setting #KeycloakConfiguration, I watched keycloak's docs and it say that i have to create a class and set all the methods that are set in the documentation
Documentation Keycloak:
#KeycloakConfiguration
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter
{
/**
* Registers the KeycloakAuthenticationProvider with the authentication manager.
*/
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(keycloakAuthenticationProvider());
}
/**
* Defines the session authentication strategy.
*/
#Bean
#Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(buildSessionRegistry());
}
#Bean
protected SessionRegistry buildSessionRegistry() {
return new SessionRegistryImpl();
}
#Override
protected void configure(HttpSecurity http) throws Exception
{
super.configure(http);
http
.authorizeRequests()
.antMatchers("/customers*").hasRole("USER")
.antMatchers("/admin*").hasRole("ADMIN")
.anyRequest().permitAll();
}
}
so i did, but when i copy and paste that in my class it says that i have to implements two more method of security configurer that are init(Builder:B) void and configure (Builder:B) void, other than that i already have a configure method.
I saw in the Docs but doesn't specify what i have to do with these two methods, i would like to know if I'm missing something or if is a feature of the last version of keycloak, the keycloak version that i'm using is the 20.0.2
my dependecies are this:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>[enter image description here](https://i.stack.imgur.com/v2En6.png)
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-security-adapter</artifactId>
<version>20.0.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.keycloak.bom</groupId>
<artifactId>keycloak-adapter-bom</artifactId>
<version>20.0.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>```
As i say i would like to know what i have to do with these two methods
Check Use Keycloak Spring Adapter with Spring Boot 3 or https://www.baeldung.com/spring-boot-keycloak both resolved My problem with same issue
I have read many posts and articles and documentation but I'm very confused about all this.
What I try to do is an apirest with springboot, using feignclient, and I must send a bearer token in my petitions, I get this bearer token from a custom provider.
My client class with feign looks like this:
#FeignClient(name="test-client", url = "https://testurl/")
public interface TestClient {
#GetMapping("/auth/me")
public ResponseEntity<String> testLoginInformation() throws FeignException;
}
my application.properties:
server.port=8082
spring.security.oauth2.client.registration.custom.client-id=mylargeID
spring.security.oauth2.client.registration.custom.client-secret=mylargePassword
spring.security.oauth2.client.registration.custom.authorization-grant-type=client_credentials
spring.security.oauth2.client.registration.custom.scope=access_token_only
spring.security.oauth2.client.registration.custom.provider=custom-provider
spring.security.oauth2.client.registration.custom.client-authentication-method=basic
spring.security.oauth2.client.provider.custom-provider.authorization-uri=https://testurl/auth/token
spring.security.oauth2.client.provider.custom-provider.token-uri=https://testurl/auth/token
In which, I think I indicate all the necesary data for making the requesto to get the token... I don't understand what is the difference between "authorization-uri" and "token-uri"
In my springboot application main class, I only have these two annotations:
#SpringBootApplication
#EnableFeignClients
and last but not least important, the dependencies in my pom file look like these:
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.3.4-RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.1-RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
<version>2.2.0-RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
<version>5.3.4-RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
<version>2.3.4-RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20190722</version>
</dependency>
</dependencies>
Right now, what I'm getting is Invalid Authorization Grant Type (client_credentials) for Client Registration with Id: custom.
What am I doing wrong?
Authorization url
The /authorization endpoint is used to interact with the resource owner and get the authorization to access the protected resource. To better understand this, imagine that you want to log in to a service using your Google account. First, the service redirects you to Google in order to authenticate (if you are not already logged in) and then you will get a consent screen, where you will be asked to authorize the service to access some of your data (protected resources); for example, your email address and your list of contacts.
Token url
An access token is an opaque string or a JWT that denotes who has authorized which permissions (scopes) to which application. It is meant to be exchanged with an access token at the /oauth/token endpoint.
Check here for more: https://auth0.com/docs/protocols/protocol-oauth2
I'm doing a Web application project in Java and I have a problem with securing the application using Spring Security, namely my configuration does not work, I've tried several ways to configure Spring Security, but it does not protect the application.
I bow to whoever will help me with this confi guration. Below are dependencies and a configuration class. I am asking for forgiveness, I am a beginner programmer. Thank you in advance
Ok, so the problem is that I have an MVC and Security configuration, but the Secuity configuration does not work at all, no errors in the console. Stamping url addresses does not work. I am sorry for the organization I am a new user.
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/find").denyAll()
.anyRequest().authenticated()
.and().formLogin().and().httpBasic();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
super.configure(auth);
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
}
}
<!--Spring Security-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>
I want to add to a an existing spring REST api project a simply configuration for WebSecurityConfigurerAdapter to test it. But when spring starts it doesn't load the configuration. Maybe I need to add it to the application context but I don't know how to do it.
If I make a curl localhost:8080/ always get an unauthorized response, so I think that is not loading the configuration, why it is? Or, how I should load it?
In all the diversed projects that I saw on github, they never do special things to load it! Its maybe because its loading an embbeded servlet first?
This is the simple web security configuration:
#SuppressWarnings("SpringJavaAutowiringInspection")
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder
.userDetailsService(this.userDetailsService)
.passwordEncoder(passwordEncoder());
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
// we don't need CSRF because our token is invulnerable
.csrf().disable()
// don't create session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
//.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
// allow anonymous resource requests
.antMatchers(
HttpMethod.GET,
"/",
"/*.html",
"/favicon.ico",
"/**/*.html",
"/**/*.css",
"/**/*.js",
"/**"
).permitAll()
.antMatchers("/auth/**").permitAll()
.anyRequest().authenticated();
// disable page caching
httpSecurity.headers().cacheControl();
}
}
And this is my Application
#Configuration
#EnableConfigurationProperties
#ComponentScan(basePackageClasses = SimpleCORSFilter.class)
#EnableAutoConfiguration org.springframework.boot.actuate.autoconfigure.ManagementSecurityAutoConfiguration.class})
#EntityScan(basePackages = "com.thing.model")
#RestController
public class Application {
#Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
registrationBean.setFilter(characterEncodingFilter);
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
registrationBean.setOrder(Integer.MIN_VALUE);
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
public static void main(String[] args) {
SpringApplication application = new SpringApplication(Application.class);
SpringApplication.run(Application.class, args);
}
#RequestMapping("/")
public String home() {
return "Hello World";
}
pom.xml dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-referencing</artifactId>
<version>8.2</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.7.2</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.3-1102-jdbc41</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
I need to add the WebSecurityConfig to the application context adding this line in the main class declaration:
...
#Import(WebSecurityConfig.class)
public class Application {
...
Another thing that I did is upgrade SpringBoot to 1.4.3.RELEASE and put the main application to root folder:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
The tree will be, for example:
└── com
└── app
├── Application.java
└── config
└── WebSecurityConfig.java
This automatically load all #Configuration in son folders.
Have a look at this example to learn how to enable web security in Spring projects.
#RunWith(SpringRunner.class)
#SpringBootTest
#AutoConfigureMockMvc
public class ClientResourceControllerTest {
Above helped me for the same issue.
I've been racking my brain on this one for a couple days now. Backstory is, I'm using Spring Boot with spring-boot-starter-security dependency for the security aspect. I'm trying to build a REST Web Service that should only reply with JSON (or XML if I decide to implement that as well). I can return resources and my URI's work fine, so no problem there. I even have json object authentication on the security.
So Here's my problem. When an unauthorized user tries to access a restricted resource, Spring Security delivers a login page (HTML). This is problematic. I just want it to return a 401 and possibly a JSON error object of my choosing. Same with successful logins. I don't want it to redirect. And especially not a pre-made HTML page.
I have looked up tutorials and everyone mentions using AuthenticationEntryPoint and the like for controlling the flow. BUT! I don't have that. Apparently that method doesn't exist anymore for HttpSecurity class. Anyone have the answer? Here's the relevant code, I'll supply more if you need it.
#Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
private JsonAuthenticationFilter authFilter;
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
authFilter = new JsonAuthenticationFilter();
authFilter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/login","POST"));
authFilter.setAuthenticationManager(this.authenticationManagerBean());
httpSecurity
.addFilterBefore(authFilter, UsernamePasswordAuthenticationFilter.class)
.csrf()
.disable()
.formLogin()
.permitAll()
.loginProcessingUrl("/login")
.failureUrl("/error")
.usernameParameter("username")
.passwordParameter("password")
.and()
.logout()
.permitAll()
.logoutUrl("/logout")
.and()
.authorizeRequests()
.antMatchers("/", "/version")
.permitAll()
.and()
.authorizeRequests()
.anyRequest()
.authenticated();
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
}
And the maven dependencies...
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>com.datastax.cassandra</groupId>
<artifactId>cassandra-driver-mapping</artifactId>
</dependency>
</dependencies>
When an un-authorized user tries to access a restricted resource,
Spring Security delivers a login page (HTML). This is problematic. I
just want it to return a 401 and possibly a JSON error object of my
choosing
If you don't want the Form Login, just disable it in your SecurityConfiguration. In order to do that, replace this piece of configuration:
formLogin()
.permitAll()
.loginProcessingUrl("/login")
.failureUrl("/error")
.usernameParameter("username")
.passwordParameter("password")
With:
formLogin()
.disable();
Or you can just throw away the formLogin part.
BUT! I don't have that. Apparently that method doesn't exist anymore
for HttpSecurity class. Anyone have the answer?
It's under exceptionHandling:
http.exceptionHandling()
.authenticationEntryPoint(yourEntryPoint)