spring-boot project with spring-security do not access views - spring

I start a new project based on spring-boot, using this working configuration class for spring-security from another project:
#Configuration
#ComponentScan
#EnableWebMvcSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private PasswordEncoder passwordEncoder;
#Autowired
private PermissionEvaluator permissionEvaluator;
#Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/signin")
.loginProcessingUrl("/login").permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/");
}
#Override
public void configure(WebSecurity web) throws Exception {
DefaultWebSecurityExpressionHandler handler = new DefaultWebSecurityExpressionHandler();
handler.setPermissionEvaluator(permissionEvaluator);
web.expressionHandler(handler);
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder);
}
}
when I deploy the project in the tomcat server, without errors, and try access the application, instead of the index page, I get a popup windows asking me for username and password.
the full code for the project is: https://github.com/klebermo/basic_webapp
anyone can see what's wrong with this configuration?

add this to your application.properties file:
security.basic.enabled=false
By default everything is secured with HTTP Basic authentication.
Ref: http://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/autoconfigure/security/SpringBootWebSecurityConfiguration.html

Related

Authenticaton with login and password or with certificate

I have an application with spring boot where the user can authenticate with login and password or by digital certificate.
I try to validate with user and password an it works but when i tried to validate with certificate, chrome dont show me the windows to select the certificate that i want to use in validation (i have several certificates and the server is secure, etc...)
Any ideas?
I attach the code of my WebSecurityConfigurerAdapter in case I have put something wrong
> #EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
#EnableWebSecurity
#Configuration
#RequiredArgsConstructor
#Slf4j
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Configuration
#Order(2)
public static class AdminSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
CustomAuthenticationProvider customAuthProvider;
#Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.mvcMatchers(PublicUrls.URLS).permitAll()
.anyRequest().fullyAuthenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/")
.permitAll()
.and()
.cors()
.and()
.logout()
.invalidateHttpSession(true)
.clearAuthentication(true)
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login?logout")
.permitAll();
}
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(customAuthProvider);
}
}
#Configuration
#Order(1)
public static class UserSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
CustomAuthenticationProvider2 customAuthProvider2;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/loginCert*").authorizeRequests()
.mvcMatchers(PublicUrls.URLS).permitAll()
.anyRequest().fullyAuthenticated()
.and().x509()
.subjectPrincipalRegex("CN=(.*?)(?:,|$)")
.userDetailsService(userDetailsService());
}
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(customAuthProvider2);
}
}
#Bean("authenticationManager")
#Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
And the config properties are:
server.ssl.key-store=store/keystore.jks
server.ssl.key-store-password=changeit server.ssl.key-alias=localhost
server.ssl.key-password=changeit server.ssl.enabled=true
server.ssl.client-auth=need server.port=8443
To make the browser prompt you for client certificate
You need to set the below Spring property in your application.properties if using embedded tomcat
server.ssl.client-auth=need
For dedicated tomcat you need to set the below property in your server.xml
clientAuth="want"
Refer the below tutorial for setting up mutual-auth / 2-way SSL
https://www.baeldung.com/x-509-authentication-in-spring-security

Spring Security WebSecurityConfigurerAdapter Configuration

I have a simple Spring Boot application with the following 2 endpoints:
int: requires Shibboleth SSO && Authorized Role
ext: no SSO, no authorization required
I've implemented a PreAuthenticationFilter to work with SSO. Below is
the configuration that is not working:
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/ext/**").permitAll()
.anyRequest().authenticated()
.and()
.authorizeRequests()
.and()
.addFilter(preAuthenticationFilter());
}
}
Shouldn't PreAuthenticationFilter bypass the /ext endpoint? However, the above configuration forces both endpoints to go to the PreauthenticationFilter. Also tried
web.ignoring().antMatchers("/ext/**")
to no avail.
Here's the rest of my program:
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/ext/**").permitAll()
.anyRequest().authenticated()
.and()
.authorizeRequests()
.and()
.addFilter(preAuthenticationFilter());
}
#Override
public void configure(WebSecurity web) throws Exception {
//web.ignoring().antMatchers("/ext/**");
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
PreAuthenticatedAuthenticationProvider authenticationProvider = new PreAuthenticatedAuthenticationProvider();
authenticationProvider.setPreAuthenticatedUserDetailsService(new ShibbolethUserDetailsService());
auth.authenticationProvider(authenticationProvider);
}
#Bean
RequestHeaderAuthenticationFilter preAuthenticationFilter() throws Exception {
ShibbolethRequestHeaderAuthenticationFilter filter = new ShibbolethRequestHeaderAuthenticationFilter();
filter.setAuthenticationManager(authenticationManager());
return filter;
}

Stormpath integration with existing spring boot app

I have a spring boot app which has spring boot security enabled on it.
The table I have used UserAccount and Role. Now I want to integrate stormpath for access control. How can I migrate my existing system with stormpath? My security configuration is given below.
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
#Autowired
private CustomUserDetailsService customUserDetailsService;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http
.authorizeRequests()
.antMatchers("/*", "/static/**", "/css/**", "/js/**", "/images/**").permitAll()
.antMatchers("/school-admin/*").hasAuthority("SCHOOL_ADMIN").anyRequest().fullyAuthenticated()
.antMatchers("/teacher/*").hasAuthority("TEACHER").anyRequest().fullyAuthenticated()
.anyRequest().authenticated().and()
.formLogin()
.loginPage("/login.html").defaultSuccessUrl("/loginSuccess.html")
.failureUrl("/login.html?error").permitAll().and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout.html")).logoutSuccessUrl("/login.html?logout");
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
}

Spring boot: Securing api endpoint with oauth2 while having mvc UI pages

I'm trying to get a spring-boot mvc application working with standard login while exposing some API endpoints with oAuth2 security.
Basically my requirements are as follows:
If a user hits the home page ("/") check if it's authenticated.
If not show the login form, else show the home page.
But a user should also be able to ask for an oauth authentication token and with that token acces /api/assignment/{id}.
I can get the standard login to work, and I can get the oauth2 to work but I can not get them to work together.
This is my configuration at the moment:
WebSecurityConfig
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private DataSource dataSource;
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(this.dataSource).passwordEncoder(new BCryptPasswordEncoder());
}
}
OAuth2Config
#Configuration
#EnableResourceServer
#EnableAuthorizationServer
public class OAuth2Config {
protected static final String RESOURCE_ID = "oauthdemo";
#Configuration
#EnableResourceServer
protected static class ResourceServer extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.authorizeRequests()
.antMatchers("/js/**", "/css/**", "/images/**", "/webjars/**", "/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
#Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(RESOURCE_ID);
}
}
#Configuration
#EnableAuthorizationServer
protected static class AuthServer extends AuthorizationServerConfigurerAdapter {
#Autowired
#Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.allowFormAuthenticationForClients();
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("client")
.authorizedGrantTypes("password", "refresh_token")
.authorities("ROLE_USER")
.scopes("read")
.resourceIds(RESOURCE_ID)
.secret("secret").accessTokenValiditySeconds(3600);
}
}
}
The problem is I always get the following error when trying to open the home page ("/")
<oauth>
<error_description>
Full authentication is required to access this resource
</error_description>
<error>unauthorized</error>
</oauth>
It does not redirect to the login page.
I do not need this page to be protected by oauth2, but even if i go directly to the login page ("/login", which i can access) and supply credentials I still get the 'full authentication is required' error.
Even though i disabled basic http authentication.
Does anyone know how to separate the normal user UI from the api endpoints that need to be protected by OAuth2?
Can you try this
http
.authorizeRequests()
.antMatchers("/js/**", "/css/**", "/images/**", "/webjars/**", "/login").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/home").authenticated();
Considering /home is a page that needs to be authorized.
Hi you have to specify filters used for each config in your case you need:
in web security configurtion
http
.authorizeRequests()
.antMatchers("/api/**","/oauth/**")
.permitAll()
.and()
.......
this will let web security bypass authorization/resource servers URLs
and in resource server security configuration
http
.antMatcher("/api/**")
.authorizeRequests()
.anyRequest()
.authenticated();
this will let resource security bypass all URLs except "/api/**".
in this way you can ignore orders of configuration there is another option by make one of above actions and put its configuration in early order using #Order

Spring Security Not Allowing Static Content

I have been fighting with Spring Security for the past few days so I hope someone can help me out here.
I am using Spring Boot 1.2.5
I was using Spring Actuator and Spring Remote Shell, those have since been removed from the classpath thinking they may be causing issues
I excluded SecurityAutoConfiguration on the off chance it was causing my issues
Here is my main class
#SpringBootApplication(exclude = {org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration.class})
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
Here is my security configuration
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private AuthFailureHandler authFailureHandler;
#Autowired
private AuthSuccessHandler authSuccessHandler;
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/css/**")
.antMatchers("/js/**")
.antMatchers("/images/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.exceptionHandling()
.authenticationEntryPoint(new Http403ForbiddenEntryPoint())
.accessDeniedPage("/403")
.and()
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/about").permitAll()
.antMatchers("/login").permitAll()
.anyRequest().fullyAuthenticated()
.and()
.formLogin()
.usernameParameter("sec-user")
.passwordParameter("sec-password")
.loginPage("/login")
.failureHandler(authFailureHandler)
.successHandler(authSuccessHandler)
.permitAll()
.and()
.logout()
.deleteCookies("JESSIONID")
.invalidateHttpSession(true)
.permitAll();
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(new BCryptPasswordEncoder());
}
#Bean
#Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
}
My questions / issues are
CSS, JavaScript, Images, basically no static content will load, and I can't seem to figure out why
What makes things even more interesting, instead of getting a 403 error which is what I would expect, it redirects to the Login page? I don't want that, it should return 403 is they don't have access.
I am calling my static resources from Thymeleaf like so
<link rel="stylesheet" media="screen" th:href="#{/css/main.css}" />
My static resources were working fine before adding security.
My static files are in resources/public/.
This is fine acording to Spring Boot docs
By default Spring Boot will serve static content from a folder called /static (or /public or /resources or /META-INF/resources) in the classpath or from the root of the ServletContext.
Try adding a resource handler.
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/css/**")
.addResourceLocations("classpath:/css/**");
registry.addResourceHandler("/img/**")
.addResourceLocations("classpath:/img/**");
registry.addResourceHandler("/resources/**")
.addResourceLocations("/resources/");
}

Resources