Spring boot Security - java

I want to put restriction on this "/realtime/updates" Url but If I request "/anyurl" it redirects me to Login page. I want to be redirected to login page only for "/realtime/updates".
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecConfig1 extends WebSecurityConfigurerAdapter {
#Override
public void configure(WebSecurity web) throws Exception {
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.authorizeRequests().antMatchers("/realtime/updates").hasRole("USER").anyRequest().authenticated().and().formLogin();
}
#Autowired
public void ConfigGlobal(AuthenticationManagerBuilder auth) throws Exception{
auth.inMemoryAuthentication().withUser("abc").password("123").roles("USER");
}
}

You need to change one snippet in the protected void configuremethod.
Try this:
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.authorizeRequests()
.antMatchers("/**").permitAll()
.antMatchers("/realtime/updates").hasRole("USER")
.and().formLogin().permitAll();
}

You need to add your restrictions in configure method.Your method like below :
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/realtime/updates/**").authenticated()
.antMatchers("/otherURL/**").hasRole("ADMIN")
.and()
.exceptionHandling().accessDeniedPage("/login")
.and()
.formLogin().loginPage("/index")
.usernameParameter("username")
.passwordParameter("password")
.loginProcessingUrl("/j_spring_security_check")
.failureUrl("/loginControl?error=true")
.defaultSuccessUrl("/loginControl?error=false")
.and()
.logout().logoutUrl("/logout").logoutSuccessUrl("/index")
;
}

I was calling super.configure(http); inside configure method I removed that it worked.
This is was previous code:
#Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.authorizeRequests().antMatchers("/realtime/updates")
.hasRole("USER")
.anyRequest()
.authenticated()
.and()
.formLogin();
}
This is current code that worked:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/realtime/updates")
.hasRole("USER")
.anyRequest()
.authenticated()
.and()
.formLogin();
}

Related

Spring security : managing two Authentication Provider

I need to have 2 implementations of AuthenticationProvider required for spring security.
One is WindowsAuthenticationProvider (retrieve the user logged in windows - through waffle connector)
So I configure like this :
#Configuration
#EnableWebSecurity
public class WaffleConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
//basic auth for rest endpoint callers
.antMatcher("/api/**")
.authorizeRequests()
.antMatchers("/api/**")
.authenticated()
.and()
.authenticationProvider(inMemoryAuthenticationProvider)
.httpBasic()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
//waffle for spring mvc users (with prime faces)
.and()
.antMatcher("/secure/**")
.authorizeRequests()
.antMatchers("/secure/**").authenticated()
.and()
.authenticationProvider(windowsAuthProvider)
.httpBasic()
.authenticationEntryPoint(negotiateSecurityFilterEntryPoint)
.and()
.addFilterBefore(negotiateSecurityFilter, BasicAuthenticationFilter.class);
}
}
The problem is this line :
.authenticationProvider(inMemoryAuthenticationProvider)
I just want to do like my inmemory authentication :
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
GrantedAuthority ga = new GrantedAuthority() {
#Override
public String getAuthority() {
return "eligibilite:read";
}
};
GrantedAuthority gaw = new GrantedAuthority() {
#Override
public String getAuthority() {
return "eligibilite:write";
}
};
auth.inMemoryAuthentication()
.withUser("francois")
.password("{noop}fournel")
.authorities(Arrays.asList(ga))
.and()
.withUser("francois2")
.password("{noop}fournel2")
.authorities(Arrays.asList(gaw));
}
For windows connection through waffle I already defined the auth provider :
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(windowsAuthProvider)
}
I need to define the "In memory authentication provider", but I don't know how to define and create this object.

Spring boot security to allow all endpoints except one

For a project that has no spring security. All controllers (GET/POST) of the project are not secured and should stay unsecured. But now, I have a new Controller and i want to secure its path (/private), sub-pathes and parameters. Only this one path must be secured with Basic Authentication. Why is my code not working?
#Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/**").permitAll()
.antMatchers("/private**").hasAuthority("ADMIN").and().httpBasic();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user")
.password("{noop}pass")
.roles("ADMIN");
}
}
http.csrf()
.disable()
.authorizeRequests()
.antMatchers("/private").hasRole("ADMIN")
.antMatchers("/private/**").hasRole("ADMIN")
.antMatchers("/**").permitAll()
.and()
.httpBasic();
or
http.csrf()
.disable()
.authorizeRequests()
.antMatchers("/private").hasRole("ADMIN")
.antMatchers("/private/**").hasRole("ADMIN")
.anyRequest().permitAll()
.and()
.httpBasic();

Issue with having multiple WebSecurityConfigurerAdapter in spring-boot

I am using spring-boot-1.5.10 and spring-boot-starter-security.
In my microservice, I am exposing API's to the external world and internal microservices.
so I would like to 2-kind of security. one for external calls and other for internal calls.
I have referred this URL and tried to implement multiple security adapters in my application.
But no luck it's always picking the internal one instead of external one,
Please find the security adapter for your reference,
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired(required = false)
ServiceWebSecurityConfigurer serviceWebSecurityConfigurer;
// #Override
// public void configure(WebSecurity web) throws Exception {
// web
// .ignoring()
// .antMatchers(HttpMethod.PUT,"/v1/emp/**")
// .antMatchers(HttpMethod.DELETE,"/v1/emp/**");
// }
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authenticationProvider(new ExternalApiAuthenticationProvider())
.securityContext()
.securityContextRepository(new ExternalApiSecurityContextRepository())
.and()
.exceptionHandling()
.authenticationEntryPoint(new ApiAuthenticationEntrypoint())
.and()
.httpBasic().disable()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/v1/**").fullyAuthenticated();
if(serviceWebSecurityConfigurer != null)
serviceWebSecurityConfigurer.configure(http);
http.authenticationProvider(new InternalApiAuthenticationProvider())
.securityContext()
.securityContextRepository(new InternalApiSecurityContextRepository())
.and()
.exceptionHandling()
.authenticationEntryPoint(new ApiAuthenticationEntrypoint())
.and()
.httpBasic().disable()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.PUT,"/v1/emp/**").fullyAuthenticated()
.antMatchers(HttpMethod.DELETE,"/v1/emp/**").fullyAuthenticated();
}
}
It always picks the "InternalApiSecurityContextRepository" even the external API's using internal security.
It seems the later is overriding the former.
UPDATE-1(as per Gaurav Srivastav answer)
External API call security adapter :
#EnableWebSecurity
public class WebSecurityConfig {
#Configuration
#Order(2)
public static class InternalSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authenticationProvider(new InternalApiAuthenticationProvider())
.securityContext()
.securityContextRepository(new InternalApiSecurityContextRepository())
.and()
.exceptionHandling()
.authenticationEntryPoint(new InternalApiAuthenticationEntrypoint())
.and()
.httpBasic().disable()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.PUT,"/v1/emp/**").fullyAuthenticated()
.antMatchers(HttpMethod.DELETE,"/v1/emp/**").fullyAuthenticated();
}
}
#Configuration
#Order(1)
public static class ExternalSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authenticationProvider(new ExternalApiAuthenticationProvider())
.securityContext()
.securityContextRepository(new ExternalApiSecurityContextRepository())
.and()
.exceptionHandling()
.authenticationEntryPoint(new ApiAuthenticationEntrypoint())
.and()
.httpBasic().disable()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/v1/**").fullyAuthenticated();
}
}
}
It works for External(Since the order is 1) but for internal we are getting the following exception and it is using the External configuration security context,
An internal server error occurred.Message:An Authentication object was not found in the SecurityContext
I think the problem here is, we cannot use 2-security context it seems.Is there anyway to use different security context?
Any hint would be really appreciable to solve the issue.
Thanks in Advance.
You have define more than one configuration and specify the order using #Order annotation.
Internal Configuration with its own authentication provider and url pattern.
#EnableWebSecurity
public class MultiHttpSecurityConfig {
#Configuration
#Order(1)
public static class InternalSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/internal/**")
.authorizeRequests().anyRequest().hasRole("ADMIN")
.and().httpBasic().authenticationEntryPoint(authenticationEntryPoint());
}
}
#Configuration
#Order(2)
public static class ExternalSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/external/**")
.authorizeRequests().anyRequest().hasRole("ADMIN")
.and().httpBasic().authenticationEntryPoint(authenticationEntryPoint());
}
}
Get more detail through using below article.
https://www.baeldung.com/spring-security-multiple-entry-points

Unauthorized user access to some url

I use Oauth and want to create user but have error
POST http://localhost:4200/proxy/user/createUser 401 (Unauthorized)
In spring i have some configuration
#Configuration
#EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/createUser", "/user/**", "/user/createUser", "proxy/user/createUser").permitAll();
http.csrf().disable();
http.formLogin().disable();
http.authorizeRequests().anyRequest().authenticated();
}
}
and
#Configuration
#EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/createUser", "/register", "/token", "/token/createUser", "proxy/user/createUser").permitAll();
http.requestMatchers()
.and()
.authorizeRequests()
.anyRequest()
.authenticated();
}
}
What configuration changes are required to enable access to ../createUser?
looks like http.authorizeRequests().anyRequest().authenticated() this is creating problem in code. just change in WebSecurity as
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests().antMatchers("/createUser", "/user/**", "/user/createUser", "proxy/user/createUser")
.permitAll()
.formLogin().disable();
}}`
AND
change in ResourceServerConfig as
http.authorizeRequests()
.antMatchers("/createUser", "/register", "/token", "/token/createUser",
"proxy/user/createUser")
.permitAll();
for details checkout Security-config.

How to set two or more AuthenticationProvider in spring security? [duplicate]

There are several references of multiple authentication providers in spring security, but no example in Java config could be located.
The following link gives the XML notation:
Multiple Authentication Providers in Spring Security
We need to authenticate using LDAP or DB
Below is our sample code:
#Configuration
#EnableWebSecurity
public class XSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private AuthenticationProvider authenticationProvider;
#Autowired
private AuthenticationProvider authenticationProviderDB;
#Override
#Order(1)
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
}
#Order(2)
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProviderDB);
}
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/scripts/**","/styles/**","/images/**","/error/**");
}
______
#Override
#Order(1)
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/","/logout","/time").permitAll()
.antMatchers("/admin").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/index")
.loginProcessingUrl("/perform_login")
.usernameParameter("email")
.passwordParameter("password")
.failureUrl("/index?failed=true")
.defaultSuccessUrl("/summary",true)
.permitAll()
.and()
.logout().logoutUrl("/logout")
.logoutSuccessUrl("/index?logout=true").permitAll()
.and()
.exceptionHandling().accessDeniedPage("/error403")
.and().authenticationProvider(authenticationProvider);
}
#Order(1)
protected void configureDB(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/","/logout").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/index")
.loginProcessingUrl("/perform_login")
.usernameParameter("email")
.passwordParameter("password")
.failureUrl("/index?failed=true")
.defaultSuccessUrl("/summary",true)
.permitAll()
.authenticationProvider(authenticationProviderDB)
//This line giving compilation error stating authenticationProvider is not available in formloginconfigurer
.and()
.logout().logoutUrl("/logout")
.logoutSuccessUrl("/index?logout=true").permitAll()
.and()
.exceptionHandling().accessDeniedPage("/error403");
}
}
May be this will help you :-
#Configuration
#EnableWebSecurity
#Profile("container")
public class XSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private AuthenticationProvider authenticationProvider;
#Autowired
private AuthenticationProvider authenticationProviderDB;
#Override
#Order(1)
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
}
#Order(2)
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProviderDB);
}
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/scripts/**","/styles/**","/images/**","/error/**");
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/rest/**").authenticated()
.antMatchers("/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.successHandler(new AuthenticationSuccessHandler() {
#Override
public void onAuthenticationSuccess(
HttpServletRequest request,
HttpServletResponse response,
Authentication a) throws IOException, ServletException {
//To change body of generated methods,
response.setStatus(HttpServletResponse.SC_OK);
}
})
.failureHandler(new AuthenticationFailureHandler() {
#Override
public void onAuthenticationFailure(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException ae) throws IOException, ServletException {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
})
.loginProcessingUrl("/access/login")
.and()
.logout()
.logoutUrl("/access/logout")
.logoutSuccessHandler(new LogoutSuccessHandler() {
#Override
public void onLogoutSuccess(
HttpServletRequest request,
HttpServletResponse response,
Authentication a) throws IOException, ServletException {
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
}
})
.invalidateHttpSession(true)
.and()
.exceptionHandling()
.authenticationEntryPoint(new Http403ForbiddenEntryPoint())
.and()
.csrf()//Disabled CSRF protection
.disable();
}
}
In Spring Boot this worked for me:
Each Authentication provider is tested in order. If one passes, then its following Authentication providers are skipped
auth.userDetailsService(userDetailsService)...
then:
auth.ldapAuthentication()....
#EnableRedisHttpSession
#Configuration
#EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private CustomUserDetailsService userDetailsService;
#Autowired
public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
//each Authentication provider is tested in order
//if one passes then its following Authentication providers are skipped
//DataBase Authentication
auth.userDetailsService(userDetailsService).passwordEncoder(passwordencoder());
LdapContextSource ldapContextSource = new LdapContextSource();
ldapContextSource.setUrl("ldap://192.168.XXX.XXX:389");
ldapContextSource.setBase("dc=companyname,dc=com");
ldapContextSource.setUserDn("cn=user,cn=testgroup,ou=Test,dc=companyname,dc=com");
ldapContextSource.setPassword("user1234");
ldapContextSource.afterPropertiesSet();
//LDAP Authentication
auth.ldapAuthentication()
//The {0} in the (uid={0}) will be replaced by the username entered in the form.
.userSearchBase("ou=Group")
.userSearchFilter("uid={0}")
//.userDnPatterns("uid={0},ou=people")//does the same thing
//Specifies where the search for Roles start
//.groupSearchBase("ou=mathematicians")
//in groups we search for member
//.groupSearchFilter("member={0}")
//.contextSource().ldif("classpath:test-server.ldif");
.contextSource(ldapContextSource);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/hello").access("hasRole('ROLE_ADMIN')")
.antMatchers("/index").fullyAuthenticated()
.antMatchers("/").fullyAuthenticated()
.antMatchers("/home").fullyAuthenticated()
.anyRequest().permitAll()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.usernameParameter("username").passwordParameter("password")
.and()
.logout()
.logoutSuccessUrl("/login?logout")
.permitAll()
.and()
.exceptionHandling()
.accessDeniedPage("/403")
.and()
.csrf()
.disable();
}
#Bean(name = "passwordEncoder")
public PasswordEncoder passwordencoder() {
return new BCryptPasswordEncoder();
}
}
This is a successful configuration which helps configure multiple authentication providers in java config.
Thanks a lot ojus for your inputs. It did help in nailing down the issue.
The key is to have
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
auth.authenticationProvider(authenticationProviderDB);
}
Full code below
#Configuration
#EnableWebSecurity
public class XSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private LDAPAuthenticationProvider authenticationProvider;
#Autowired
private DBAuthenticationProvider authenticationProviderDB;
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/scripts/**","/styles/**","/images/**","/error/**");
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
auth.authenticationProvider(authenticationProviderDB);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/","/logout").permitAll()
.antMatchers("/admin").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/index")
.loginProcessingUrl("/perform_login")
.usernameParameter("user")
.passwordParameter("password")
.failureUrl("/index?failed=true")
.defaultSuccessUrl("/test",true)
.permitAll()
.and()
.logout().logoutUrl("/logout")
.logoutSuccessUrl("/index?logout=true").permitAll()
.and()
.exceptionHandling().accessDeniedPage("/error");
}
}

Categories