Authenticaton with login and password or with certificate - spring

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

Related

how to configure a Content Security Policy in a SecurityConfig class

In my java/spring-boot application, I have a SecurityConfig class as follows:
#EnableWebSecurity
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final BasicAuthenticationProvider basicAuthenticationProvider;
#Autowired
public SecurityConfig(BasicAuthenticationProvider basicAuthenticationProvider) {
this.basicAuthenticationProvider = basicAuthenticationProvider;
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.antMatcher(PATH_NAME)
.httpBasic()
.and().authorizeRequests().anyRequest().authenticated()
.and().csrf().disable();
}
}
I need to configure a ContentSecurityPolicy by using the code .and().headers().contentSecurityPolicy("script-src 'self'") within the configure method, but I've tried in the possible places and keep getting errors (e.g. cannot resolve method .and() when trying the below code)
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.antMatcher(PATH_NAME)
.httpBasic()
.and().authorizeRequests().anyRequest().authenticated()
.and().csrf().disable()
.and().headers().contentSecurityPolicy("script-src 'self'");
}
Would anyone know how to properly do this?
You simply don't have to call .and() after csrf().disable(), since disable() already returns the HttpSecurity object that you have to configure.
So something like
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.antMatcher(PATH_NAME)
.httpBasic()
.and().authorizeRequests().anyRequest().authenticated()
.and().csrf().disable()
// notice that .and() is removed from the next line
.headers().contentSecurityPolicy("script-src 'self'");
}

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;
}

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

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

Authorization roles Spring-boot Oauth2 ~ Restful API

i'm needing help with this problem...
i can't secure my controllers in my security configuration files. but i can do it in my controller using
#PreAuthorize("hasAuthority('ROLE_ADMIN')")
but this is really annoying, i want to do it from my security conf. files
this is my WebSecurityconfigurerAdapter:
#Configuration
//#EnableWebMvcSecurity
#EnableGlobalMethodSecurity(prePostEnabled = false)
//#Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
//#EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
CustomAuthenticationProvider customAuthenticationProvider;
#Autowired
CustomUserDetailsService cuds;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(cuds)
.passwordEncoder(passwordEncoder())
.and()
.authenticationProvider(customAuthenticationProvider);
}
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/**").authenticated()
.antMatchers("/test").authenticated()
.antMatchers("/usuarios/**").hasRole("ADMIN");
}
}
and this is my Oauth2Configuration:
#Configuration
public class Oauth2Configuration {
private static final String RESOURCE_ID = "restservice";
#Configuration
#EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Autowired
private CustomLogoutSuccessHandler customLogoutSuccessHandler;
#Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources
.resourceId(RESOURCE_ID);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
// Logout
.logout()
.logoutUrl("/oauth/logout")
.logoutSuccessHandler(customLogoutSuccessHandler)
.and()
//Session management
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
//URI's to verify
.authorizeRequests()
.antMatchers("/oauth/logout").permitAll()
.antMatchers("/**").authenticated()
.antMatchers("/usuarios/**").hasRole("ADMIN");
}
}
i've tried to use authority and roles, but nothings works. some idea what i'm doing wrong?
Well thanks to Yannic Klem i got the answer, was a problem with the order
First on my WebSecurityConfigurerAdapter i set my authentication on "usuarios"
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/usuarios").authenticated();
}
after that in my Oauth2Configuration set my authorizarion with my rol.
#Override
public void configure(HttpSecurity http) throws Exception {
http
// Logout
.logout()
.logoutUrl("/oauth/logout")
.logoutSuccessHandler(customLogoutSuccessHandler)
.and()
//Session management
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
//URI's to verify
.authorizeRequests()
.antMatchers("/oauth/logout").permitAll()
.antMatchers("/usuarios/**").hasRole("ADMIN");
}
and now all works pretty fine. thank you all!

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

Resources