How can I bypass token authentication for Swagger-UI from browser?
I can make requests to Swagger-UI via Postman.
When I make a request from the browser, I get an error because it requests a token.
http://localhost:8080/swagger-ui/index.html
How can I fix?
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.14</version>
</dependency>
Main class
#SpringBootApplication
public class ExampleMain {
public static void main(String[] args) {
SpringApplication.run(ExampleMain.class, args);
}
}
Security class
#Configuration
#EnableWebSecurity
public class SecurityConfig {
private JwtConverter wtConverter;
public SecurityConfig(JwtConverter jwtConverter) {
this.jwtConverter = jwtConverter;
}
#Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/swagger-ui/**").permitAll()
.anyRequest().authenticated()
.and()
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(jwtConverter);
return http.build();
}
}
Apart from /swagger-ui/**, you should also permit access to OpenAPI documentation and Swagger resources:
...antMatchers("/v3/api-docs/**", "/swagger-ui.html", "/swagger-ui/**", "/swagger-resources/**", "/swagger-resources").permitAll()
Related
Implementing the logic of limiting active sessions for each user (number of possible sessions stored in the database, sessions in Redis), I came across the problem of configuring FindByIndexNameSessionRepository.
Due to the fact that I am injecting FindByIndexNameSessionRepository spring starts to configure the bean in the RedisHttpSessionConfiguration class, and the fields are not injected into the class via setters.
As a result, I get the error:
Caused by: java.lang.IllegalStateException: RedisConnectionFactory is required
at org.springframework.util.Assert.state(Assert.java:73) ~[spring-core-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.data.redis.core.RedisAccessor.afterPropertiesSet(RedisAccessor.java:38) ~[spring-data-redis-2.2.6.RELEASE.jar:2.2.6.RELEASE]
at org.springframework.data.redis.core.RedisTemplate.afterPropertiesSet(RedisTemplate.java:127) ~[spring-data-redis-2.2.6.RELEASE.jar:2.2.6.RELEASE]
at org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration.createRedisTemplate(RedisHttpSessionConfiguration.java:291) ~[spring-session-data-redis-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration.sessionRepository(RedisHttpSessionConfiguration.java:120) ~[spring-session-data-redis-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
Config code:
#EnableRedisHttpSession
#EnableWebSecurity
#Configuration
#RequiredArgsConstructor
public class CustomConfiguration extends WebSecurityConfigurerAdapter {
private final FindByIndexNameSessionRepository sessionRepository;
// ....
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/**")
.authenticated()
.and()
.formLogin()
.and()
// ....
.sessionManagement()
.sessionAuthenticationStrategy(new CustomAuthenticationStrategy(sessionRegistry(), sessionsLimitRepository));
}
#Bean
public SpringSessionBackedSessionRegistry sessionRegistry() {
return new SpringSessionBackedSessionRegistry(sessionRepository);
}
#Bean
public LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(new RedisStandaloneConfiguration("server", 6379));
}
#Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
}
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
</dependency>
<!-- .... -->
</dependencies>
If you remove\comment out the places where FindByIndexNameSessionRepository is used, then the RedisHttpSessionConfiguration setters are called by the "guts" of the spring when the springSessionRepositoryFilter bean is created.
If I understood correctly, then I accidentally broke the order of configuring the beans. In attempts to fix it, I tried #DependsOn, #Lazy and various frauds with moving bins to different classes of configs, changing the order of loading configs, and so on.
UPD: Add bean httpSessionEventPublisher and pom.xml
The main problem was that spring-boot had already configured most of the bins for me.
To resolve this problem, you must remove #EnableRedisHttpSession (#EnableWebSecurity can also be deleted), beans redisConnectionFactory and httpSessionEventPublisher, and optionally you can remove the unnecessary dependency spring-session-core
Actual config code:
#Configuration
#RequiredArgsConstructor
public class CustomConfiguration extends WebSecurityConfigurerAdapter {
private final FindByIndexNameSessionRepository<? extends Session> sessionRepository;
// ....
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/**")
.authenticated()
.and()
.formLogin()
.and()
// ....
.sessionManagement()
.sessionAuthenticationStrategy(new CustomAuthenticationStrategy(sessionRegistry(), sessionsLimitRepository));
}
#Bean
public SessionRegistry sessionRegistry() {
return new SpringSessionBackedSessionRegistry<>(sessionRepository);
}
}
Actual pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<!-- .... -->
</dependencies>
I created a springboot application with spring security dependencies.
I following some tutorials and most of the say the same. I add the dependencies needed and then create a websecurityconfig file. I created these and when I run the project on my local host it works fine. I pushed my application to a remote server and I am not seeing the login page.
Here are my list of dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
And here is my websecurity config
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
LdapConfig ldapConfig;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().fullyAuthenticated()
.and()
.formLogin();
}
#Bean
public UserDetailsContextMapper userDetailsContextMapper() {
return new CustomUserDetailsContextMapper();
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
LdapAuthenticationProviderConfigurer<AuthenticationManagerBuilder>.ContextSourceBuilder contextSourceBuilder = auth.ldapAuthentication()
.userSearchBase(ldapConfig.getUserSearchBase())
.userSearchFilter(ldapConfig.getUserSearchFilter())
.groupSearchBase(ldapConfig.getGroupSearchBase())
.groupSearchFilter(ldapConfig.getGroupSearchFilter())
.groupRoleAttribute(ldapConfig.getGroupRoleAttribute())
.userDetailsContextMapper(userDetailsContextMapper())
.contextSource();
if (ldapConfig.getPort() != null) {
contextSourceBuilder.port(ldapConfig.getPort());
}
contextSourceBuilder
.root(ldapConfig.getRoot())
.url(ldapConfig.getUrl())
.managerDn(ldapConfig.getManagerDn())
.managerPassword(ldapConfig.getManagerPassword());
}
}
This has eaten up a lot of my time, any one Please help me...
Are you getting a Not Authorized when trying to get to the login page ?
Because it looks like you are requiring someone to already be authenticated to access it.
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().fullyAuthenticated()
.and()
.formLogin();
}
You'll need something similar to
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().fullyAuthenticated()
.and()
.formLogin();
}
to allow the login page to be reached.
The addLogoutHandler is not working.
When visiting the API request /logout It still using the default handler CompositeLogoutHandler and SimpleUrlLogoutSuccessHandler.
logoutRequestMatcher,addLogoutHandler,logoutSuccessHandler are all not working.
I am using the spring-boot, part of the dependencies.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.0.15.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
<version>1.0.9.RELEASE</version>
</dependency>
</dependencies>
#Configuration
#Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout", "GET"))
.addLogoutHandler((request,response,authentication) -> System.out.println("=====1====="))
.addLogoutHandler((request,response,authentication) -> System.out.println("=====2======"))
.addLogoutHandler((request,response,authentication) -> System.out.println("=====3======"))
.logoutSuccessHandler(((request, response, authentication) -> {
System.out.println("=====4=======");
response.sendRedirect("/html/logoutsuccess1.html");
}))
.clearAuthentication(true)
.invalidateHttpSession(true);
}
}
So how to make the customize LogoutHandler and LogoutSuccessHandler working.
#EnableResourceServer Because I have added this annotation.
#Configuration
public class ResourceServerConfiguration extends WebSecurityConfigurerAdapter implements Ordered {
In this class, it also configured the HttpSecurity.
I am doing Spring Security Oauth2. In client side I override
configure(HttpSecurity http) method and want to use oauth2Login()
method in HttpSecurity file. But HttpSecurity do not have this
function. I already add dependency of spring-security-oauth2-client,
spring-boot-starter-security and spring-security-oauth2 in pom.xml.
In HttpSecurity file it writes "Copyright 2002-2016 the original
author or authors". How can i update this?
#EnableWebSecurity
public class OauthConfig extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/login**")
.permitAll()
.anyRequest()
.authenticated();
}
}
Please make sure your spring-boot-starter-parent version is correct.
The below is a sample:
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>your-artifactId</artifactId>
<version>your-version</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
</dependency>
<!--if you need to generate token-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.5.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
How to configure WebSecurityConfigurerAdapter class:
1.with default implementations:
#Configuration
public class SimpleTestSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.oauth2Login();
}
}
with customized implementation for loginPage, authorizationEndpoint , TokenEndpoint, redirectionEndpoint, userInfoEndpoint:
#Configuration
public class SimpleTestSecurityConfig extends WebSecurityConfigurerAdapter {
private String[] PERMIT_ALL = {"unsecured-endpoint1", "unsecured-endpoint2", "..."};
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(PERMIT_ALL).permitAll()
.anyRequest().authenticated()
.and()
.oauth2Login()
.loginPage("/login")
.defaultSuccessUrl("/home")
.failureUrl("/error")
.authorizationEndpoint()
.baseUri("/oauth2/authorize-client") //default is "/oauth2/authorization"
.and()
.tokenEndpoint()
.accessTokenResponseClient(accessTokenResponseClient())
.and()
//.redirectionEndpoint()
//.baseUri("/oauth2/redirect") //base for google is "/login/oauth2/code"
//.and()
.userInfoEndpoint().oidcUserService(new OidcUserService(){
#Override
public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException {
return super.loadUser(userRequest);
}
});
}
#Bean
public AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository(){
return new HttpSessionOAuth2AuthorizationRequestRepository();
}
#Bean
public OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient(){
return new NimbusAuthorizationCodeTokenResponseClient();
}
}
application.yml :
spring:
security:
oauth2:
client:
registration:
google:
client-id: your-client-id
client-secret: your-client-secret
redirectUriTemplate: "http://localhost:8080/login/oauth2/code/google"
scope:
- email
- profile
Since you are using spring boot you can use the following dependencies to auto configure the spring security for oauth2:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
After adding the above dependency if you want to override anything.The Spring Boot 2.x auto-configuration class for OAuth Client support is OAuth2ClientAutoConfiguration.
It performs the following tasks:
Registers a ClientRegistrationRepository #Bean composed of
ClientRegistration(s) from the configured OAuth Client properties.
Provides a WebSecurityConfigurerAdapter #Configuration and enables
OAuth 2.0 Login through httpSecurity.oauth2Login().
If you need to override the auto-configuration based on your specific requirements, you may do so in the following ways:
Register a ClientRegistrationRepository #Bean
Provide a WebSecurityConfigurerAdapter
Completely Override the Auto-configuration
By overrriding WebSecurityConfigurerAdapter is as follows:
#EnableWebSecurity
public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.oauth2Login()
.clientRegistrationRepository(this.clientRegistrationRepository())
.authorizedClientService(this.authorizedClientService())
.loginPage("/login")
.authorizationEndpoint()
.baseUri(this.authorizationRequestBaseUri())
.authorizationRequestRepository(this.authorizationRequestRepository())
.and()
.redirectionEndpoint()
.baseUri(this.authorizationResponseBaseUri())
.and()
.tokenEndpoint()
.accessTokenResponseClient(this.accessTokenResponseClient())
.and()
.userInfoEndpoint()
.userAuthoritiesMapper(this.userAuthoritiesMapper())
.userService(this.oauth2UserService())
.oidcUserService(this.oidcUserService())
.customUserType(GitHubOAuth2User.class, "github");
}
}
For reference see this :
https://docs.spring.io/spring-security/site/docs/5.0.7.RELEASE/reference/html/oauth2login-advanced.html
and
https://docs.spring.io/spring-security/site/docs/current/reference/html/jc.html
I am using spring boot with the bootstrap dependency. After implementing a portion of code I am unable to load my webpage with bootstrap (the page will load but it will not utilize bootstrap). I am using the spring bootstrap dependency. Anyone have similar results using spring boot and thymeleaf?
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers().permitAll().anyRequest().authenticated().and().formLogin()
.loginPage("/login").permitAll().and().logout().permitAll();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
}
If the problem if reportet to css I use a configuration like this
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
public class WebSecurityContext extends WebSecurityConfigurerAdapter {
...
#Override
protected void configure(HttpSecurity http) throws Exception {
http....
.and()
.authorizeRequests()
.antMatchers(LOG_IN_URL_PAGE,
LOG_OUT_URL_PAGE,
"/css/**",
"/js/**",
"/img/**",
"/**/favicon.ico",
"/webjars/**",
"/signup").permitAll()
.antMatchers("/**").fullyAuthenticated()
.anyRequest().authenticated();
}
...
}
webjars dependency in my pom
<!--static assets-->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>1.11.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.4</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>select2</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>select2-bootstrap-css</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>angularjs</artifactId>
<version>1.3.15</version>
</dependency>
I use a configuration like this in a my open source projects and works for me
the key point is that you have say at Spring Secuirty that don't secure the resource url
for the resorce url Spring boot autoconfiguration make the work for you it is the motivation of webjars as sample of usage
you can see the complete set of avaiable webjars at the link http://www.webjars.org/
I hope that this can help you