Spring ErrorController issue with Spring security - java

I am stuck configuring Spring Error mapping with Spring security in Spring Boot 1.3.5 app.
I have follow security config class:
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin").password("123").roles("ADMIN");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().and()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/admin").hasRole("ADMIN").and()
.csrf().disable();
}
}
And ExceptionController :
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
#Controller
public class ExceptionController implements ErrorController {
private static final String ERROR_PATH = "/error";
#RequestMapping(value = ERROR_PATH)
#ResponseStatus(HttpStatus.NOT_FOUND)
public String error(HttpServletResponse response) {
response.setCharacterEncoding("UTF-8");
return "redirect:/";
}
#Override
public String getErrorPath() {
return ERROR_PATH;
}
}
/admin secure page works fine without ExceptionController . But when I adding it, login form not appearing, I have tried a lot of things, such as ControllerAdvice, but nothing seems work for me. What's proper solution here ?

Related

Error with using basic spring boot authentication

I am going through a spring security tutorial where I am trying to configure a basic security using the spring-boot-starter-security using the class like below
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/","/api/*").permitAll()
.anyRequest().authenticated().and().formLogin().loginPage("/login").permitAll()
.and().logout().permitAll();
}
#Autowired
public void ConfigureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(NoOpPasswordEncoder.getInstance())
.withUser("user").password("password").roles("USER");
}
}
But when I try to use the page localhost:8080 or localhost:8080/api/hello?name=test, it's not asking for login and directly showing the requested page. please help me with the issue.
Code allows access without authentication for / and /api/*
http.authorizeRequests().antMatchers("/","/api/*").permitAll()
It restricts access without authentication to any requests which are not matched with above url
.anyRequest().authenticated()

Control API exposure - Spring

I have an application made in Spring + Vue js and I have questions regarding the exposure of endpoints on the web.
After I'm authenticated in the system, when for example I try to access localhost:8080/contracts he is bringing the response in JSON format on the screen, but I would like to block this exposure, even on account of data security.
How can I best control this? Do I do for Spring Security?
WebSecurityConfig.java
package br.com.braxxy.adm.brxmind.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import br.com.braxxy.pls.web.user.CustomUserDetailsService;
#Configuration
#EnableWebSecurity
#ComponentScan("br.com.braxxy.adm.brxmind.security")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
#Autowired
CustomizeAuthenticationSuccessHandler customizeAuthenticationSuccessHandler;
#Bean
public UserDetailsService mongoUserDetails() {
return new CustomUserDetailsService();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
UserDetailsService userDetailsService = mongoUserDetails();
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/css/**", "/js/**", "/img/**", "favicon.ico", "/materialize/**", "/style/**").permitAll()
.antMatchers(HttpMethod.GET, "/new-user").hasRole("ADMIN")
.antMatchers(HttpMethod.POST, "/new-user").hasRole("ADMIN")
.antMatchers("/login").permitAll()
.antMatchers("/signup").permitAll()
.and().csrf().disable().formLogin().successHandler(customizeAuthenticationSuccessHandler)
.loginPage("/login").failureUrl("/login?error=true").usernameParameter("email")
.passwordParameter("password").and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/").and().exceptionHandling();
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/img/**", "/assets/css/**", "/assets/css/vendor/**", "/assets/fonts/**", "/assets/images/**", "/assets/js/**", "/assets/js/vendor/**", "/assets/js/ui/**", "/assets/js/pages/**");
}
}
[![Response API][1]][1]

Sending POST on /login spring security with postman

I'm struggling with log into my application with postman. I'm using spring security with simple configuration:
package main.configuration;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
#Configuration
#EnableWebSecurity()
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
private final UserDetailsService userDetailsService;
public WebSecurityConfiguration(#Qualifier("userDetailsServiceImpl") UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/createUser").permitAll()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().permitAll();
}
#Override
public void configure(WebSecurity web) {
web
.ignoring()
.antMatchers(HttpMethod.POST, "/createUser")
.antMatchers(HttpMethod.POST, "/login");
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
I'm sending POST request on /loginso that I could log in, but all the time I get:
photo from postman
Could you tell me what I'm doing wrong here? How am I supposed to log in and oparte on postman normally? What is interesting if I try to get page within my browser, I'm asked for credentials and then I'm succesfully logged in.
I want to access my other pages which are protected and test them using POSTMAN.
Here is the answer, lack of httpBasic()
Conf class:
package main.configuration;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.HttpStatusEntryPoint;
#Configuration
#EnableWebSecurity()
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
private final UserDetailsService userDetailsService;
public WebSecurityConfiguration(#Qualifier("userDetailsServiceImpl") UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/createUser").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().permitAll().and().httpBasic();
http.csrf().disable();
}
#Override
public void configure(WebSecurity web) {
web
.ignoring()
.antMatchers(HttpMethod.POST, "/createUser");
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
In that case can you please change below as of now and take it from there ?
#Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user1").password(passwordEncoder().encode("user1Pass")).roles("POSTMAN");
}
#Override
protected void configure(final HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/login*").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginProcessingUrl("/login")
.defaultSuccessUrl("/success.html", true) // example page where request need to be redirected when login is sucessful.
.and()
.logout()
.deleteCookies("JSESSIONID");
}
Try above username and password using in memory implementation first and then configure databaseservice later.
Create success.html and you should see the same after login attempt
If you want to test internal URL's through POSTMAN without authentication/ authorization then comment .anyRequest().authenticated() during testing.

How to ignore some resources/urls for everyone in spring security?

I have some urls (one as of now) which I would like to allow for every users like registration and login urls. I only want to exclude any url path after register and secure or restrict any other urls.
Please refer the code below:
package com.travelplanner.rest.config;
//COPY
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.User.UserBuilder;
import org.springframework.security.provisioning.JdbcUserDetailsManager;
import org.springframework.security.provisioning.UserDetailsManager;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private DataSource securityDataSource;
#Bean
public UserDetailsManager userDetailsManager() {
JdbcUserDetailsManager jdbcUserDetailsManager = new JdbcUserDetailsManager();
jdbcUserDetailsManager.setDataSource(securityDataSource);
return jdbcUserDetailsManager;
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(securityDataSource);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().httpBasic().and().csrf().disable()
.authorizeRequests().antMatchers("/register/**").permitAll();
}
}
It is a spring mvc rest in google app engine. I have used the above snippet and it says unauthorised even for the antmatchers. Please help! Thanks in advance.
It's probably the httpBasic() part which is requiring authentication. You should put specific instructions first and more general ones at last, so try with this:
http.cors().and().csrf().disable()
.authorizeRequests().antMatchers("api/users/register/user").permitAll()
.and()
.anyRequest().httpBasic();
This allows everyone to access "api/users/register/user", but requires http authentication for other URLs.

Oauth2 Spring implementation

Im am new in Spring. I would like use Oauth2 with Spring Security.
This is my app:
package demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#SpringBootApplication
#RestController
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#RequestMapping("/")
public String home() {
return "Hello World";
}
#Configuration
#EnableResourceServer
protected static class ResourceServer extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http
.requestMatcher(new OrRequestMatcher(
new AntPathRequestMatcher("/"),
new AntPathRequestMatcher("/admin/beans")
))
.authorizeRequests()
.anyRequest().access("#oauth2.hasScope('read')");
}
#Override
public void configure(ResourceServerSecurityConfigurer resources)
throws Exception {
resources.resourceId("id");
}
}
#Configuration
#EnableAuthorizationServer
protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {
#Autowired
private AuthenticationManager authenticationManager;
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.authenticationManager(authenticationManager);
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("my-trusted-client")
.authorizedGrantTypes("password", "authorization_code",
"refresh_token", "implicit")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
.scopes("read", "write", "trust").resourceIds("id")
.accessTokenValiditySeconds(60).and()
.withClient("my-client-with-registered-redirect")
.authorizedGrantTypes("authorization_code")
.authorities("ROLE_CLIENT")
.scopes("read", "trust").resourceIds("id")
.redirectUris("http://anywhere?key=value").and()
.withClient("my-client-with-secret")
.authorizedGrantTypes("password")
.authorities("ROLE_CLIENT").scopes("read", "write")
.resourceIds("id")
.secret("secret");
}
}
#Configuration
protected static class AuthenticationConfiguration extends
GlobalAuthenticationConfigurerAdapter {
#Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password("password")
.roles("USER").and().withUser("admin").password("password")
.roles("USER");
}
}
}
I want to use password grant authentication. Unfortunately when I run such command:
curl -u my-client-with-secret: http://localhost:8080/oauth/token -d grant_type=password&username=user&password=password&client_id=my-trusted-client&client_secret=secret
the response is:
{"timestamp":1477484999849,"status":401,"error":"Unauthorized","message":"Bad credentials","path":"/oauth/token"}
Can you help me with this problem?
You have to change the curl Request a little. Please put the credentials from the client in front of the Request and append the user credentials as parameters:
curl my-client-with-secret:secret#localhost:8080/oauth/token -d grant_type=password -d username=user -d password=password

Categories

Resources